我正在编写自己的 shell,我试图支持像 ls -la /* 或 top 这样的外部命令,但是当我尝试运行 execvp() 时,它给了我
exec permission denied
,因此我尝试使用 sudo chmod +777 /bin/
包括任何文件我尝试跑步,但这并没有什么作用。因此我在这里寻求帮助。下面的代码是我通过execvp()
调用外部命令的地方。另外,我尝试通过 strcat() 两次创建路径,并在路径上循环添加 args[0]
和 args[1]
(手动连接),但是每次我循环路径和 args[0]
时,args[1]
也变成相同的字符串作为 arg[0]
,我找不到解决办法。
void extern_com(char* buffer){
int i = 0, j = 1, k = 0;
pid_t pid;
char *args[5];
char temp[MAX_CMD_BUFFER];
args[0] = "/bin/";
args[4] = NULL;
while(buffer[i] != '\0'){
temp[k] = buffer[i];
printf("%c\n", buffer[i]);
if(buffer[i] == '\n'){
temp[k] = '\0';
char temp_arg[k+1];
k = 0;
while(temp[k] != '\0'){
temp_arg[k]=temp[k];
k++;
}
temp_arg[k]='\0';
args[j] = temp_arg;
break;
}
if(buffer[i] == ' '){
temp[k] = '\0';
char temp_arg[k+1];
k = 0;
while(temp[k] != '\0'){
temp_arg[k]=temp[k];
k++;
}
temp_arg[k]='\0';
args[j] = temp_arg;
j+=1;
k = 0;
i+=1;
continue;
}
k++;
i++;
}
if(j < 3){
j+=1;
for(j = j; j<4; j++){args[j] = NULL;}
}
printf("print args[0] %s\n", args[0]);
printf("print args[1] %s\n", args[1]);
int len0 = strlen(args[0]), len1 = strlen(args[1]), len=len0+len1;
char path[len+1];
for(i = 0; i<len0; i++){
path[i] = args[0][i];
}
for (i = len0; i < len; ++i)
{
path[i] = args[1][i-len0];
}
path[strlen(path)] = '\0';
printf("path: %s\n", path);
pid = fork();
if(pid==0) { //fork child
execvp(args[0], args);
perror("exec");
} else { //Parent
wait(NULL);
}
}
TLDR:该命令不作为 exec 运行:权限被拒绝,并将 args[0] 和 args[1] 复制到路径上似乎每次都会破坏其中一个。谢谢你
这里有两个主要问题。首先是这个:
args[0] = "/bin/";
由于这也是您作为第一个参数传递给
execv
的内容,因此您表示要运行命令“/bin/”。这是一个目录,目录不可执行(至少不是文件的意义上),因此会出现权限被拒绝错误。
您希望从 0 而不是 1 开始
j
,因此“ls”会放在 argv[0]
作为命令名称。
其次,您在两个块内声明它:
char temp_arg[k+1];
然后将
temp_arg
分配给 args
的元素之一,然后退出该块。该内存现已超过其生命周期,随后尝试引用它将在代码中触发未定义的行为。
您需要动态分配此内存,使其比块的寿命更长:
char *temp_arg = malloc(k+1);