ตามคู่มือ Bashตัวแปรสภาพแวดล้อมBASH_COMMAND
มี
คำสั่งที่กำลังดำเนินการหรือกำลังจะถูกดำเนินการยกเว้นว่าเชลล์กำลังดำเนินการคำสั่งเป็นผลมาจากกับดักซึ่งในกรณีนี้มันเป็นคำสั่งที่ดำเนินการในเวลาที่กับดัก
การเอามุมของมุมกับดักนั้นไว้ถ้าฉันเข้าใจถูกต้องนี่หมายความว่าเมื่อฉันรันคำสั่งตัวแปรจะBASH_COMMAND
มีคำสั่งนั้นอยู่ ไม่ชัดเจนว่าตัวแปรนั้นไม่มีการตั้งค่าหลังจากการดำเนินการคำสั่ง (กล่าวคือเป็นเพียง avaialble ขณะที่คำสั่งกำลังทำงาน แต่ไม่ใช่หลังจาก) แม้ว่าจะมีใครโต้แย้งว่าเป็นเพราะ "คำสั่งที่กำลังดำเนินการอยู่หรือกำลังจะถูกดำเนินการ" มันไม่ใช่คำสั่งที่เพิ่งถูกเรียกใช้งาน
แต่ให้ตรวจสอบ:
$ set | grep BASH_COMMAND=
$
ว่างเปล่า ฉันคาดว่าจะเห็นBASH_COMMAND='set | grep BASH_COMMAND='
หรืออาจจะเป็นเพียงBASH_COMMAND='set'
แต่ว่างเปล่าทำให้ฉันประหลาดใจ
ลองทำอย่างอื่น:
$ echo $BASH_COMMAND
echo $BASH_COMMAND
$
ดีที่ทำให้รู้สึก ผมรันคำสั่งecho $BASH_COMMAND
และตัวแปรมีสตริงBASH_COMMAND
echo $BASH_COMMAND
ทำไมเวลานี้ถึงใช้งานได้ แต่ไม่ใช่ก่อนหน้านี้
ลองทำset
อีกครั้ง:
$ set | grep BASH_COMMAND=
BASH_COMMAND='echo $BASH_COMMAND'
$
ดังนั้นรอ มันถูกตั้งค่าเมื่อฉันเรียกใช้งานecho
คำสั่งนั้นและจะไม่ถูกยกเลิกหลังจากนั้น แต่เมื่อฉันดำเนินการset
อีกครั้งBASH_COMMAND
ไม่ได้ตั้งค่าset
คำสั่ง ไม่ว่าฉันจะรันset
คำสั่งที่นี่บ่อยแค่ไหนผลลัพธ์ก็ยังคงเหมือนเดิม ดังนั้นตัวแปรถูกตั้งค่าเมื่อดำเนินการecho
แต่ไม่เมื่อดำเนินการset
? มาดูกัน.
$ echo Hello AskUbuntu
Hello AskUbuntu
$ set | grep BASH_COMMAND=
BASH_COMMAND='echo $BASH_COMMAND'
$
อะไร? ดังนั้นตัวแปรถูกตั้งเมื่อผมดำเนินการecho $BASH_COMMAND
แต่ไม่ได้เมื่อผมดำเนินการecho Hello AskUbuntu
? ตอนนี้ความแตกต่างอยู่ที่ไหน ตัวแปรตั้งค่าเฉพาะเมื่อคำสั่งปัจจุบันบังคับให้เชลล์ประเมินตัวแปรหรือไม่? ลองทำสิ่งที่แตกต่าง อาจมีคำสั่งจากภายนอกในเวลานี้ไม่ใช่ bash builtin สำหรับการเปลี่ยนแปลง
$ /bin/echo $BASH_COMMAND
/bin/echo $BASH_COMMAND
$ set | grep BASH_COMMAND=
BASH_COMMAND='/bin/echo $BASH_COMMAND'
$
อืมโอเค ... อีกครั้งตัวแปรถูกตั้งค่า ดังนั้นการเดาปัจจุบันของฉันถูกต้องหรือไม่ มีการตั้งค่าตัวแปรเฉพาะเมื่อต้องมีการประเมินหรือไม่? ทำไม? ทำไม? ด้วยเหตุผลด้านประสิทธิภาพ? ลองทำอีกครั้ง เราจะพยายาม grep สำหรับ$BASH_COMMAND
ในไฟล์และ$BASH_COMMAND
จากนั้นควรมีgrep
คำสั่งgrep
ควร grep สำหรับgrep
คำสั่งนั้น(เช่นสำหรับตัวเอง) ดังนั้นให้สร้างไฟล์ที่เหมาะสม:
$ echo -e "1 foo\n2 grep\n3 bar\n4 grep \$BASH_COMMAND tmp" > tmp
$ grep $BASH_COMMAND tmp
grep: $BASH_COMMAND: No such file or directory
tmp:2 grep <-- here, the word "grep" is RED
tmp:4 grep $BASH_COMMAND tmp <-- here, the word "grep" is RED
tmp:2 grep <-- here, the word "grep" is RED
tmp:4 grep $BASH_COMMAND tmp <-- here, the word "grep" is RED
$ set | grep BASH_COMMAND=
BASH_COMMAND='grep --color=auto $BASH_COMMAND tmp'
$
ตกลงน่าสนใจ คำสั่งgrep $BASH_COMMAND tmp
ได้ขยายไปgrep grep $BASH_COMMAND tmp tmp
(ตัวแปรที่ได้รับการขยายตัวเพียงว่าครั้งหนึ่งของหลักสูตร) และดังนั้นผมจึง grepped สำหรับgrep
ครั้งหนึ่งในไฟล์ที่ไม่อยู่และเป็นครั้งที่สองในแฟ้ม$BASH_COMMAND
tmp
Q1:สมมติฐานปัจจุบันของฉันถูกต้องที่:
BASH_COMMAND
ถูกตั้งค่าเมื่อคำสั่งพยายามประเมินค่าจริงเท่านั้น และ- มันไม่ได้ล้างคำสั่งหลังจากการดำเนินการของคำสั่งแม้ว่าคำอธิบายอาจทำให้เราเชื่อเช่นนั้น?
Q2:ถ้าใช่ทำไม ประสิทธิภาพ? หากไม่สามารถอธิบายพฤติกรรมในลำดับคำสั่งด้านบนได้อย่างไร
คำถามที่ 3:ท้ายที่สุดมีสถานการณ์ใดบ้างที่ตัวแปรนี้สามารถใช้อย่างมีความหมายได้จริงหรือไม่? จริง ๆ แล้วฉันพยายามใช้ภายใน$PROMPT_COMMAND
เพื่อวิเคราะห์คำสั่งที่ถูกดำเนินการ (และทำบางสิ่งขึ้นอยู่กับว่า) แต่ฉันทำไม่ได้เพราะทันทีที่ภายในฉัน$PROMPT_COMMAND
ฉันเรียกใช้คำสั่งเพื่อดูตัวแปร$BASH_COMMAND
ตัวแปร รับชุดเป็นคำสั่งที่ แม้เมื่อฉันทำMYVARIABLE=$BASH_COMMAND
ถูกต้องที่จุดเริ่มต้นของฉัน$PROMPT_COMMAND
แล้วMYVARIABLE
มีสตริงMYVARIABLE=$BASH_COMMAND
เพราะการกำหนดเป็นคำสั่งด้วย (คำถามนี้ไม่ได้เกี่ยวกับวิธีที่ฉันจะได้รับคำสั่งปัจจุบันภายในการ$PROMPT_COMMAND
ดำเนินการมีหลายวิธีที่ฉันรู้)
มันค่อนข้างคล้ายกับหลักการความไม่แน่นอนของไฮเซนเบิร์ก เพียงแค่สังเกตตัวแปรฉันก็เปลี่ยนมัน
bash
über-gurus อยู่ที่นั่นจริง