#bash #shell
Вопрос:
Обычно, когда INT
оказывается в ловушке, select
не дают shell
немедленно отреагировать Ctr-C
сигналом. Когда этот сценарий запускается , а затем нажимается пользователем Ctr-C
, ничего не происходит. Пользователь должен нажать RETURN
, что-то напечатать, а затем RETURN
снова нажать, чтобы увидеть trap
, что работает.
trap 'echo INT signal TRAPPED; exit 0' INT
a=(A B C)
function choose_item ()
{
PS3="Choose an item in the preceding list: "
select n in ${a[*]}; do
echo "You choose $n"
return 0
done
}
choose_item
#$(choose_item)
Однако, когда мы:
- прокомментируйте строку
choose_item
- раскомментируйте строку
$(choose_item)
- запустите сценарий
- нажимает Ctr-C,
сценарий немедленно завершается и показывает, что ловушка работает. Так какова же роль command substitution
?
Ответ №1:
С $(choose_item)
вами начнется другой процесс. Командная строка заменяется выводом этого процесса.
my_echo() {
echo "echo again"
}
my_echo
$(my_echo)
возвращает
эхо снова
и снова
Второй вызов вернул команду echo again
. Вы можете увидеть нормальный вывод с echo "$(my_echo)"
помощью .
Это системный вызов select
, который не любит, когда его убивают, см. https://unix.stackexchange.com/q/513466/57293. С choose_item
вами пошлите сигнал на select
-вызов, и это будет отложено.
При использовании вы $(choose_item)
запускаете не select
подпроцесс , а подпроцесс, вызывающий вашу функцию. В этом случае вы убьете подпроцесс, который работает «без проблем».
Когда вам понравится поведение «убить без промедления $(choose_item)
«, измените свою функцию:
choose_item () {
(
PS3="Choose an item in the preceding list: "
select n in ${a[*]}; do
echo "You choose $n"
return 0
done
)
}
Теперь select
это вызывается в подпроцессе, и вы можете choose_item
это сделать .