เครื่องหมายดอลลาร์ตามด้วยเครื่องหมาย at ( @
) หมายถึงอะไรในเชลล์สคริปต์
ตัวอย่างเช่น:
umbrella_corp_options $@
เครื่องหมายดอลลาร์ตามด้วยเครื่องหมาย at ( @
) หมายถึงอะไรในเชลล์สคริปต์
ตัวอย่างเช่น:
umbrella_corp_options $@
คำตอบ:
$@
คือพารามิเตอร์ทั้งหมดที่ส่งผ่านไปยังสคริปต์
ตัวอย่างเช่นถ้าคุณเรียก./someScript.sh foo bar
แล้วจะเท่ากับ$@
foo bar
ถ้าคุณทำ:
./someScript.sh foo bar
แล้วภายในsomeScript.sh
การอ้างอิง:
umbrella_corp_options "$@"
สิ่งนี้จะถูกส่งผ่านไปumbrella_corp_options
พร้อมกับพารามิเตอร์แต่ละตัวที่อยู่ในเครื่องหมายคำพูดคู่อนุญาตให้ใช้พารามิเตอร์ที่มีช่องว่างจากผู้เรียกและส่งต่อไป
someScript.sh foo bar "boo far"
?
$@
ไม่ไม่จำเป็นต้องมาจาก PARAMATERS ส่งผ่านไปยังสคริปต์ ... เช่น; set a b "x y"; printf '(%s)' "$@"
เอาท์พุท(a)(b)(x y)
$@
และ$*
$@
เกือบเหมือนกัน$*
ทั้งความหมาย "อาร์กิวเมนต์บรรทัดคำสั่งทั้งหมด" พวกเขามักจะใช้เพียงแค่ส่งข้อโต้แย้งทั้งหมดไปยังโปรแกรมอื่น (ดังนั้นการสร้างเสื้อคลุมรอบโปรแกรมอื่น ๆ
ความแตกต่างระหว่างไวยากรณ์ทั้งสองจะปรากฏขึ้นเมื่อคุณมีอาร์กิวเมนต์ที่มีช่องว่างในนั้น (เช่น) และใส่$@
เครื่องหมายคำพูดคู่:
wrappedProgram "$@"
# ^^^ this is correct and will hand over all arguments in the way
# we received them, i. e. as several arguments, each of them
# containing all the spaces and other uglinesses they have.
wrappedProgram "$*"
# ^^^ this will hand over exactly one argument, containing all
# original arguments, separated by single spaces.
wrappedProgram $*
# ^^^ this will join all arguments by single spaces as well and
# will then split the string as the shell does on the command
# line, thus it will split an argument containing spaces into
# several arguments.
ตัวอย่าง: การโทร
wrapper "one two three" four five "six seven"
จะส่งผลให้:
"$@": wrappedProgram "one two three" four five "six seven"
"$*": wrappedProgram "one two three four five six seven"
^^^^ These spaces are part of the first
argument and are not changed.
$*: wrappedProgram one two three four five six seven
wrappedProgram "$*"
-> separated by single spaces.
แต่ในตัวอย่างที่ 2 ของคุณจะไม่ถูกคั่นด้วยช่องว่างเดียว
นี่คืออาร์กิวเมนต์บรรทัดคำสั่งที่:
$@
= เก็บอาร์กิวเมนต์ทั้งหมดในรายการสตริง
$*
= เก็บอาร์กิวเมนต์ทั้งหมดเป็นสตริงเดี่ยว
$#
= เก็บจำนวนอาร์กิวเมนต์
การใช้วิธีการที่บริสุทธิ์$@
ในกรณีส่วนใหญ่ "ทำให้โปรแกรมเมอร์ยากที่สุดเท่าที่จะทำได้" เพราะในกรณีส่วนใหญ่มันนำไปสู่ปัญหาการแยกคำและช่องว่างและอักขระอื่น ๆ ในการโต้แย้ง
ใน (เดา) 99% ของทุกกรณีจำเป็นต้องใส่ไว้ใน"
: "$@"
เป็นสิ่งที่สามารถใช้ในการทำซ้ำข้อโต้แย้งได้อย่างน่าเชื่อถือ
for a in "$@"; do something_with "$a"; done
for a in start_token "$@" end_token; do something_with "$a"; done
:-)
แอท
ขยายไปยังพารามิเตอร์ตำแหน่งโดยเริ่มจากหนึ่งพารามิเตอร์ เมื่อการขยายเกิดขึ้นภายในเครื่องหมายคำพูดคู่พารามิเตอร์แต่ละตัวจะขยายเป็นคำแยกต่างหาก นั่นคือ "$ @" เทียบเท่ากับ "$ 1" "$ 2" .... หากการขยายตัวที่มีเครื่องหมายคำพูดเกิดขึ้นภายในคำการขยายตัวของพารามิเตอร์ตัวแรกจะรวมกับส่วนเริ่มต้นของคำเดิมและ การขยายตัวของพารามิเตอร์สุดท้ายจะเข้าร่วมกับส่วนสุดท้ายของคำเดิม เมื่อไม่มีพารามิเตอร์ตำแหน่ง "$ @" และ $ @ จะขยายเป็นไม่มีอะไร (เช่นจะถูกลบออก)
ในช่วงสั้น ๆขยายไปยังข้อโต้แย้งตำแหน่งผ่านจากโทรไปทั้งฟังก์ชั่นหรือสคริปต์$@
ความหมายของมันขึ้นอยู่กับบริบท : ภายในฟังก์ชั่นมันจะขยายไปยังอาร์กิวเมนต์ที่ส่งผ่านไปยังฟังก์ชันดังกล่าว หากใช้ในสคริปต์ (ไม่ใช่ภายในขอบเขตของฟังก์ชัน) มันจะขยายไปยังอาร์กิวเมนต์ที่ส่งผ่านไปยังสคริปต์ดังกล่าว
$ cat my-sh
#! /bin/sh
echo "$@"
$ ./my-sh "Hi!"
Hi!
$ put () ( echo "$@" )
$ put "Hi!"
Hi!
ตอนนี้หัวข้ออื่นที่มีความสำคัญยิ่งเมื่อความเข้าใจวิธีการ$@
ทำงานในเปลือกเป็นแยกคำ เชลล์แยกโทเค็นตามเนื้อหาของIFS
ตัวแปร ค่าเริ่มต้นคือ\t\n
; เช่นช่องว่างแท็บและขึ้นบรรทัดใหม่
การขยาย"$@"
จะให้สำเนาของอาร์กิวเมนต์ที่ผ่านไป อย่างไรก็ตามการขยายตัว$@
จะไม่เสมอไป โดยเฉพาะอย่างยิ่งหากข้อโต้แย้งมีตัวละครจากIFS
พวกเขาจะแยก
เวลาส่วนใหญ่ของสิ่งที่คุณจะต้องการที่จะใช้งานไม่ได้"$@"
$@