Есть ли способ для bash-скрипта узнать, работает ли он на переднем плане или в фоне, и поэтому он может вести себя немного по-разному в каждом случае?
Есть ли способ для bash-скрипта узнать, работает ли он на переднем плане или в фоне, и поэтому он может вести себя немного по-разному в каждом случае?
Ответы:
Цитирование man ps
:
Here are the different values that the s, stat and state output
specifiers (header "STAT" or "S") will display to describe the state of
a process.
...
+ is in the foreground process group
Таким образом, вы можете выполнить простую проверку:
case $(ps -o stat= -p $$) in
*+*) echo "Running in foreground" ;;
*) echo "Running in background" ;;
esac
Все предыдущие решения включают процессы порождения и т. Д. Очень, очень уродливо, так как .bashrc
вызывается каждый раз, когда запускается оболочка bash, следовательно, эти решения заканчивают запуск тысяч процессов.
Большая часть спрашивает сам bash: bash имеет предопределенную переменную, $-
которая имеет «i», если она работает в интерактивной оболочке. Например, поместить это в ваш .bashrc намного чище, намного дешевле и, что самое важное, всегда будет работать!
case "$-" in
*i*) # interactive shell
;;
esac
Хотя вы можете подумать, что проверка запуска оболочки в интерактивном режиме даст тот же результат, на практике это не так. Концепция выглядит похожей, но на самом деле другая. Вы можете запустить интерактивный скрипт в фоновом режиме ввода, благодаря ожидаемому . Также вы можете запустить ваш скрипт с bash с -l
аргументом. Таким образом, мы не можем полагаться на интерактивность bash, чтобы проверить, выполняется ли наш скрипт в фоновом режиме или на переднем плане.
Ответ от Devnull, таким образом, правильный . Чтобы определить, выполняется ли процесс на переднем плане, утилита ps проверяет, совпадает ли группа процессов (pgrp) с идентификатором группы процессов, связанным с управляющим терминалом сеанса (tpgid), и добавляет +
знак в выходной файл в соответствии с процессом. штат.
Зная это, мы можем определенно иметь чистую версию теста bash:
#!/usr/bin/env bash
IFS=$' '
retval=($(</proc/$$/stat))
IFS=$' \t\n'
if [[ "${retval[3]}" == "${retval[7]}" ]]; then
echo "Background" > ./result.txt
else
echo "Foreground" > ./result.txt
fi
exit
В приведенном выше коде мы выводим результат в текстовом файле, поскольку stdout
он не подключен, когда процесс выполняется в фоновом режиме.
Обратите внимание, что 4-й и 8-й элементы таблицы соответственно соответствуют pgrp
и tpgid
( см. Раздел / proc / [pid] / stat на странице man - man 5 proc
).