$ _ vs! $. อาร์กิวเมนต์สุดท้ายของคำสั่งก่อนหน้าและการเปลี่ยนเส้นทางผลลัพธ์


28

คำถามเกี่ยวกับตัวแปรพิเศษ เอกสารอธิบายว่า:

!!:$

กำหนดอาร์กิวเมนต์สุดท้ายของคำสั่งก่อนหน้า สิ่งนี้อาจสั้นลงถึง! $


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

จะต้องมีความแตกต่างบางอย่างที่ฉันไม่สามารถจับได้เพราะ:

$ echo "hello" > /tmp/a.txt
$ echo "!$"
echo "/tmp/a.txt"
/tmp/a.txt

$ echo "hello" > /tmp/a.txt
$ echo $_
hello

อะไรคือความแตกต่าง?


4
! $ เป็นการขยายประวัติไม่ใช่ตัวแปรพิเศษดังนั้นฉันคิดว่ารหัสทุบตีจัดการพวกมันแตกต่างกัน
Jeff Schaller

2
ฉันไม่ได้มีคำตอบที่ชัดเจนให้กับคำถามนี้ แต่: ①ภาษาเปลือกบอร์นเป็นหนึ่งในบางทีภาษาการเขียนโปรแกรมอย่างน้อยสอดคล้องภายในยังคงใช้กันอย่างแพร่หลายในปัจจุบัน ความพยายามที่จะอนุมานหลักการทั่วไปจะช่วยให้คุณไม่มีที่ติ คุณเพียงแค่ต้องจดจำกฎพิเศษทั้งหมด ขอโทษ ②หมายเหตุ: คำว่า "หลังจากที่ขยายตัว" ทันทีหลังจากวลีที่คุณไฮไลต์ในความหมายของ นั่นเป็นสิ่งสำคัญ มันอาจไม่อธิบายความแตกต่างที่ไขปริศนาคุณ แต่มันอธิบายวิธีอื่น ๆ มากมายและไม่เหมือนกัน $_$_!$
zwol

คำตอบ:


32

!$เป็นตัวกำหนดคำประวัติศาสตร์ของการขยายตัวก็จะขยายคำพูดสุดท้ายของคำสั่งก่อนหน้านี้ในประวัติศาสตร์ IOW คำสุดท้ายของรายการก่อนหน้าในประวัติศาสตร์ คำนี้มักจะเป็นอาร์กิวเมนต์สุดท้ายของคำสั่ง แต่ไม่ใช่ในกรณีของการเปลี่ยนเส้นทาง ใน:

echo "hello" > /tmp/a.txt

คำสั่งทั้งหมด'echo "hello" > /tmp/a.txt'ปรากฏในประวัติศาสตร์และ/tmp/a.txtเป็นคำสุดท้ายของคำสั่งนั้น

_เป็นพารามิเตอร์ของเชลล์ซึ่งจะขยายเป็นอาร์กิวเมนต์สุดท้ายของคำสั่งก่อนหน้า ที่นี่การเปลี่ยนเส้นทางไม่ได้เป็นส่วนหนึ่งของการขัดแย้งที่ส่งผ่านไปยังคำสั่งดังนั้นจึงhelloมีการส่งผ่านการโต้แย้งechoเท่านั้น นั่นเป็นเหตุผลที่ขยายไปสู่$_hello

_ไม่ใช่พารามิเตอร์พิเศษมาตรฐานของเชลล์อีกต่อไป มันทำงานในbash, zsh, mkshและdashเฉพาะเมื่อโต้ตอบksh93เฉพาะเมื่อทั้งสองคำสั่งที่อยู่บนเส้นแยก:

$ echo 1 && echo $_
1
/usr/bin/ksh

$ echo 1
1
$ echo $_
1

1
ผลกระทบอย่างหนึ่งของ!$การขยายตัวของ$_พารามิเตอร์เทียบกับพารามิเตอร์ที่echo $_มักจะแสดงในประวัติศาสตร์เป็นecho $_ในขณะที่echo !$แสดงค่าที่มันถูกขยายไป เช่นecho one twoนั้นแล้วกดขึ้นแสดงecho !$ echo two
Jacktose
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.