Як баш скрипт може виявити, якщо він працює у фоновому режимі?


28

Чи є спосіб, коли баш сценарій дізнається, чи працює він на передньому плані чи на задньому плані, і він може вести себе трохи по-різному у кожному випадку?


Зауважте, що процес може переміщуватися з переднього плану на другий план і навпаки через контроль роботи.
Бармар

1
Можливо, вам також буде цікаво дізнатися, чи працює сценарій з інтерактивної оболонки
GnP

Відповіді:


30

Цитування 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

Напевно, все, що викликається в $ (...), саме працює у фоновому режимі ....? Я думаю, що процесна група є важливою справою, але не можу заперечити, що вона працює.
Ед Рендалл

2

Подивіться на файл /etc/bash.bashrc ".

Рядок, що містить "$ PS1". Потім зробіть "man bash" і шукайте маркер PS1.

[ -z "$PS1" ] && return

закриває сценарій, який не є інтерактивним.


1

Усі попередні рішення включають нерестові процеси тощо. Дуже, дуже некрасиво, оскільки .bashrcназивається кожен раз, коли запускається оболонка bash, отже, ці рішення закінчуються запуском 1000 процесів.

Значно чистіший запитує сам bash: bash має заздалегідь задану змінну, $-яка має "i", якщо її працює в інтерактивній оболонці. Наприклад, помістити це у свій .bashrc набагато чистіше і набагато дешевше, а головне, завжди буде працювати!

case "$-" in 

    *i*) # interactive shell

    ;;
esac

ЧОМУ ВИ ЖЕЛИТИ? Це виглядає дуже, дуже потворно ...
Pierre.Vriens

Просте, правильне рішення.
Ед Рендалл

0

Хоча ви могли подумати, що перевірка того, чи оболонка запускається в інтерактивному режимі, дасть такий же результат, на практиці це не так. Концепція схожа, але насправді відрізняється. Ви можете запустити інтерактивний скрипт у фоновому вводі подачі завдяки очікуваним . Крім того, ви можете запустити свій скрипт з 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).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.