Я пытаюсь выполнить серию команд как единое целое внутри основной оболочки, но способ, которому меня учили, работает только внутри подоболочки:
решение1
Зависит от того, что вы подразумеваете подв целом.
Если вы имеете в виду только отправку нескольких команд в оболочку и гарантию того, что оболочка не начнет их выполнять, пока вы не введете их все, то вы можете просто сделать:
cmd1; cmd2
Или
cmd1 Ctrl+VCtrl+Jcmd2
(или включите функцию вставки в скобках ( bind 'set enable-bracketed-paste on'
) и вставляйте команды из терминала, который поддерживает вставку в скобках).
Или:
{
cmd1
cmd2
}
Расположить их на нескольких линиях.
Если вы хотите сгруппировать их так, чтобы они использовали один и тот же stdin или stdout, например, вы можете использовать:
{ cmd1; cmd2; } < in > out
Или
eval 'cmd1; cmd2' < in > out
Если вы хотите, чтобы они запускались с собственной областью действия переменных и опций, поскольку bash
у них нет эквивалента zsh
анонимных функций, вам нужно будет определить временную функцию:
f() { local var; var=foo; bar;}; f
решение2
Вместо ( something )
, который запускается something
в подоболочке, используйте { something ; }
, который запускается something
в текущей оболочке
После точки (или точки) необходимо {
поставить пробелы, а ;
перед точкой (или точкой) — символ новой строки }
.
Бывший:
$ { echo "hello $BASHPID";sleep 5;echo "hello again $BASHPID" ; }
hello 3536
hello again 3536
Однако обратите внимание, что если вы запускаете некоторые сложные команды (или конвейерные команды), они в любом случае большую часть времени будут находиться в подоболочке.
А «переносимый» способ получить pid вашей текущей оболочки — это $$
.
Поэтому я бы вместо этого записал ваш тест так:
{ echo "hello $$"; sleep 5 ; echo "hello again $$" ; }
(в любом случае сон здесь не особо полезен)