linux execvp; ls не может получить доступ|, Нет такого файла или каталога
Я пытаюсь закодировать оболочку. Но моя оболочка не выполняет команду-ls-l | less. Я использую execvp. код приведен ниже.
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main(){
int pid, status, num, len;
char str[1000], cwd[100];
char* word[100];
getcwd(cwd, sizeof(cwd));
while(1){
chdir(cwd);
printf("%s > ", cwd);
gets(str);
pid=vfork();
if(pid == 0){
num = 0;
word[num] = strtok (str, " ");
while (word[num] != NULL) {
word[num] = strdup (word[num]);
len = strlen (word[num]);
if (strlen (word[num]) > 0)
if (word[num][len-1] == 'n')
word[num][len-1] = '';
word[++num] = strtok (NULL, " ");
}
if(strcmp(word[0], "cd") == 0){
chdir(word[1]);
getcwd(cwd, sizeof(cwd));
}
else{
execvp(word[0],word);
}
exit(0);
}
else{
wait(&status);
}
}
return 0;
}
1 ответов
ls -l | less
фактически является командной строкой оболочки, которая состоит из двух процессов, Соединенных каналом. The execvp()
вызов может породить только один процесс.
если вы хотите сделать это из своей программы, вы должны вызвать оболочку явно-либо с помощью system()
вызов, или путем изменения командной строки на sh -c 'ls -l | less'
. Ваш word
массив должен выглядеть так:
word[0] = "sh"
word[1] = "-c"
word[2] = "ls -l | less"
word[3] = NULL
[EDIT] кроме того, вы можете сделать то, что оболочка делает внутри: породить два процесса и соедините их трубой. Это будет включать использование fork()
, pipe()
, dup2()
и execve()
звонки. Однако вызов оболочки намного меньше работы, и так как less
это интерактивная программа в любом случае, вам не нужно беспокоиться о производительности: все, что занимает менее 100 мс, воспринимается как мгновенное.