我创建了一个shell程序,可以或多或少地执行普通的linux shell。我的程序可以正确地重定向输入或输出,但不能同时重定向输入或输出。到目前为止,任何在线解决方案都对我有用。
e.g。
" echo hi kenny > kenny.txt " works
" cat in.txt | less " works
但是,(假设in.txt是随机字母文件)
" sort -u < in.txt > out.txt " does not work for both, only for the input(<).
我的代码大致如下:
int main(int argc, char* argv[]){
readLine();
if (lineHasSpecialSymbols()) {
if(hasInput()){
inRedirection();
}else
outRedirection();
}
}
让我们假设这一切都需要。没有管道等。
readLine()从终端读取一行并将其保存在args []
中lineHasSpecialSymbols()检测&#39;&lt;&#39;的第一个实例或者&#39;&gt;&#39;并返回。
这是inRedirection()如何工作的棘手部分:
void inRedirection(void) {
extractCommand("<");
int fd;
if ((pid = fork()) == -1) {
perror("fork");
exit(1);
}
if (pid == 0) {
close(0);
//open the file args2[0] and use it as standard input
fd = open(args2[0], O_RDWR);
execvp(args[0], args);
perror("execv");
exit(1);
}
if (pid != 0) {
wait(NULL);
printf("Done ");
printf(args[0]);
printf(".\n");
}
}
outRedirection():
void outRedirection(void) {
extractCommand(">");
int fd;
if ((pid = fork()) == -1) {
perror("fork");
exit(1);
}
if (pid == 0) {
close(1);
fd = creat(args2[0], 0644);
execvp(args[0], args);
perror("execv");
exit(1);
}
if (pid != 0) {
wait(NULL);
printf("Done ");
printf(args[0]);
printf(".\n");
}
}
最后,extractCommand():
void extractCommand(char* symbol) {
int i;
int count = 0;
for (i = 0; args[i] != NULL; i++)
if (!strcmp(args[i], symbol)) {
args[i] = NULL;
while (args[i+1] != NULL) {
args2[count] = args[i+1];
args[i+1] = NULL;
i++;
count++;
}
}
}
抱歉,对于巨大的代码。这就是问题所在:
我们说我输入命令:
&#34; sort -u&lt; in.txt&gt; out.txt&#34;
代码会检测到&#39;&lt;&#39;并将命令提取为两部分。
args[0] = "sort" args2[0] = "in.txt" args2[2] = "out.txt"
args[1] = "-u" args2[1] = ">"
只有&#34;排序-u&lt; in.txt&#34;而不是其余的。我的问题是如何更改我的代码才能成为意图?另外,如何为两个以上的命令执行此操作?例如:&#34; ls -l / home / user | sort -u | wc -l&gt; in.txt&#34;
我已经想过一些算法,比如制作第三个args(args3),但是在更多这两个命令的情况下会发生碰撞。
答案 0 :(得分:1)
我建议你改变你的方法。
int outRedirection(void) {
int i;
int j;
for(i = 0; args[i] != NULL; i++) {
// Look for the >
if(args[i][0] == '>') {
args[i] = NULL;
// Get the filename
if(args[i+1] != NULL) {
output_filename[0] = args[i+1];
} else {
return -1;
}
//For- loop to make input AND output functional
for(j = i; args[j-1] != NULL; j++) {
args[j] = args[j+2];
}
return 1;
}
}
return 0;
}
对输入做同样的事情然后执行如下:
void IOcommand(void){
if ((pid = fork())== -1){
perror("fork");
exit(1);
}if (pid == 0){
if (input == 1)
freopen(input_filename[0], "r", stdin);
if (output == 1)
freopen(output_filename[0], "w+", stdout);
execvp(args[0],args);
exit(-1);
}
if (pid != 0 ){
wait(NULL);
printf("Done ");
printf(args[0]);
printf(".\n");
}
}