Какова спецификация POSIX о поведении встроенных команд с перенаправлениями и/или конвейерами?

Нет возможности иметь несколько файлов с одинаковым именем в одном каталоге. Вы можете разрешить cp --backup=numberedавтоматически добавлять файлы резервных копий с суффиксами в порядке возрастания для ранее существовавших файлов (с )с тем же именем.

2
26.04.2019, 19:37
2 ответа

Это происходит потому, что exitвыполняется в подоболочке для exit | cat, а не для exit > /dev/null. Выход из подоболочки не приводит к выходу из основной оболочки:

If the current execution environment is a subshell environment, the shell shall exit from the subshell environment with the specified exit status and continue in the environment from which that subshell environment was invoked

Но конкретная разница подоболочки или не подоболочки указана в разделе 2.12 стандарта POSIX – чтобы процитировать соответствующий отрывок полностью:

A subshell environment shall be created as a duplicate of the shell environment, except that signal traps that are not being ignored shall be set to the default action. Changes made to the subshell environment shall not affect the shell environment. Command substitution, commands that are grouped with parentheses, and asynchronous lists shall be executed in a subshell environment. Additionally, each command of a multi-command pipeline is in a subshell environment; as an extension, however, any or all commands in a pipeline may be executed in the current environment. All other commands shall be executed in the current shell environment.

Здесь exit | catподходит под описание:

each command of a multi-command pipeline is in a subshell environment

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

as an extension, however, any or all commands in a pipeline may be executed in the current environment

... Это означает, что это не гарантируется во всех оболочках. Раньше мне приходилось отлаживать код, в котором одна реализация выполняла правую часть конвейера в текущей оболочке, позволяя следующей работать с некоторыми реализациями KSH, но не с другими :

.
cat foo | while read line
do
    X="$line"
done

Поэтому всегда предполагайте, что канал может порождать подоболочку, но не полагайтесь на нее.

0
27.01.2020, 22:02

Колодец(выход ),

The exit utility shall cause the shell to exit from its current execution environment [...]

и(2.12. Среда выполнения оболочки)

A subshell environment shall be created as a duplicate of the shell environment, [...] Additionally, each command of a multi-command pipeline is in a subshell environment; as an extension, however, any or all commands in a pipeline may be executed in the current environment. All other commands shall be executed in the current shell environment.

Таким образом, exitв конвейере запускается в собственной среде выполнения/подоболочке и выходит только из нее, в то время как команда в простой команде exit > /dev/nullзапускается в основной среде оболочки. (Как отмечалось в комментариях, перенаправление на самом деле никак на это не влияет.)

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

В Bash с lastpipe, например:

$ bash -c 'true | exit; echo end.'
end.

Но

$ bash -O lastpipe -c 'true | exit; echo end.'

ничего не печатает.

3
27.01.2020, 22:02

Теги

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