2015-05-21 3 views
1
#include <stdio.h> 
#include <unistd.h> 
main() 
{ 
    execlp("ls" , "ls", "-l", "|" , "sort", NULL);  
} 

Что случилось? Пожалуйста помоги.Почему execlp не позволяет мне использовать трубку?

Если я пишу это: execlp("ls" , "ls", "-l", NULL); тогда результат отображается на экране, и если я пытаюсь это execlp("ls" , "ls", "-l", "|" , "sort", NULL); экран сообщение об ошибке отображается не может получить доступ к.

Почему? Кто-нибудь есть идеи? Почему он не позволяет мне использовать трубу (|), когда я выполняю команду execlp?

+0

потому сортировки другой программы. – resultsway

+0

@purpletech Что вы имеете в виду? Не могли бы вы кратко объяснить? – anorthosi

+0

«ls» и «sort» - это две программы. первый аргумент execlp может иметь дело только с одной программой. в основном он накладывает память на эту новую программу, которую вы указываете в первом аргументе, и передает параметры, которые вы упомянули. – resultsway

ответ

2

Когда вы пишете следующую команду в оболочке выполняются

ls -l | sort 

две программы: ls и sort.

Символ трубы (|) означает, что выход первого должен быть перенаправлен на стандартный вход второго. Эта труба интерпретируется вашей оболочкой. Это не параметр вашей команды.

execlp принимает имя вашей программы и ее параметров в качестве аргументов.

Так что, когда вы пишете

execlp("ls" , "ls", "-l", "|" , "sort", NULL); 

это не имеет никакого смысла, так как | и sort не являются параметрами ls.

Что вы хотите делать то, что оболочка делает для вас:

  1. объявить pipe
  2. сделать вилку, где вы перенаправлять стандартный вывод в вашей трубе (с dup) и выполнить ls:

    execlp("ls" , "ls", "-l", NULL); 
    
  3. сделать вилку, где вы перенаправляете свою трубу на stdin и выполняете sort:

    execlp("sort" , "sort", NULL); 
    
  4. закрыть трубу, подождите и т.д.

2

Трубопровод представляет собой конструкцию оболочки. execlp() не подлежит разбору оболочки; он передает аргументы непосредственно указанной команде. Чтобы получить функции оболочки, вам нужно явно запустить процесс оболочки.

execl("/bin/sh", "/bin/sh", "-c", "ls -l | sort", NULL); 

В этом случае это, вероятно, лучше всего указать абсолютный путь к оболочке /bin/sh, что означает, что вы можете использовать execl вместо execlp.

2

Oups, вы создаете путаницу. exec... Семейные функции позволяют выполнять одну единственную программу заменяя вызывающего абонента. Таким образом, ваша программа просто выполняет команду ls с "-l", "|", "sort" как параметры.

Вот что это дает в интерактивном режиме:

$ ls "-l" "|" "sort" 
ls: sort: No such file or directory 
ls: |: No such file or directory 

На другом конце, то вы выполняете нормально ls -l | sort в оболочке, то |интерпретируется оболочкой. И оболочка:

  • начинает ls -l в качестве первой команды
  • начинает sort как вторая команда
  • с выходом первой команды, подключенной к входу второго.

Вы можете сделать это явно с помощью fork, pipe и execlp, но вы должны будете подготовить трубу, и явно раскошелиться для того, чтобы иметь 2 процессов.

В качестве альтернативы, вы можете попросить скорлупу, чтобы сделать работу:

execlp("/bin/sh" , "sh", "-c", "ls -l | sort", NULL); 
1

Существует простой способ сделать это. Она включает в себя использование функции popen:

#include <stdio.h> 
#include <unistd.h> 

int main() { 

    FILE* out = popen("ls -l | sort", "w"); 

    pclose(out); 

    return 0; 
} 

Однако это может быть не то, что вы собираетесь для, как он не использует EXEC.

Смежные вопросы