Оболочка зависает при назначении результата команды переменной
Моя первоначальная проблема состояла в том, чтобы убить процесс и его детей, когда истекло время ожидания. И я нашел 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
Эта страница объясняет больше о связи между фоновым процессом и дескриптором файла. Основном:
Фоновые (лучше: разветвленные) процессы наследуют файловые дескрипторы, и Запуск команды в обратных галочках означает собирать свой стандартный вывод, пока его стандартный вывод не будет закрыт.