Программа Bash не выполняется, если перенаправление не сработало

Если все эти 7 Справочников находятся в одном месте, обратитесь к комментарию Кристофера

ls -R

Здесь будет перечислено все содержимое каталога 7, если они находятся в одном месте.

9
28.04.2016, 02:51
4 ответа

На самом деле вопрос не в порядке проверок, а просто в порядке, в котором оболочка устанавливает вещи. Перенаправления настраиваются перед запуском команды; поэтому в вашем примере оболочка пытается открыть ~ root / log для добавления, прежде чем делать что-либо, связанное с ./ write_file.py . Поскольку файл журнала не может быть открыт, перенаправление не выполняется, и в этот момент оболочка прекращает обработку командной строки.

Один из способов продемонстрировать это - взять неисполняемый файл и попытаться запустить его:

$ touch demo
$ ./demo
zsh: permission denied: ./demo
$ ./demo > ~root/log
zsh: permission denied: /root/log

Это показывает, что оболочка даже не смотрит на ./ demo , когда перенаправление может ' не быть настроенным.

18
27.01.2020, 20:03

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

Рассмотрим ваш пример:

./write_file.py >> ~root/log

В оболочке происходит следующее:

  1. Мы (оболочка) fork () ; дочерний процесс наследует дескрипторы открытых файлов от своего родителя (оболочки).
  2. В дочернем процессе мы fopen () (расширение) «~ root / log» и dup2 () его до fd 1 (и закрываем () временный fd). В случае сбоя fopen () вызовите exit () , чтобы сообщить об ошибке родителю.
  3. Все еще в дочернем состоянии, мы exec () "./write_file.py". В этом процессе больше не выполняется какой-либо из наших кодов (если мы не смогли выполнить, и в этом случае мы exit () , чтобы сообщить об ошибке родителю).
  4. Родитель будет wait () для завершения дочернего процесса и обработает его код выхода (копируя его, по крайней мере, в $? ).

Таким образом, перенаправление должно происходить в дочернем элементе между fork () и exec () : этого не может произойти до fork () , потому что это не должен изменять стандартный вывод оболочки, и это не может произойти после exec () , потому что имя файла и исполняемый код оболочки теперь заменены программой Python. Родитель не имеет доступа к файловым дескрипторам дочернего элемента (и даже если бы он был, он не мог гарантировать перенаправление между exec () и первой записью в stdout).

3
27.01.2020, 20:03

На странице руководства bash, раздел ПЕРЕНАПРАВЛЕНИЕ (выделено мной):

Перед выполнением команды ее ввод и вывод могут быть перенаправлены с использованием специальной нотации, интерпретируемой оболочкой .

...

Ошибка при открытии или создании файла приводит к сбою перенаправления.

Итак, оболочка пытается открыть целевой файл для stdout , но это не удается, и команда не выполняется вообще.

11
27.01.2020, 20:03

Сожалею, что сообщаю вам, что это как раз наоборот. Оболочке необходимо сначала открыть свой ввод-вывод, а затем передать управление программе.

tee может оказаться полезным в этом случае: ./ write_file.py | tee -a ~ root / log> / dev / null

0
27.01.2020, 20:03

Теги

Похожие вопросы