ความหมายของ“ _ =” คืออะไร?


29

หลังจากที่ฉันเรียกใช้set -a var=99ฉันสามารถค้นหาประโยคในผลลัพธ์ของset:

...
TERM=xterm
UID=0
USER=root
VIRTUAL_ENV_DISABLE_PROMPT=1
_=var=99
colors=/etc/DIR_COLORS
...

ใครช่วยบอกฉันได้ว่า "_ =" หมายถึงอะไร

ฉันทราบว่าecho $varจะไม่ให้อะไรเลย ถ้าฉันเรียกใช้set -aแล้วsetจะไม่รวมตัวแปรนี้อีก เกิดอะไรขึ้น?


คำตอบ:


16

เมื่อคุณดำเนินการset -a var=99มีสามสิ่งที่แตกต่างเกิดขึ้น (เกี่ยวข้องกับคำถามของคุณ):

  1. ตัวเลือกชุด ( -a) (ย้อนกลับโดยทำset +a) เพื่อส่งออก vars
  2. พารามิเตอร์ตำแหน่งคือ "ตั้งค่า" เป็นสิ่งที่ตามหลังตัวเลือก ( $1ตั้งค่าเป็นvar=99)
  3. ตัวแปรเชลล์ขีดล่าง$_ถูกตั้งค่าเป็นพารามิเตอร์สุดท้าย (ขยาย)

ชุด

การดำเนินการของset -aเครื่องหมายทั้งหมดที่ตามมา (ใหม่หรือมีการเปลี่ยนแปลง) เป็นตัวแปรที่ส่งออก (ในเปลือกหอยทั้งหมดยกเว้นcshและบางส่วนเปลือกหอยที่เกี่ยวข้อง)

$ set -a
$ myvariable=wer
$ env | grep myvariable
myvariable=wer

หากต้องการกู้คืนจากการตั้งค่านี้เพียงแค่เปลี่ยน-เป็น+:

$ set +a
$ unset myvariable              # to erase it from the environment if it
                                # was exported before the change of set +a
$ myvariable=456544654          # A new value of the variable.
$ env | grep "variable"         # No output means the var does not exist
                                # in the current environment

set var = 99

ซึ่งจริงๆแล้วควรset -- var=99หลีกเลี่ยงการตีความตัวเลือก (และชุดมีจำนวนมาก) ด้วยค่าที่ขึ้นต้นด้วยเส้นประ ( -)

ชุดรายการของอาร์กิวเมนต์ (รายการพารามิเตอร์ตำแหน่ง) --เพื่อว่าหลังจากที่ ที่ถูกต้องในเชลล์ที่สมเหตุสมผลทั้งหมด (ไม่ใช่ใน csh et al) อาร์กิวเมนต์ตำแหน่งจะพิมพ์ด้วย "$ @" (หรือคล้ายกัน "$ *" ไม่เท่ากับ)

$ set -- a=1 b=2 c=3
$ echo "$@"
a=1 b=2 c=3

_ = last_argument

และค่าของตัวแปรเชลล์ภายใน_เปลี่ยนเป็นอาร์กิวเมนต์สุดท้ายของบรรทัดที่ดำเนินการ นั่นไม่เป็นความจริงในเชลล์เกือบทั้งหมด (jsh, ash, yash, dash, lksh, mksh, ksh93, attsh และ csh และ tcsh) ยกเว้น bash

$ echo one two last argument
one two last argument

$ echo "$_"
argument

$ echo This is a new: last_argument
This is a new: last_argument

$ echo "$_"
last_argument

โปรดทราบว่าค่าใน$_คือค่าหลังจากการขยาย:

$ a="A New_Argument"
$ echo Something else to test: "$a"
Something else to test: A New_Argument

$ echo "$_"
A New_Argument

นั่นเป็นเหตุผลที่เมื่อคุณรัน:

$ set -a myvar=99; set | grep 'myvar'
_=myvar=99

คุณจะได้รับคำอธิบายของตัวแปรเชลล์ '$ _' สิ่งนี้ยังใช้งานได้:

$  set -a myvar=99; declare -p _
declare -- _="myvar=99"

37

ขีดเส้นใต้เป็นตัวแปรเชลล์พิเศษ สิ่งที่คุณเห็นนี่คือขีดล่าง ( _ตัวแปร) var=99ที่มีค่าของ มันอ่านได้อย่างเดียวและดูแลโดยเชลล์ มันคือ:

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

ตัวอย่างของคุณอยู่ในหมวดหมู่ที่สอง คุณพิมพ์:

set -a var=99  

ดังนั้นอาร์กิวเมนต์สุดท้ายมีvar=99และที่เป็นค่าที่คุณตั้งค่า (คุณไม่ได้ตั้งค่าvarการ99) ดังนั้นจึง_ถูกตั้งค่าเป็น และนี่คือสิ่งที่ถูกรายงาน:

_=var=99  

มันค่อนข้างสับสน แต่ข้อแรก=บ่งบอกถึงการมอบหมายตัวแปร_และข้อที่สองเป็นส่วนหนึ่งของค่า

นอกจากนี้ยังเป็นมูลค่าการกล่าวขวัญว่า-aตัวเลือกที่setจะทำให้ตัวแปรที่กำหนดไว้ทั้งหมดจะถูกส่งออกในภายหลัง


16

คำตอบที่ถูกต้องนั้นขึ้นอยู่กับเชลล์ที่คุณใช้:

  • เพื่อbashอะไรก็ตามที่ @BobEager พูดถึง
  • สำหรับzshมันถูกตั้งค่าเป็นอาร์กิวเมนต์สุดท้ายของคำสั่งก่อนหน้านี้และเป็นชื่อพา ธ เต็มของคำสั่งในสภาพแวดล้อมของคำสั่ง
  • เชลล์บางตัวต้องการdashตั้งค่าตัวแปรนี้เฉพาะเมื่อใช้งานเซสชันแบบโต้ตอบ

อาจมีลักษณะพิเศษอื่นในเชลล์อื่นเช่นกัน ดังนั้น$_จึงไม่ได้กำหนดไว้ใน POSIX ดังนั้นจึงควรตระหนักถึงปัญหาการพกพาที่อาจเกิดขึ้นเมื่อใช้งาน

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

export var=99

2
unset var;set -a; var=99ไวยากรณ์ยังที่ถูกต้องคือ ใช้งานได้ในเชลล์ที่ปรับแต่งได้ทั้งหมด (ไม่ใช่ csh et al)
ลูกศร

1
@Arrow ถึงแม้ว่าจะเป็นไปตามบรรทัดสุดท้ายของคำตอบของBob Eagerสิ่งนี้จะทำให้ตัวแปรทั้งหมดถูกตั้งค่า / แก้ไขในภายหลังซึ่งอาจไม่ใช่สิ่งที่คุณต้องการ
TripeHound

8

และฉันทราบว่าecho $varจะไม่ให้อะไรเลย … เกิดอะไรขึ้น?

ในการพิมพ์bash (1) ที่ไม่ค่อยดีนักเราพบว่า

set[ --abefhkmnptuvxBCEHPT] [ ตัวเลือกชื่อ ] [ หาเรื่อง …]   [ ] [ ตัวเลือกชื่อ ] [ หาเรื่อง …]-o
set+abefhkmnptuvxBCEHPT+o

            ︙
    เมื่อมีการระบุตัวเลือกพวกมันจะตั้งค่าหรือยกเลิกการตั้งค่าแอตทริบิวต์ของเชลล์ ข้อโต้แย้งใด ๆ ที่เหลือหลังจากการประมวลผลตัวเลือกที่จะถือว่าเป็นค่าสำหรับพารามิเตอร์ตำแหน่งและได้รับมอบหมายในการสั่งซื้อเพื่อ$1, ...$2 $n

ซึ่งหมายถึงset -a var=99ไม่ได้กำหนดตัวแปรสภาพแวดล้อมvarที่จะ99; มันตั้งไป$1 var=99ลองecho "$1"หรือecho "$*"และคุณจะเห็น

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