สคริปต์ทุบตีตรวจพบได้อย่างไรว่าสคริปต์นั้นทำงานในพื้นหลัง


28

มีวิธีที่สคริปต์ทุบตีจะรู้ว่ามันทำงานในเบื้องหน้าหรือพื้นหลังและเพื่อให้สามารถทำงานแตกต่างกันเล็กน้อยในแต่ละกรณี?


โปรดทราบว่ากระบวนการสามารถย้ายจากเบื้องหน้าไปยังพื้นหลังและในทางกลับกันเนื่องจากการควบคุมงาน
Barmar

คำตอบ:


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

มีอะไรที่เรียกใช้ภายใน $ (... ) จริงหรือไม่ว่าทำงานในพื้นหลัง .... ฉันเดาว่ากลุ่มกระบวนการเป็นสิ่งสำคัญ แต่ก็ปฏิเสธไม่ได้ว่ามันใช้งานได้
Ed Randall

2

ดูไฟล์ /etc/bash.bashrc "

บรรทัดที่มี "$ PS1" จากนั้นทำ "man bash" แล้วมองหาโทเค็น PS1

[ -z "$PS1" ] && return

ออกจากสคริปต์ที่ไม่สามารถโต้ตอบได้


1

โซลูชันก่อนหน้าทั้งหมดเกี่ยวข้องกับกระบวนการวางไข่ ฯลฯ น่าเกลียดมากตั้งแต่นั้นเป็นต้นมา .bashrcถูกเรียกทุกครั้งที่มีการเปิดใช้งานเชลล์ bash shell ดังนั้นโซลูชันเหล่านั้นจึงสิ้นสุดการเปิดตัวกระบวนการ 1000 รายการ

ตัวทำความสะอาดส่วนใหญ่ถามถึง bash: bash มีตัวแปรที่กำหนดไว้ล่วงหน้า$-ซึ่งมี "i" ถ้ามันทำงานในเชลล์แบบโต้ตอบ ตัวอย่างเช่นการใส่สิ่งนี้ลงใน. bashrc ของคุณนั้นสะอาดกว่าและราคาถูกกว่ามากและที่สำคัญที่สุดจะใช้ได้เสมอ!

case "$-" in 

    *i*) # interactive shell

    ;;
esac

ทำไมคุณถึงร้องตะโกน นั่นดูน่าเกลียดมาก ...
Pierre.Vriens

วิธีแก้ปัญหาที่ง่ายและถูกต้อง
Ed Randall

0

ในขณะที่คุณอาจคิดว่าการตรวจสอบว่าเชลล์ทำงานในโหมดการโต้ตอบจะให้ผลเหมือนกัน แต่ในทางปฏิบัตินี่ไม่ใช่ แนวคิดมีลักษณะคล้ายกัน แต่แตกต่างกันจริง คุณสามารถเรียกใช้สคริปต์แบบโต้ตอบในอินพุตการป้อนพื้นหลังได้ด้วยหวังว่าจะได้ นอกจากนี้คุณสามารถเปิดใช้สคริปต์ของคุณด้วยการทุบตีกับ-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 - man 5 proc)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.