Ký hiệu đô la theo sau ký hiệu ( @
) có nghĩa là gì trong tập lệnh shell?
Ví dụ:
umbrella_corp_options $@
Ký hiệu đô la theo sau ký hiệu ( @
) có nghĩa là gì trong tập lệnh shell?
Ví dụ:
umbrella_corp_options $@
Câu trả lời:
$@
là tất cả các tham số được truyền cho tập lệnh.
Chẳng hạn, nếu bạn gọi ./someScript.sh foo bar
thì $@
sẽ bằng foo bar
.
Nếu bạn làm:
./someScript.sh foo bar
và sau đó someScript.sh
tham khảo bên trong :
umbrella_corp_options "$@"
điều này sẽ được chuyển đến umbrella_corp_options
với từng tham số riêng lẻ được đặt trong dấu ngoặc kép, cho phép lấy tham số có khoảng trống từ người gọi và chuyển chúng vào.
someScript.sh foo bar "boo far"
?
$@
nhưng không nhất thiết phải đến từ các thông số được truyền cho kịch bản ... ví dụ; set a b "x y"; printf '(%s)' "$@"
đầu ra(a)(b)(x y)
$@
và$*
$@
gần giống như $*
, cả hai đều có nghĩa là "tất cả các đối số dòng lệnh". Chúng thường được sử dụng để đơn giản chuyển tất cả các đối số cho một chương trình khác (do đó hình thành một trình bao bọc xung quanh chương trình khác đó).
Sự khác biệt giữa hai cú pháp xuất hiện khi bạn có một đối số có khoảng trắng trong đó (ví dụ) và đặt $@
dấu ngoặc kép:
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.
Ví dụ: Gọi điện thoại
wrapper "one two three" four five "six seven"
sẽ cho kết quả:
"$@": 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.
nhưng trong ví dụ thứ 2 của bạn, chúng không bị ngăn cách bởi các khoảng trắng.
Đây là các đối số dòng lệnh trong đó:
$@
= lưu trữ tất cả các đối số trong danh sách chuỗi
$*
= lưu trữ tất cả các đối số dưới dạng một chuỗi
$#
= lưu trữ số lượng đối số
Việc sử dụng nguyên chất $@
phương tiện trong hầu hết các trường hợp "làm tổn thương lập trình viên hết sức có thể", bởi vì trong hầu hết các trường hợp, nó dẫn đến các vấn đề về tách từ và với khoảng trắng và các ký tự khác trong các đối số.
Trong (đoán) 99% của tất cả các trường hợp, cần phải gửi nó vào "
: "$@"
là những gì có thể được sử dụng để lặp lại một cách đáng tin cậy trên các đối số.
for a in "$@"; do something_with "$a"; done
for a in start_token "$@" end_token; do something_with "$a"; done
:-)
@
Mở rộng đến các tham số vị trí, bắt đầu từ một. Khi mở rộng xảy ra trong dấu ngoặc kép, mỗi tham số sẽ mở rộng thành một từ riêng biệt. Nghĩa là, "$ @" tương đương với "$ 1" "$ 2" .... Nếu việc mở rộng trích dẫn kép xảy ra trong một từ, việc mở rộng tham số đầu tiên được nối với phần đầu của từ gốc và mở rộng tham số cuối cùng được nối với phần cuối của từ gốc. Khi không có tham số vị trí, "$ @" và $ @ mở rộng thành không có gì (nghĩa là chúng bị xóa).
Tóm lại, $@
mở rộng cho các đối số vị trí được truyền từ người gọi đến một hàm hoặc một tập lệnh . Ý nghĩa của nó là phụ thuộc vào ngữ cảnh : Bên trong một hàm, nó mở rộng tới các đối số được truyền cho hàm đó. Nếu được sử dụng trong một tập lệnh (không nằm trong phạm vi một hàm), nó sẽ mở rộng thành các đối số được truyền cho tập lệnh đó.
$ cat my-sh
#! /bin/sh
echo "$@"
$ ./my-sh "Hi!"
Hi!
$ put () ( echo "$@" )
$ put "Hi!"
Hi!
Bây giờ, một chủ đề khác có tầm quan trọng tối cao khi hiểu cách $@
hành xử trong vỏ là tách từ . Shell tách mã thông báo dựa trên nội dung của IFS
biến. Giá trị mặc định của nó là \t\n
; tức là khoảng trắng, tab và dòng mới.
Mở rộng "$@"
cung cấp cho bạn một bản sao nguyên sơ của các đối số được thông qua. Tuy nhiên, việc mở rộng $@
sẽ không luôn luôn. Cụ thể hơn, nếu các đối số chứa các ký tự từ IFS
, chúng sẽ phân tách.
Hầu hết thời gian những gì bạn sẽ muốn sử dụng là "$@"
, không $@
.