简体   繁体   English

在C中的自定义外壳中执行重定向(“>”和“ <”)

[英]Executing redirection ( “>” and “<” ) in custom shell in C

I'm supposed to write a simple custom shell in C that can handle redirection with just the "<" and ">" commands. 我应该用C语言编写一个简单的自定义外壳程序,该外壳程序仅可以使用“ <”和“>”命令来处理重定向。

To do this I'm parsing each command (in an array of strings), checking for the characters '<' and '>' and then opening a file name with open(fd, filename, flags) to either read or write to. 为此,我要解析每个命令(以字符串数组形式),检查字符“ <”和“>”,然后使用open(fd, filename, flags)要读取或写入的文件名。

If I issue these commands (where % signifies my shell), I expect to get the output below: 如果发出这些命令(%表示我的外壳程序),则希望获得以下输出:

% echo hello > output.txt
% cat output.txt
hello

However, when I issue these commands, and really any commands, it seems to ignore (but not ignore?) my redirections. 但是,当我发出这些命令以及实际上所有命令时,似乎都忽略(但不忽略?)重定向。 This is what happens when I issue the same commands: 当我发出相同的命令时,将发生以下情况:

% echo hello > output.txt
% cat output.txt
hello > output.txt

The weird part is, it does create a file, called "output.txt", and writes to it, "hello > output.txt" 奇怪的是,它确实创建了一个名为“ output.txt”的文件,并将其写入“ hello> output.txt”

This happens with both the input and output redirectors. 输入和输出重定向器都会发生这种情况。 Here is just the code for opening and executing an output command. 这只是用于打开和执行输出命令的代码。

int fd;
open_write_file(&fd, commands[index]);
dup2(fd, 1);
execvpe(commands[0], commands, envp);
close(fd);

Note that open_write_file() opens the file name, with flags O_WRONLY | O_TRUNC | O_CREAT, S_RUSR | S_IRGRP | S_IWGRP | S_IWUSR 请注意, open_write_file()将打开文件名,并带有标志O_WRONLY | O_TRUNC | O_CREAT, S_RUSR | S_IRGRP | S_IWGRP | S_IWUSR O_WRONLY | O_TRUNC | O_CREAT, S_RUSR | S_IRGRP | S_IWGRP | S_IWUSR O_WRONLY | O_TRUNC | O_CREAT, S_RUSR | S_IRGRP | S_IWGRP | S_IWUSR and does error checking to ensure it opens correctly. O_WRONLY | O_TRUNC | O_CREAT, S_RUSR | S_IRGRP | S_IWGRP | S_IWUSR并进行错误检查以确保其正确打开。 How can I solve this and get it to actually execute the real command I want? 如何解决此问题并使其真正执行我想要的真实命令?

The syntax of open is fd = open(path, flags, [mode]); open的语法是fd = open(path, flags, [mode]);

In case of > , you'd better use the fd = creat(path, mode); 如果是> ,则最好使用fd = creat(path, mode); syscall, which overwrites and creates by default. syscall,默认情况下会覆盖并创建。

When you parse, the argv array for execvpe should include the parameters up to, but not including, the 1st redirection symbol > or < . 解析时, execvpe的argv数组应包含最多但不包括第一个重定向符号>< The argv array shall have a last NULL-pointer element to indicate its end. argv数组应具有最后一个NULL指针元素以指示其结束。

The redirections should happen after a fork() syscall in the child process, otherwise your shell loses its stadard IO and the exec will wipe it out completely. 重定向应该在子进程中的fork() syscall之后进行,否则您的shell会丢失其标准IO,而exec将完全清除它。

/* Parse input line, create argv array, and inputfile/outputfile names */
...
if (fork() == 0) {
  /* Child process: stdin redirection */
  fd_in = open(inputfile, O_RDONLY);
  close(0);
  dup(fd_in);
  close(fd_in);
  /* Child process: stdout redirection */
  fd_out = creat(outputfile, 0644);
  close(1);
  dup(fd_out);
  close(fd_out);
  /* Child process: exec other program */
  execvp(argv[0], argv); /* Does NOT return */
} else {
  /* Parent process: wait until child process exits */
  wait();
}

There is a general misunderstanding about what the exec syscall family does. 关于exec syscall系列的功能存在普遍的误解。 They simply throw away the current program and replace it with another one in the CURRENT PROCESS. 他们只是简单地丢弃当前程序,并在当前进程中将其替换为另一个程序。 They do not return, as there is nowhere to return to. 他们不会返回,因为无处可回。

What people usually mean, can be done with the fork exec wait syscalls, see above. 人们通常的意思是,可以使用fork exec wait syscall来完成,请参见上文。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM