bash, возврат из перенаправленного цикла, безопасен ли он?

Обратите внимание, что мы возвращаемся из цикла, который перенаправляется.

Я не знаю, если я должен беспокоиться о буфере записи «файла».

function f { i=1 while : do echo aaaaaaaaaaaaabbbbbbbbbbbbbbbbb ((i++)) if [ $i -gt 3 ] then return # return while redirected fi done >> file # writing to file } f 

ПРИМЕЧАНИЕ. Я знаю, что эту функцию можно было бы легко переписать, так что она не вернется из перенаправленного цикла. Однако это просто упрощенный пример для этого вопроса.

Поэтому, пожалуйста, не пытайтесь улучшить этот код.

Меня тоже не интересуют обходные пути.

Мой единственный вопрос: если есть что-то, о чем я должен знать. Как и дескриптор файла, он не закрыт должным образом. Или иногда я могу ожидать, что в файл будет записана только половина буфера (т. Е. «Aaaaaa»).

Я хотел бы знать, если это очень плохая идея и почему? Или, может быть, это будет работать без непредвиденных условий гонки или подобных? (но опять же, я не хочу, чтобы ответы вроде «это плохо, потому что вы должны использовать этот и этот шаблон вместо этого»)

Хотя каждая команда может иметь свой собственный буфер записи, нет буфера записи, который совместно используется командами, даже встроенными в bash (или даже двумя вызовами одной и той же команды, встроенной или нет).

Даже ksh93, который, как известно, выполняет некоторую оптимизацию ввода-вывода (например, он будет читать дальше и делиться некоторыми данными на входе ( вызывая некоторые ошибки )), не делает этого.

Таким образом, это будет безопасно в этом отношении. После завершения команды, например, вашего echo aaaaaaaaaaaaabbbbbbbbbbbbbbbbb , и при условии, что он не поддерживает автоматический процесс без работы в фоновом режиме, вы можете быть echo aaaaaaaaaaaaabbbbbbbbbbbbbbbbb , что все echo aaaaaaaaaaaaabbbbbbbbbbbbbbbbb ввода-вывода выполнены.

Тем не менее, несколько заметок. В такой функции, как:

 f() { { echo x return echo y } > file echo something else } 

В оболочке Bourne (и только в оболочке Bourne) этот return прерывает вывод внутренней группы команд, но не возвращает функцию, как в этой древней оболочке, эта группа команд будет работать в подоболочке из-за перенаправления (так что вы 'd увидеть что- something else ).

Это больше не происходит в современных оболочках, таких как bash , но у вас будет такая же проблема в bash, если вы написали:

 f() { ( echo x return echo y ) > file echo something else } 

или

 f() { { echo x return echo y } | tr xy ab echo something else } 

Остерегайтесь случаев, когда некоторые команды не ждут. В:

 f() { { echo >(sleep 1; echo x) return } > file } f; cat file 

Вы можете обнаружить, что x не отображается, потому что cat запускается до echo x .

Некоторые оболочки (хотя и не bash ) имеют схожие потенциальные проблемы с компонентами конвейера, другими словами, самый правый.