Если по трубопроводу две вложенные оболочки, каждая из которых перезаписывает файл, почему содержимое файла непредсказуемо? - PullRequest
1 голос
/ 01 декабря 2019

Я хотел бы узнать, почему после ввода следующей команды "(echo" 1 "> file) | (echo" 2 "> file)" в bash содержимое файла с именем "file" может бытьчисло 2 - иногда. Обычно содержимое файла равно 1 после выполнения команды, но иногда оно равно 2.

[root@server root]# (echo "1" > file) | (echo "2" > file)
[root@server root]# cat file
2

из PuTTY

Ответы [ 3 ]

3 голосов
/ 01 декабря 2019

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

1 голос
/ 01 декабря 2019

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

В первой строке команд есть две субоболочки, которые одновременно изменяют один и тот же файл - в зависимости от того, какая запись подоболочкиИ наконец, содержимое файла будет тем, что написал этот подоболочек.

0 голосов
/ 01 декабря 2019

Это потому, что элементы конвейера выполняются параллельно и потому что echo справа не ожидает триггера;он не ждет ввода перед выполнением действия вывода.

Если мы сделаем это так:

( echo "1" > file ) | ( read; echo "2" > file)

, тогда мы получим 2 в файле. Второй конвейерный элемент имеет read, который блокируется до тех пор, пока не получит ввод, или индикация окончания ввода. Таким образом, элемент конвейера приостанавливается в read, пока не выйдет левый echo. Затем он выполняет echo "2" > file, который предсказуемо перезаписывает 1. К тому времени левый echo больше не работает, поэтому гонка разрешена.

Кстати, нам не нужны скобки в нижнем регистре в исходной версии. Это эквивалентно:

echo "1" > file | echo "2" > file

и моя измененная версия может быть:

echo "1" > file | ( read; echo "2" > file)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...