когда вы устанавливаете chrome, skype или any.deb и сталкиваетесь с этой проблемой, просто запустите «apt install -f»
sudo apt install -f
Это решит проблему или удалит поврежденный пакет, если нет шансов.
wait
не перехватывает сигнал. Оболочка его не пропускает. Сигнал не перехватывается и не передается. Подоболочки, выполняющие ваши три «фоновые» команды, либо получают сигнал напрямую , либо нет.
Вы можете протестировать следующий скрипт:
#!/usr/bin/env bash
printf 'My PID is %s.\n' "$$"
sleep 15 && echo '123' &
sleep 15 && echo '456' &
sleep 15 && echo '999' &
wait < <(jobs -p)
Сценарий ведет себя так же, как ваш сценарий с wait
. Я имею в виду, что вы можете завершить и три «фоновых» задания с помощью Ctrl + C .
Запустите еще раз и не нажимайте Ctrl + C . Скрипт сообщит вам свой собственный PID ($$
). Теперь, если вы отправите SIGINT
с другого терминала (kill -s INT <pid_here>
), он завершит сценарий, но , а не три задания.
Но если отправить SIGINT
всей группе процессов (kill -s INT -- -<pid_here>
), то скрипт и задания получат его. То же самое происходит, когда вы нажимаете Ctrl + C и ваш терминал настроен на отправку сигнала прерывания при нажатии клавиши (, как это обычно бывает, stty -a
включает intr = ^C
), Вся группа получает сигнал.
Речь идет о группе процессов переднего плана. Одной из задач, которую выполняет оболочка, является информирование терминала о том, какая группа процессов находится на переднем плане.
A terminal may have a foreground process group associated with it. This foreground process group plays a special role in handling signal-generating input characters […].
A command interpreter process supporting job control can allocate the terminal to different jobs, or process groups, by placing related processes in a single process group and associating this process group with the terminal. […]
(источник)
Вот что действительно происходит в вашем случае:
bash
интерпретация сценария. Неинтерактивный -Bash запускается с отключенным по умолчанию управлением заданиями. Команды, выполняемые ею, не станут лидерами своих собственных групп процессов (, если только сама команда не изменит свою группу процессов; возможно, но в вашем случае этого не происходит ). Три подоболочки и три процесса sleep
принадлежат к той же группе процессов, что и запущенный скрипт. Это объясняет поведение, которое вы наблюдали:
Если скрипт запущен, когда вы нажимаете Ctrl + C , тогда он и практически все его потомки получат SIGINT
. Неважно, ждет ли скрипт из-за wait
или из-за какой-то команды, выполненной без &
. Важно то, что его группа процессов по-прежнему является группой процессов переднего плана, и (великие )дети принадлежат к группе.
Если скрипт больше не запускается, когда вы нажимаете Ctrl + C , то его потомки (, если таковые имеются, )не получат SIGINT
, потому что они не принадлежат в текущую группу процессов переднего плана.
Обратите внимание, что вы можете изменить это поведение, отключив или включив управление заданиями.
Если вы отключите управление заданиями(set +m
)в интерактивной оболочке и запустите сценарий, оболочка запустит сценарий, не сделав его лидером группы процессов. В скрипте нет управления заданиями. Сценарий и в основном все его дочерние элементы будут принадлежать группе процессов интерактивной оболочки. Эта группа будет группой процессов переднего плана все время. После Ctrl + C все процессы (, включая интерактивную оболочку ), получат SIGINT
, независимо от того, запущен скрипт или нет.
Если вы включите управление заданиями(set -m
)в самом скрипте, три подоболочки будут помещены в соответствующие группы процессов. В подобных обстоятельствах команда без &
стала бы лидером группы процессов, и терминал был бы проинформирован о новой группе процессов переднего плана. Но ваши команды с &
, они станут лидерами, но группа процессов переднего плана не изменится. После Ctrl + C они не получат SIGINT
, независимо от того, запущен скрипт или нет, и независимо от того, включено ли в интерактивной оболочке управление заданиями.
Разделитель или терминатор &
не означает «запускать в фоновом режиме». Это означает только «запускать асинхронно». Команды, выполняемые с &
, могут оставаться в группе процессов переднего плана (, например. если управление заданиями отключено ). Команды, запущенные без &
, могут покинуть группу процессов переднего плана.
Вас может удивить тот факт, что интерактивная оболочка помещает себя в фоновый режим при выполнении команд. Это действительно происходит. Запустите эти команды в интерактивном Bash:
set -m
trap 'echo "Signal received."' INT
sleep 999
Ctrl + C
Вы увидите, что sleep
был прерван, но оболочка не получила сигнал. Это связано с тем, что оболочка поместила sleep
в отдельную группу процессов, которая была группой процессов переднего плана в момент нажатия клавиши. Оболочка не находилась в группе процессов (, а затем )переднего плана, это означает, что она находилась в фоновом режиме.
Теперь измените set -m
на set +m
и запустите снова:
set +m
trap 'echo "Signal received."' INT
sleep 999
Ctrl + C
При отключенном управлении заданиями sleep
будет выполняться в группе процессов оболочки. Группа все время будет группой процессов переднего плана. Вы увидите сообщение от trap
.