เครื่องหมายดอลลาร์ตามด้วยเครื่องหมาย 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พวกเขาจะแยก
เวลาส่วนใหญ่ของสิ่งที่คุณจะต้องการที่จะใช้งานไม่ได้"$@"$@