我正在尝试在C中实现LINUX shell但是当我尝试运行这样的命令时:sort -u < in.txt > out.txt
它说:sort: cannot read: '<': No such file or directory
。我也尝试了其他命令,如ls -l > out.txt
等,但它一直在告诉我同样的事情。这是我的代码:
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <sys/types.h>
#define LENGTH 1024
int main(){
char line[LENGTH];
char* argv[100];
char* path= "/bin/";
char fullPath[30];
int option;
char* inputFile;
char* outputFile;
while(1){
printf("mysh3>");
if(!fgets(line,LENGTH,stdin)){
break;
}
size_t length = strlen(line);
if(line[length-1]=='\n')
line[length-1] = '\0';
}
char* token;
token = strtok(line," ");
int i = 0;
while(token!=NULL){
argv[i]=token;
token = strtok(NULL," ");
i++;
}
if(argv[1]==">"){
option=1;
outputFile=argv[2];
}
else if(argv[2]==">"){
option = 1;
outputFile=argv[3];
}
else if(argv[1]=="<" && argv[3]==">"){
option=2;
inputFile=argv[2];
outputFile=argv[4];
}
else if(argv[2]=="<" && argv[4]==">"){
option=2;
inputFile=argv[3];
outputFile=argv[5];
}
else if(argv[1]=="<" && argv[3]==">>"){
option=3;
inputFile=argv[2];
outputFile=argv[4];
}
else if(argv[2]=="<" && argv[4]==">>"){
option=3;
inputFile=argv[3];
outputFile=argv[5];
}
argv[i]=NULL;
strcpy(fullPath, path);
strcat(fullPath, argv[0]);
for(int i = 0; i < strlen(fullPath); i++){
if(fullPath[i]=='\n'){
fullPath[i]='\0';
}
}
int ret=forkEx2(argv,inputFile,outputFile,fullPath,option);
if(ret==-1) {
return -1;
}
int forkEx2(char* argv[],char* inputFile,char* outputFile,char
fullPath[],int option){
int fd;
pid_t pid,waitPid;
pid = fork();
if(pid<0){
perror("ERROR: Fork failed.\n");
return -1;
}
else if(pid==0){
if(option==1){
fd=open(outputFile,O_CREAT | O_TRUNC | O_WRONLY, 0600); //if the file does not exist the system create it. Clear all data from the file. Open the file for write only.Store its file descriptor in fd
dup2(fd,STDOUT_FILENO); //replace the standar out with the file
close(fd);
}
else if(option==2){
fd=open(inputFile,O_RDONLY,0600); //open the file for read only
dup2(fd,STDIN_FILENO); //replace the standar in with the file
close(fd);
fd=open(outputFile,O_CREAT | O_TRUNC | O_WRONLY, 0600); //if the file does not exist the system create it. Clear all data from the file. Open the file for write only
dup2(fd,STDOUT_FILENO); //replace the standar out with the file
close(fd);
}
else if(option==3){
fd=open(inputFile,O_RDONLY,0600); //open the file for read only
dup2(fd,STDIN_FILENO); //replace the standar in with the file
close(fd);
fd=open(outputFile, O_APPEND | O_WRONLY, 0600); //append at the end of the file. Open the file for write only
dup2(fd,STDOUT_FILENO); //replace the standar out with the file
close(fd);
}
execvp(fullPath,argv);
perror("ERROR: Child should never arrive here.\n");
}
else{
waitPid = wait(&waitPid);
if (waitPid == -1) {
perror("ERROR: Waitpid failed.\n");
return -1;
}
printf("Parent: Finished pid %d.\n", waitPid);
}
}
}
感谢任何帮助。
答案 0 :(得分:2)
让我们来看看这个案例(在所有情况下都是一样的):
else if(argv[2]=="<" && argv[4]==">"){
option=2;
inputFile=argv[3];
outputFile=argv[5];
}
首先,您使用==
比较字符串:这不起作用。您必须使用strcmp
或者您正在比较指针。
然后,您正在提取输入文件&amp;输出文件可以,但您忘记从argv
中删除重定向参数。您必须将它们过滤掉(每次遇到一个重定向参数时,通过移动参数数组的其余部分)
除此之外:您应该初始化argv
数组,否则如果没有足够的参数,您可能会遇到未定义的行为。