编辑:问题是echo显然不从stdin读取。谢谢@Jonathan Leffler
我有一个编程练习,我的代码如下:int processProgram(char **tokens, int requireWait) {
char *cmd = tokens[0];
if (access(cmd, R_OK) == -1) {
printf("%s not foundn", cmd);
return -1;
}
int index = 1;
char *iterator = tokens[index];
int inputTokenIndex = 0;
// Look for a < to figure out where the redirection is
while (iterator != NULL) {
if (strcmp(iterator, "<") == 0) { // <---- THIS IS WHERE I ATTEMPT TO FIND THE INDEX OF "<"
if (access(tokens[index + 1], R_OK) == -1) {
printf("%s does not existn", tokens[index + 1]);
return -1;
}
// set null at <
tokens[index] = NULL;
inputTokenIndex = index + 1;
break;
}
index++;
iterator = tokens[index];
}
// basically create a struct to store pids and stuff....
processList *process = addNewProcess();
int childPid = fork();
if (childPid == 0) {
// is the child
if (inputTokenIndex > 0) {
// if previously strcmp "<" is true
// set redirection for input....
int fd = open(tokens[inputTokenIndex], O_RDONLY); // <----- THIS IS WHERE I DO THE REDIRECTING FOR STDIN!
dup2(fd, STDIN_FILENO);
close(fd);
}
// start from where inputTokenIndex could have left off
// since > is always at least after < in our test cases
index = inputTokenIndex + 1;
iterator = tokens[index];
while (iterator != NULL) { // <--- LOOKING FOR ">" and "2>", CURRENTLY THIS WORKS FINE
// look for output redirection FROM previous while loop onwards
int out = 0;
if (strcmp(iterator, ">") == 0) {
// stdout
out = STDOUT_FILENO;
} else if (strcmp(iterator, "2>") == 0) {
// stderr
out = STDERR_FILENO;
}
if (out != 0) {
int fd = open(tokens[index + 1], O_WRONLY | O_TRUNC | O_CREAT, 0777);
dup2(fd, out);
tokens[index] = NULL;
close(fd);
}
index++;
iterator = tokens[index];
}
int value = execv(cmd, tokens); // <----- EXEC IS HERE!!
if (value == -1) {
exit(errno);
}
exit(0);
} else {
int status;
if (requireWait == 1) {
// wait for process to finish
process->pid = childPid;
wait(&status);
process->running = 0;
process->status = status;
if (status != 0) {
printf("%s failed", cmd);
}
} else {
process->pid = childPid;
printf("Child[%d] in backgroundn", childPid);
// no return should be expected
status = 0;
}
return status;
}
}
这个想法是模拟linux重定向使用<和在>和在>
tokens是提供给shell的字符串数组。
向"a.t txt"写入hello的示例调用:/bin/echo hello>。/a.txt
它不能用于重定向in,即"/bin/echo
文件a.txt是使用这个程序创建的。完整的例子是
/bin/echo hellooooo>。/a.txt
/bin/echo & lt;。/a.txt
,其中第一个命令成功创建并写入a.t txt,但第二个命令只生成一个空行
如何帮助
假设tokens是正确的,并且文件名存在,为什么execv()调用不从文件名中接收输入(假设我重定向了它????)
谢谢你的阅读!!
正如我在评论中指出的那样,echo
命令不读取标准输入,因此您将无法判断echo
(或sleep
)的输入重定向是否成功。
使用一个读取标准输入的命令——cat
是最简单的例子,但tr
和sed
可能是明智的选择。