`_` ตัวแปรสภาพแวดล้อมของ bash shell เมื่อใด


10

Bash Manual พูดว่า (manpage, การเน้นของฉัน):

เมื่อ Bash เรียกใช้คำสั่งภายนอกตัวแปร$_จะถูกตั้งค่าเป็นชื่อพา ธ เต็มของคำสั่งและส่งไปยังคำสั่งนั้นในสภาพแวดล้อมของมัน

และ ( พารามิเตอร์พิเศษ ):

_

( $_ขีดล่าง.) ที่การเริ่มต้นเชลล์ตั้งค่าชื่อพา ธ สัมบูรณ์ที่ใช้เพื่อเรียกใช้เชลล์หรือสคริปต์เชลล์ที่จะดำเนินการตามที่ส่งผ่านในสภาพแวดล้อมหรือรายการอาร์กิวเมนต์ ต่อจากนั้นขยายไปยังอาร์กิวเมนต์สุดท้ายไปยังคำสั่งก่อนหน้าหลังจากการขยาย นอกจากนี้ยังตั้งเป็นชื่อพา ธ แบบเต็มที่ใช้เพื่อเรียกใช้คำสั่งแต่ละคำสั่งที่ดำเนินการและวางไว้ในสภาพแวดล้อมที่ส่งออกไปยังคำสั่งนั้น เมื่อตรวจสอบเมลพารามิเตอร์นี้เก็บชื่อของไฟล์เมล

  1. ใน bash shell ฉันรัน:

    $ bash
    $ export | grep '_=' 
    

    ตามคู่มือ_ควรเป็นตัวแปรสภาพแวดล้อมของ bash shell ใหม่ exportควรจะส่งออกทั้งหมดตัวแปรสภาพแวดล้อมของเปลือกทุบตีใหม่ _แต่มันไม่ออก ดังนั้นฉันสงสัยว่า_ตัวแปรสภาพแวดล้อมของ bash shell ใหม่เป็นอย่างไร

  2. ที่จริงแล้วใน bash shell ใด ๆ สิ่งเดียวกันจะเกิดขึ้น

    $ export | grep '_='

    ไม่ส่งออกอะไร ดังนั้นฉันสงสัยว่า_ตัวแปรสภาพแวดล้อมของ bash shell นั้นเคยมีหรือไม่?

  3. สำหรับการเปรียบเทียบ:

    $ dash
    $ export  | grep '_='        
    export _='/bin/dash'
    

โพสต์ของฉันคือแรงบันดาลใจจากความคิดเห็นของไมค์และตอบกลับของสเตฟาน


1
มันเป็นตัวแปรเชลล์และมันถูกส่งผ่านไปยังสภาพแวดล้อมของคำสั่ง มันไม่จำเป็นต้องส่งออกไปยังสภาพแวดล้อม ของเชลล์ exportเป็น builtin แต่ถ้าคุณใช้printenv _มันจะแสดงให้คุณเห็นว่ามันถูกเรียกใช้อย่างไร: /usr/bin/printenvในระบบนี้
Toby Speight

โปรดทราบว่าbash -c export | grep _=(จาก Bash) จะแสดงว่าเชลล์พาเรนต์เรียกใช้bashคำสั่งแม้ว่าจะ$_ไม่ได้ตั้งค่าในพาเรนต์
Toby Speight

ดูเพิ่มเติมunix.stackexchange.com/questions/293302
JdeBP

คำตอบ:


13

ใช่_เป็นตัวแปรสภาพแวดล้อมของ Bash shell ใหม่ คุณสามารถดูได้โดยการทำงาน

tr '\0' '\n' < /proc/$$/environ | grep _=

ภายในเชลล์: ที่แสดงเนื้อหาของสภาพแวดล้อมเริ่มต้นของเชลล์ คุณจะไม่เห็นมันในเชลล์แรกเพราะไม่มีเชลล์ก่อนหน้านี้ที่จะตั้งมันก่อนที่มันจะเริ่ม

การขยาย$_ภายใน Bash หมายถึง_พารามิเตอร์พิเศษซึ่งขยายไปยังอาร์กิวเมนต์สุดท้ายของคำสั่งก่อนหน้า (ภายในทุบตีจัดการสิ่งนี้โดยใช้_ตัวแปรเชลล์ซึ่งมีการปรับปรุงทุกครั้งที่มีการแยกวิเคราะห์คำสั่ง แต่เป็นรายละเอียดการใช้งานจริง ๆมันคือ "ไม่ได้ส่งออก" ทุกครั้งที่มีการแยกวิเคราะห์คำสั่ง ) exportจะไม่แสดง_เพราะไม่ ตัวแปรที่ทำเครื่องหมายว่าส่งออก setแต่คุณสามารถเห็นมันในการส่งออกของ

ในตัวอย่างแรกใหม่ทุบตีแยกวิเคราะห์เปลือกและดำเนินการคำสั่งในแฟ้มเริ่มต้นของดังนั้นเมื่อทำงานexplore | grep '-=', _ได้รับแล้วเขียนทับและทำเครื่องหมายว่าไม่ถูกส่งออก

ในdashตัวอย่างเช่นมันดูเหมือนจะไม่เรียกใช้ไฟล์ที่เริ่มต้นขึ้นใด ๆ dashเพื่อให้คุณเห็นตัวแปรตัวแปรสภาพแวดล้อมที่ถูกกำหนดโดยการทุบตีก่อนที่จะใช้


ขอบคุณ ใน bash shell ใหม่ทำไมไม่export | grep '_='ส่งออกอะไรเลย ในเชลล์ทุบตีดั้งเดิมทำไมไม่มีtr '\0' '\n' < /proc/$$/environ | grep _=อะไรส่งออก
ทิม


9

exportโดยไม่ขัดแย้งรายการส่งออกตัวแปร _ไม่ได้เป็นตัวแปร แต่จะปรากฏเป็นพารามิเตอร์พิเศษ

ค่อนข้างสับสน_ก็จะเป็นชื่อที่ถูกต้องสำหรับตัวแปรซึ่งแตกต่างจากชื่อของพารามิเตอร์พิเศษอื่น ๆ Bash 4.4 เป็นอย่างน้อยอนุญาตให้ทำการมอบหมายได้โดยไม่มีการร้องเรียน มันไม่มีประโยชน์เพราะเอฟเฟกต์พิเศษจะแทนที่ค่าทันที


2
ขอให้สนุกลองใช้_เป็นตัวแปร ;-) มันเขียนได้อย่างมีประสิทธิภาพและค่าจะหายไปทันที
Stephen Kitt

1
นอกจากนี้ภายในทุบตีไม่รักษาเป็นตัวแปรซึ่งเป็นเหตุผลที่ปรากฏในการส่งออกของ_ setอย่างไรก็ตามมันไม่สามารถทำเครื่องหมายว่าส่งออกได้เท่าที่ฉันจะทราบได้
Stephen Kitt

2
@StephenKitt แต่ Bash 4.4 อนุญาตให้ทำเครื่องหมายเป็นอ่านอย่างเดียว หรือจำนวนเต็ม ด้วยผลลัพธ์ที่ค่อนข้างเฮฮา
ilkkachu

1
ฮ่า, หาดี, มันค่อนข้างสนุก!
Stephen Kitt

5

ทุกตัวแปรเปลือกไม่ es declare -pทำเครื่องหมายว่าการส่งออกในขณะที่คุณสามารถมองเห็นในการส่งออกของ

มันไม่สมเหตุสมผลที่bashจะทำเครื่องหมาย$_ว่าเอ็กซ์พอร์ตเนื่องจากมันจะเพิ่มตัวแปรนี้เข้ากับสภาพแวดล้อมของกระบวนการลูกโดยอัตโนมัติแต่มีค่าต่างจากที่มีในเชลล์ (ในขณะนั้น)

การแสดงว่าการส่งออกจะสร้างความสับสนให้ผู้ใช้เกี่ยวกับสิ่งที่จะเกิดขึ้นกับสภาพแวดล้อมของคำสั่งภายนอก

"ตัวแปรรันไทม์" BASH*ทั้งหมดจะไม่ถูกส่งออก

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