Оболочка зависает при назначении результата команды переменной

Моя первоначальная проблема состояла в том, чтобы убить процесс и его детей, когда истекло время ожидания. И я нашел GNU timeout неплохой выбор.

Однако в этом тестовом сценарии все становится странным:

Предположим, что у нас есть test1.sh как это:

#!/bin/sh
# test1.sh
output=`timeout 2 ./run.sh`
echo $output

а также run.sh как это:

#!/bin/sh
# run.sh
sleep 8s&

Интуитивно мы должны ожидать test1.sh выходит мгновенно, так как init возьму на себя ответственность за это глупо sleep процесс и run.sh затем выйдет.

Тем не мение:

sh-4.2$ time ./test1.sh

real    0m8.022s
user    0m0.013s
sys     0m0.003s

И если я создам это test2.sh:

#!/bin/sh
# test2.sh
timeout 2 ./run.sh
sh-4.2$ time ./test2.sh

real    0m0.014s
user    0m0.003s
sys     0m0.007s

Итак, очевидно, что во время замены команды мы столкнулись с чем-то неправильным, но почему?

1 ответ

Решение

Это может быть так, как у вас в сценарии оболочки -

`timeout 2 ./run.sh` 

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

Попробуйте это, чтобы увидеть аналогичный результат....

echo "hello `sleep 2 &`"

Еще один интересный сценарий -

$ cat y.sh
echo "hi"
sleep 2 &
echo "bye"
sleep 2 &

Запустить с помощью

echo "hello `sh y.sh`"

$time sh y.sh
hi
bye

real    0m0.006s
user    0m0.000s
sys     0m0.004s

$time echo "hello `sh y.sh`"
hello hi
bye

real    0m2.008s
user    0m0.004s
sys     0m0.000s

Эта страница объясняет больше о связи между фоновым процессом и дескриптором файла. Основном:

Фоновые (лучше: разветвленные) процессы наследуют файловые дескрипторы, и Запуск команды в обратных галочках означает собирать свой стандартный вывод, пока его стандартный вывод не будет закрыт.

Другие вопросы по тегам