Bagaimana skrip bash dapat mendeteksi jika skrip berjalan di latar belakang?


28

Apakah ada cara bagi skrip bash untuk mengetahui apakah skrip tersebut berjalan di latar depan atau di latar belakang, dan sehingga dapat berperilaku sedikit berbeda di setiap kasus?


Perhatikan bahwa suatu proses dapat bergerak dari latar depan ke latar belakang dan sebaliknya karena kontrol pekerjaan.
Barmar

1
Anda juga mungkin tertarik untuk mengetahui apakah skrip berjalan dari shell interaktif
GnP

Jawaban:


30

Mengutip man ps:

KODE NEGARA PROSES

   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

Jadi Anda bisa melakukan pemeriksaan sederhana:

case $(ps -o stat= -p $$) in
  *+*) echo "Running in foreground" ;;
  *) echo "Running in background" ;;
esac

Tentunya sesuatu yang dipanggil dalam $ (...) itu sendiri berjalan di latar belakang ....? Saya kira kelompok proses adalah hal yang penting, tidak dapat disangkal bahwa itu berfungsi.
Ed Randall

2

Lihatlah file /etc/bash.bashrc ".

Baris yang memiliki "$ PS1". Kemudian lakukan "bash pria" dan cari token PS1.

[ -z "$PS1" ] && return

keluar dari skrip yang tidak interaktif.


1

Semua solusi sebelumnya melibatkan proses pemijahan, dll. Sangat, sangat jelek, karena .bashrcdisebut setiap kali bash shell diluncurkan, maka solusi tersebut akhirnya meluncurkan 1000's proses.

Jauh lebih bersih meminta bash sendiri: bash memiliki variabel $-yang sudah ditentukan yang memiliki "i" jika berjalan dalam shell interaktif. Misalnya, memasukkan ini ke dalam .bashrc Anda jauh lebih bersih dan jauh lebih murah dan, yang paling penting, akan selalu berfungsi!

case "$-" in 

    *i*) # interactive shell

    ;;
esac

KENAPA KAMU BERTERIAK? Itu terlihat sangat, sangat jelek ...
Pierre.Vriens

Sederhana, solusi yang benar.
Ed Randall

0

Meskipun Anda dapat berpikir bahwa memeriksa apakah shell dijalankan dalam mode interaktif akan memberikan hasil yang sama, dalam praktiknya, ini tidak. Konsepnya terlihat mirip tetapi sebenarnya berbeda. Anda dapat menjalankan skrip interaktif di input umpan latar belakang terima kasih untuk yang diharapkan . Juga, Anda bisa meluncurkan skrip Anda dengan bash dengan -largumen. Karena itu, kami tidak dapat mengandalkan interaktivitas bash untuk memeriksa apakah skrip kami dijalankan di latar belakang atau di latar depan.

Jawaban dari devnull dengan demikian benar . Untuk menentukan apakah proses berjalan di latar depan, utilitas ps memeriksa apakah grup proses (pgrp) sama dengan id grup proses yang terkait dengan terminal pengendali sesi (tpgid) dan menambahkan +tanda pada output sesuai dengan proses negara.

Mengetahui hal itu, kami pasti dapat memiliki versi murni dari tes:

#!/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

Dalam kode di atas, kami mengeluarkan hasilnya dalam file teks karena stdouttidak terhubung ketika proses dijalankan di latar belakang.

Harap perhatikan elemen ke-4 dan ke-8 dari tabel masing-masing sesuai dengan pgrpdan tpgid( lihat bagian / proc / [pid] / stat dari halaman manual - man 5 proc).

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.