Что делает Ctrl-Z отличающимся от
kill -STOP
, и как я могу получить поведение первого в сценарии оболочки?
CTRL-Z
обычно отправляет SIGTSTP (который может быть заблокирован), и - кроме других вещей - оболочки часто сбрасывают tty к ранее сохраненному состоянию в этих случаях. Что еще более важно, однако группа процесса терминала управления установлена на PID оболочки (и с другой стороны на PID задания, возобновленного сfg
).Назад к Вашей исходной проблеме: использование температурного зависимого частотного масштабирования как, например, Cpufreqd могло бы быть на самом деле лучшим молотком для Вашего гвоздя.
Вопрос заключается в конфликте кадров страниц при переключении контекста двух процессов, а не в адресном пространстве виртуальной памяти (адресное пространство виртуальной памяти является уникальным для каждого процесса, это не новость.). Эта ссылка переполнения стека имеет точно такой же вопрос и точный ответ. https://stackoverflow.com/questions/16581490/how-does-kernel-know-which-pages-in-the-virtual-address-space-correspond-to-a-s?lq=1
-121--162084-Во-первых, сводка некоторых фактов о сигналах и оболочке:
При нажатии клавиш CTRL + C на клавиатуре SIGINT отправляется всем процессам в группе процессов основного процесса. В этом случае это означает, что SIGINT будет получен командой cat
и процессом bash
, интерпретирующим сценарий.
При ловушке INT
команда INT
не приведет к завершению процесса, если не будет выполнен явный выход из обработчика.
При ловушке EXIT
аргумент выполняется не по определенному сигналу, а по выходу из оболочки.
Поведение trapping-int.sh
является простым, учитывая эти факты, поскольку мы знаем, что происходит следующее:
cat
получает SIGINT и его выполнение прекращается. bash
получает SIGINT и запускает обработчик сигнала, печатая «Exiting\n» на STDOUT
. bash
продолжает выполнение и печатает «Hello\n» на STDOUT
. bash
завершает работу после завершения сценария. Поведение trapping-exit.sh
также в основном простое:
cat
получает SIGINT и его выполнение прекращается. bash
получает SIGINT и, поскольку обработчик сигнала также отсутствует, выходит. Он выполняет/не выполняет команду echo
, так как он выходит сразу после получения сигнала. bash
завершается, запускается обработчик EXIT
, который печатает «Exiting\n» на STDOUT
. Оставшийся вопрос - «откуда идет новая линия?» Я считаю, что происходит то, что bash сам устанавливает обработчик SIGINT
, который печатает новую строку.
В сценарии trapping-int.sh
вы переопределяете обработчик Bash для SIGINT
, чтобы не получить дополнительную новую строку.
Вы можете просто сделать:
{ commands
....
} | logger -t my_awesome_script
Вы можете сделать это с любой оболочкой.
Если вам не нравится, как он выглядит, возможно, заставьте сценарий обернуться в функцию.
#!/bin/sh
run() if [ "$run" != "$$" ] || return
then sh -c 'run=$$ exec "$0" "$@"' "$0" "$@" |
logger -t my-awesome-script
fi
#script-body
run "$@" || do stuff
Я не думаю, что это возможно в Dash
. Насколько я могу сказать из этого MAN
страницы , он не поддерживает замену процесса.
В качестве обходного пути вы можете попробовать, что предложил Mikserv , или вы можете перенаправить все в файл, а затем после завершения сценария (предположительно это в сценарии), добавьте содержимое этого файла в Регистрация:
$ exec > ~/foo/foo.txt
$ ls
$ echo something
$ cat foo/foo.txt | sudo logger -t my-awesome-script
awk '!/BookmarkPageNumber:/ {print}; /BookmarkPageNumber:/ {print $1 " " $2-1}' old.txt > new.txt
-121--93520- Замена процесса легко моделируется с названными трубами.
mkfifo logger_input
logger -t my_awesome_script < logger_input &
exec > logger_input
echo 1
echo 2
echo 3
На самом деле, названные трубы являются одним из механизмов (другое существо / dev / fd
), с которым замена процесса может быть реализована в Bash
.