Subshells и ( )
Тема дорожной карты · Bash
Дочерняя оболочка (subshell) — дочерняя копия текущего процесса Bash, запускаемая обёртыванием команд в скобки ( commands ), которая наследует окружение родителя — переменные, функции и рабочий каталог — в момент создания, но не может изменять окружение родителя. Эта изоляция является фундаментальным свойством написания Bash-скриптов: любые cd, присваивания переменных или определения функций внутри дочерней оболочки исчезают при её завершении, что делает дочерние оболочки идеальными для изолирования побочных эффектов в скриптах автоматизации Linux. Подстановка команд $(command) неявно запускает команду в дочерней оболочке, как и подстановка процессов <(command), и каждый этап конвейера в Bash (до опции lastpipe в Bash 4.2). Поскольку дочерние оболочки являются полноценными разветвлениями процесса, они требуют накладных расходов; для производительных Bash-скриптов рекомендуется минимизировать лишние дочерние оболочки, предпочитая встроенное расширение параметров вместо $(echo ...) или $(cat file). Понимание того, как дочерние оболочки наследуют и изолируют состояние, необходимо для отладки проблем с областью видимости и написания предсказуемых и корректных Bash-скриптов на Linux.
Как это работает
Subshells и ( ): фоновые задания (cmd &, wait), job control (jobs, fg, bg), command substitution ($(cmd) — современный, `cmd` — legacy), арифметика ($((expr)), (( ))), brace expansion ({1..10}, {a,b,c}), trap-сигналы (trap "..." SIGINT SIGTERM), coproc (coproc cmd { ... } для двунаправленных пайпов), exec (exec cmd заменяет shell).
Когда применять
& + wait — для параллелизации независимых медленных операций (multi-host SSH, batch-загрузки). $() лучше backticks (чище, вкладываемы). trap "cleanup" SIGINT SIGTERM EXIT — для graceful shutdown. Coproc — редко; его особенности нишевые.
Типичные ошибки
Ловушки Subshells и ( ): фоновый запуск без wait (скрипт выходит, jobs убиты); арифметика через expr (медленно, legacy — используйте $(( ))); brace expansion в скриптах для POSIX-совместимости (это bash-расширение); долгие фоновые jobs держат терминал (disown или nohup).