Чи є спосіб, коли баш сценарій дізнається, чи працює він на передньому плані чи на задньому плані, і він може вести себе трохи по-різному у кожному випадку?
Чи є спосіб, коли баш сценарій дізнається, чи працює він на передньому плані чи на задньому плані, і він може вести себе трохи по-різному у кожному випадку?
Відповіді:
Цитування 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
Подивіться на файл /etc/bash.bashrc ".
Рядок, що містить "$ PS1". Потім зробіть "man bash" і шукайте маркер PS1.
[ -z "$PS1" ] && return
закриває сценарій, який не є інтерактивним.
Усі попередні рішення включають нерестові процеси тощо. Дуже, дуже некрасиво, оскільки .bashrc
називається кожен раз, коли запускається оболонка bash, отже, ці рішення закінчуються запуском 1000 процесів.
Значно чистіший запитує сам bash: bash має заздалегідь задану змінну, $-
яка має "i", якщо її працює в інтерактивній оболонці. Наприклад, помістити це у свій .bashrc набагато чистіше і набагато дешевше, а головне, завжди буде працювати!
case "$-" in
*i*) # interactive shell
;;
esac
Хоча ви могли подумати, що перевірка того, чи оболонка запускається в інтерактивному режимі, дасть такий же результат, на практиці це не так. Концепція схожа, але насправді відрізняється. Ви можете запустити інтерактивний скрипт у фоновому вводі подачі завдяки очікуваним . Крім того, ви можете запустити свій скрипт з bash з -l
аргументом. Таким чином, ми не можемо покластися на інтерактивність bash, щоб перевірити, чи працює наш сценарій у фоновому режимі чи на передньому плані.
Відповідь від devnull таким чином правильна . Щоб визначити, чи працює процес на передньому плані, утиліта ps перевіряє, чи група процесів (pgrp) збігається з ідентифікатором групи процесів, пов'язаним з контрольним терміналом сеансу (tpgid), і додає +
знак у висновку відповідно до процесу держава.
Знаючи це, ми точно можемо мати чисту баш-версію тесту:
#!/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 5 proc
).