ฉันจะรู้ได้อย่างไรว่าสคริปต์ bash ที่กำลังเรียกใช้อยู่ในปัจจุบันได้รับการเรียกใช้ด้วย -x เพื่อการดีบั๊กหรือไม่


11

ฉันมีสคริปต์launch.shที่รันตัวเองเป็นผู้ใช้อื่นเพื่อสร้างไฟล์กับเจ้าของที่ถูกต้อง ฉันต้องการส่ง -x ไปยังการเรียกใช้นี้หากผ่านมาถึงสคริปต์แล้ว

if [ `whoami` == "deployuser" ]; then
  ... bunch of commands that need files to be created as deployuser
else
  echo "Respawning myself as the deployment user... #Inception"
  echo "Called with: <$BASH_ARGV>, <$BASH_EXECUTION_STRING>, <$->"
  sudo -u deployuser -H bash $0 "$@"  # How to pass -x here if it was passed to the script initially?
fi

ฉันได้อ่านหน้าทุบตีแก้จุดบกพร่อง-xแต่ดูเหมือนว่าจะไม่มีตัวเลือกที่ชัดเจนที่จะบอกว่าสคริปต์เดิมเปิดตัวด้วย

คำตอบ:


15

แฟล็กจำนวนมากที่สามารถส่งผ่านไปยังbashบนบรรทัดรับคำสั่งคือsetแฟล็ก setคือเชลล์ในตัวซึ่งสามารถสลับค่าสถานะเหล่านี้ได้ในขณะทำงาน ตัวอย่างเช่นการเรียกสคริปต์ตามbash -x foo.shปกติเหมือนกับการทำset -xสคริปต์ที่ด้านบนสุด

การรู้ว่าsetเป็นตัวเชลล์ที่รับผิดชอบเรื่องนี้ทำให้เรารู้ว่าจะต้องมองตรงไหน ตอนนี้เราสามารถทำได้help setและเราได้รับดังต่อไปนี้:

$ help set
set: set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]
...
      -x  Print commands and their arguments as they are executed.
...
    Using + rather than - causes these flags to be turned off.  The
    flags can also be used upon invocation of the shell.  The current
    set of flags may be found in $-.  The remaining n ARGs are positional
    parameters and are assigned, in order, to $1, $2, .. $n.  If no
    ARGs are given, all shell variables are printed.
...

ดังนั้นจากนี้เราจะเห็นว่า$-ควรบอกเราว่ามีการเปิดใช้งานสถานะใด

$ bash -c 'echo $-'
hBc

$ bash -x -c 'echo $-'
+ echo hxBc
hxBc

ดังนั้นโดยทั่วไปคุณต้องทำ:

if [[ "$-" = *"x"* ]]; then
  echo '`-x` is set'
else
  echo '`-x` is not set'
fi

เป็นโบนัสหากคุณต้องการคัดลอกธงทั้งหมดคุณสามารถทำได้

bash -$- /other/script.sh

1
คุณจะต้องใช้[[ $- == *x* ]]สำหรับการจับคู่รูปแบบ
เกล็นแจ็คแมน

1
case $- in *x*) ... ;; *) ... ;; esacหรือคุณอาจจะใช้มาตรฐาน มันมีประโยชน์ที่จะรู้ว่าการใช้caseสคริปต์ที่ควรพกพาได้และตอนนี้ฉันรู้แล้วฉันพบว่ามันง่ายกว่าที่จะจำได้ง่ายกว่าการจำ "ถ้าเป็น bash-specific [[, else case"
hvd

ตกลงจากนั้นความคิดเห็นทั้งหมดสามารถลบได้
l0b0

$-hBเอาท์พุท ทำอะไร-hและ-Bธง / ข้อโต้แย้งทำอย่างไร ไม่เห็นแล้วในหน้าคนทุบตี
Dan Dascalescu


2

แม้ว่าคำตอบของ @Patrick คือคำว่า "ถูกต้อง" แต่คุณสามารถส่งพารามิเตอร์หรือตัวแปรที่ส่งออกไปยังสคริปต์ลูกของคุณที่บอกสิ่งที่ต้องทำเช่นเปิดการติดตาม

นี่เป็นข้อเสียที่ (ฉันเชื่อว่า) คุณต้องส่งออกซ้ำไปยังสคริปต์แต่ละระดับที่คุณต้องการป้อน

มันมีข้อดีของความสามารถในการเลือกติดตาม (หรือส่งผลกระทบอย่างอื่น) เพียงสคริปต์ที่คุณต้องการเอาท์พุท / พฤติกรรมที่ปรับเปลี่ยนจาก - เพื่อลดเอาต์พุตภายนอก ฯลฯ การติดตามเช่นสามารถปิดใช้งานสคริปต์การโทรและ ยังคงเปิดใช้งานในสคริปต์ที่เรียกว่า มันไม่ใช่ข้อเสนอทั้งหมดหรือไม่มีอะไรเลย

ไม่ใช่ส่วนหนึ่งของคำถามของคุณ แต่เกี่ยวข้อง:

บางครั้งฉันกำหนดตัวแปรเช่น

E=""
E="echo "

หรือ

E=""
E=": "

และใช้มัน (ในหลายงบ) เช่น

"${E}" rsync ...

หรือเพียงแค่สำหรับรูปแบบที่สอง

"${E}" echo "this is a debugging message"

จากนั้นฉันเพิ่งแสดงความคิดเห็นคำจำกัดความที่สองเมื่อฉันต้องการให้คำสั่งทำงาน คุณสามารถใช้เทคนิคนี้กับพารามิเตอร์หรือตัวแปรที่ส่งออกแทน

ด้วยสิ่งใดสิ่งหนึ่งเหล่านี้คุณต้องระวังคำสั่งผสมเนื่องจากวิธีนี้รับประกันได้ว่าจะสามารถทำงานกับคำสั่งแรกในรายการผสมได้


1

คุณสามารถคว้า PID ของกระบวนการแล้วตรวจสอบตารางกระบวนการกับ ps เพื่อดูว่ามันมีข้อโต้แย้งอะไร


คุณสามารถคว้า 'PID ของกระบวนการทาง: $$
Paul Calabro

2
ฉันไม่คิดว่าเป็นความคิดที่ดีโดยทั่วไปเพราะถ้า-xตั้งไว้ในสคริปต์มันจะไม่ปรากฏในpsผลลัพธ์ และวิธีนี้ก็ไม่มีประสิทธิภาพอยู่ดี
vinc17

นั่นเป็นข้อโต้แย้งที่ยุติธรรม ที่จริงฉันไม่รู้เกี่ยวกับตัวแปร $ ดูเหมือนจะเป็นวิธีที่ดีกว่าในการแก้ปัญหานี้
Paul Calabro

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