C - Перенаправление ввода-вывода дочернего процесса - PullRequest
1 голос
/ 02 апреля 2019

Я пытаюсь перенаправить ввод-вывод дочернего процесса (после fork()) в файл, и я не могу понять, почему он не работает.

Вот что я сделал:

if(fork() == 0){
    execv(exe, (char*[]){ exe, "> temp.exe" });
    ...

И исполняемый файл запускается, но не перенаправляет в файл.Буду признателен, если кто-нибудь сможет объяснить, что я делаю неправильно и как я должен это делать.У меня такое ощущение, что мне нужно перенаправить до execv(), но я не знаю, как это сделать.

Заранее спасибо!

Ответы [ 2 ]

3 голосов
/ 02 апреля 2019

Перенаправления оболочки (например, > file) осуществляются оболочкой. Используя execve(), вы обходите оболочку; дочерний процесс увидит "> temp.exe" в argv и попытается обработать его в качестве аргумента.

Если вы хотите перенаправить вывод в файл, самым простым способом будет реализовать это перенаправление самостоятельно, открыв файл после разветвления и используя dup2(), чтобы переместить его файловый дескриптор в стандартный вывод:

if (fork() == 0) {
    int fd = open("temp.exe", O_CREAT | O_WRONLY, 0666);
    if (fd < 0) { handle error... exit(255); }
    dup2(fd, 1);
    close(fd);
    execv(exe, ...);
}
0 голосов
/ 02 апреля 2019

Семейство вызовов execX () не обладает такой же гибкостью, как, например, system () или popen ().Эти последние методы вызывают shell для интерпретации команды.

Аргументы вызова execX - это точный путь к программе, которую вы хотите запустить, и аргументы, которые вы хотите дать этой программе.Любые функции «оболочки», такие как перенаправление, которые вы должны реализовать самостоятельно перед вызовом execX.

В качестве альтернативы, вы можете позволить shell фактически выполнять работу, execp("sh","sh",myexe+" >test.txt");, но это лениво, и тогда почему бы просто не использовать systemв любом случае?

Два очень полезных метода - это pipe () и dup2 (): pipe позволяет создавать каналы для вашей хост-программы;dup2 позволяет вам установить сценарий, в котором выполняемая программа думает, что пишет в stdout (1) или читает из stdin (0), но на самом деле пишет или читает созданный вами файл или канал.

Вы пройдете долгий путь, прочитав справочные страницы для pipe и dup2, или в google, ища exec pipe и dup2, так что я не откажусь от вашего удовольствия, написав полную реализацию здесь.

...