Вот что я мог придумать - это немного запутанно, но foo
запускается в контексте оболочки верхнего уровня, и его вывод предоставляется в переменной a
в контексте оболочки верхнего уровня:
#!/bin/bash
foo () { echo ${BASH_SUBSHELL}; }
mkfifo /tmp/fifo{1,2}
{
# block, then read everything in fifo1 into the buffer array
i=0
while IFS='' read -r ln; do
buf[$((i++))]="$ln"
done < /tmp/fifo1
# then write everything in the buffer array to fifo2
for i in ${!buf[@]}; do
printf "%s\n" "${buf[$i]}"
done > /tmp/fifo2
} &
foo > /tmp/fifo1
read a < /tmp/fifo2
echo $a
rm /tmp/fifo{1,2}
Это, конечно, предполагает две вещи:
- FIFO разрешены
- Группу команд, выполняющую буферизацию, можно перевести в фоновый режим.
Я проверил, как это работает в следующих версиях bash:
- 3.00.15(1)-выпуск (x86_64-redhat-linux-gnu)
- 3.2.48(1)-выпуск (x86_64-apple-darwin12)
- 4.2.25(1)-выпуск (x86_64-pc-linux-gnu)
Приложение
Я не уверен, что подход mapfile
в bash 4.x делает то, что вы хотите, поскольку замена процесса <()
создает совершенно новый процесс bash (хотя и не подоболочку bash внутри этого процесса bash):
$ bar () { echo "$BASH_SUBSHELL $BASHPID"; }
$ bar
0 2636
$ mapfile -t bar_output < <(bar)
$ echo ${bar_output[0]}
0 60780
$
Таким образом, хотя $BASH_SUBSHELL
здесь равен 0, это потому, что он находится на верхнем уровне нового процесса оболочки 60780 в замене процесса.
person
Digital Trauma
schedule
07.02.2014
mapfile
? Насколько мне известно, эквивалентаbash
нет ни в одной версии. - person chepner   schedule 07.02.2014mapfile -t foo_output <(foo)
- это замена процесса -foo
запускается в совершенно новом процессе, что, я думаю, вам не нужно. Смотрите дополнение к моему ответу. - person Digital Trauma   schedule 07.02.2014mapfile
, но поскольку он читает стандартный ввод, а не файл, вам, возможно, придется писать< <(cmd)
, а не просто<(cmd)
, поскольку<(cmd)
в конечном итоге заменяется чем-то вроде/dev/fd/63
(попробуйтеecho <(echo)
, чтобы проверить это). По крайней мере, кажется, что так не висит. - person Alice M.   schedule 11.09.2018