Trên thực tế câu trả lời của @ Graeme - và câu hỏi của bạn - chỉ tham khảo các tác dụng phụ về cách xử lý shell "$@positional $*parameters".Chúng được gán bởi shell cho các đối số của nó khi gọi và bất cứ lúc nào sau đó với settiện ích tích hợp. Chúng có thể được gọi bất cứ lúc nào với "$*"phân tách từng vị trí với ký tự đầu tiên "$IFS"hoặc "$@"trích dẫn từng vị trí và phân tách chúng với tất cả"$IFS."
man set
NAME
set — set or unset options and positional parameters
SYNOPSIS
set [−abCefhmnuvx] [−o option] [argument...]
set [+abCefhmnuvx] [+o option] [argument...]
set −− [argument...]
set −o
set +o
Nếu bạn đã có các giá trị mà bạn cho ăn vỏ, bạn không cần phải --ba lần. Các tham số Shell có setthể - luôn luôn, bất cứ lúc nào, không chỉ trong lệnh gọi (ngoại trừ $ 0 và -i):
su - mikeserv -c 'set -- "$*" ; echo "$*" ;
set -- 4 5 6 ; echo "$*"' -- -- 7 8 9
7 8 9
4 5 6
Và tất cả các trích dẫn vỏ đó có thể gây nhầm lẫn. Điều này đơn giản hóa mọi thứ một chút:
( set -- 4 5 6
su - mikeserv 4<<-\CMD /dev/fd/4 "$@"
echo $0 "$*"
set -- "$*"
echo "$*"
set -- 7 8 9
echo "$*"
CMD
)
/dev/fd/4 4 5 6
4 5 6
7 8 9
Các đối số của shell cha là set4, 5 và 6 và sau đó được chuyển đến lớp con được gọi suthông qua vị tríparameter "$@array".
Lưu ý cách tôi thực ( subshell )hiện lệnh trên - Tôi làm điều đó bởi vì tôi không muốn gây rối với môi trường shell hiện tại của mình - bởi vì tôi có thể vô tình thay đổi thứ gì đó mà tôi không muốn nếu tôi làm vớiset.
GIỚI THIỆU VỀ GIẢM GIÁ:
Trước hết, hệ thống Unix của bạn hoạt động với các tệp - quyền tệp, nội dung tệp, thuộc tính tệp. Bằng cách này hay cách khác, mọi đối tượng dữ liệu bạn sử dụng đều có thể (và, ít nhất là theo ý kiến của tôi,) nên được xử lý như một tệp. Chuyển hướng trỏ đến một tập tin - đó là tất cả. A <<HERE-DOCUMENTsẽ mô tả một tập tin trong dòng sau đó chuyển hướng nó. Hoặc mở rộng vỏ được giải thích hoặc chúng không.
Người hỏi lưu ý trong các bình luận bên dưới rằng khi anh ta cố gắng sử dụng phương pháp này với tư cách là rootngười dùng, anh ta sẽ gặp lỗi về quyền. Khi tôi trả lời tôi đề nghị ông chownhoặc chgrpcác /dev/fd/${num}tập tin đặc biệt, nhưng điều này có lẽ không phải là phương pháp tốt nhất. Lý do anh gặp phải vấn đề này rootlà được cấp readquyền nhưng không phải là execute quyền. Bạn có thể dễ dàng xử lý điều này bằng cách tránh một execcuộc gọi. Thay vì gọi /dev/fd/${num}tệp trực tiếp trên dòng lệnh, hãy thực hiện:
su -c '. /dev/fd/'${num} ${num}<<SCRIPT
Sử dụng hai heredocs có thể giúp thoát. Đây là những gì xảy ra trong mọi trường hợp:
KHÔNG CÀI ĐẶT <<HEREDOC
sh 3<<\CMD /dev/fd/3
( echo 'without set "$@" or \$@ in here-doc' ; echo
set -- '1 "2" 3' 4 "5 6"
su - mikeserv 4<<-UNQUOTED 5<<-\PREQUOTED /dev/fd/4
echo UNQUOTED; echo $0 "$*"
printf "%s\\t\\t%s\\t\\t%s\\t\\t%s\\n" $(printf "'%s' " "$@") \\
$@ '$@' "$@" '"$@"' "'$@'" \$@ '\$@' "\$@" '"\$@"'
. /dev/fd/5
UNQUOTED
echo PREQUOTED ; echo $0 "$*"
printf "%s\t\t%s\t\t%s\t\t%s\n" $(printf "'%s' " "$@") \
$@ '$@' "$@" '"$@"' \$@ '\$@' "\$@" '"\$@"'
PREQUOTED
)
CMD
ĐẦU RA
without set "$@" or \$@ in here-doc
UNQUOTED
/dev/fd/3 1 2 3 4 5 6
1 "2" 3 4 5 6 1
2 3 4 5
6 1 "2" 3 4 5 6 1 2 3 4 5 6 "1 "2" 3 4 5 6"
'1 2 3 4 5 6' $@ "$@"
PREQUOTED
/dev/fd/5
'' $@ "$@" $@
\$@ $@ "\$@"
SET "$@"TRÊN<<HEREDOC
sh 3<<\CMD /dev/fd/3
( echo 'set "$@" and \$@ in here-doc' ; echo
set -- '1 "2" 3' 4 "5 6"
su - mikeserv 4<<-UNQUOTED 5<<-\PREQUOTED /dev/fd/4
set -- "$@" "\$@"
echo UNQUOTED; echo $0 "$*"
printf "%s\\t\\t%s\\t\\t%s\\t\\t%s\\n" $(printf "'%s' " "$@") \\
$@ '$@' "$@" '"$@"' "'$@'" \$@ '\$@' "\$@" '"\$@"'
. /dev/fd/5
UNQUOTED
set -- "$@" "\$@"
echo PREQUOTED ; echo $0 "$*"
printf "%s\t\t%s\t\t%s\t\t%s\n" $(printf "'%s' " "$@") \
$@ '$@' "$@" '"$@"' \$@ '\$@' "\$@" '"\$@"'
PREQUOTED
)
CMD
ĐẦU RA
set "$@" and \$@ in here-doc
UNQUOTED
/dev/fd/3 1 2 3 4 5 6
1 "2" 3 4 5 6 1
2 3 4 5
6 1 "2" 3 4 5 6 1 2 3 4 5 6 "1 "2" 3 4 5 6"
'1 2 3 4 5 6' 1 2 3 4 5 6 $@ 1 2 3 4 5 6
"$@"
PREQUOTED
/dev/fd/5 1 2 3 4 5 6 $@
'1 2 3 4
5 6' '$@' 1 2 3 4 5 6
$@ $@ 1 2 3 4 5 6 $@
"$@" $@ \$@ $@
"\$@"
THIẾT LẬP "$@"VÀ THÊM<<HEREDOC
sh 3<<\CMD /dev/fd/3
( echo 'set "$@" and \$@ AND additional parameters in here-doc' ; echo
set -- '1 "2" 3' 4 "5 6"
su - mikeserv 4<<-UNQUOTED 5<<-\PREQUOTED /dev/fd/4
set -- "$@" "\$@" '7 "8" 9' 10 "11 12"
echo UNQUOTED; echo $0 "$*"
printf "%s\\t\\t%s\\t\\t%s\\t\\t%s\\n" $(printf "'%s' " "$@") \\
$@ '$@' "$@" '"$@"' "'$@'" \$@ '\$@' "\$@" '"\$@"'
. /dev/fd/5
UNQUOTED
set -- "$@" "\$@" '13 "14" 15' 16 "17 18"
echo PREQUOTED ; echo $0 "$*"
printf "%s\t\t%s\t\t%s\t\t%s\n" $(printf "'%s' " "$@") \
$@ '$@' "$@" '"$@"' \$@ '\$@' "\$@" '"\$@"'
PREQUOTED
)
CMD
ĐẦU RA
set "$@" and \$@ AND additional parameters in here-doc
UNQUOTED
/dev/fd/3 1 2 3 4 5 6
1 "2" 3 4 5 6 1
2 3 4 5
6 1 "2" 3 4 5 6 1 2 3 4 5 6 "1 "2" 3 4 5 6"
'1 2 3 4 5 6' 1 2 3 4 5 6 7 "8" 9 10
11 12 $@ 1 2 3 4 5 6 7 "8" 9
10 11 12 "$@"
PREQUOTED
/dev/fd/5 1 2 3 4 5 6 7 "8" 9 10 11 12 $@ 13 "14" 15 16 17 18
'1 2 3 4
5 6' '7 "8"
9' '10' '11 12'
'$@' '13 "14" 15'
'16' '17 18' 1 2 3 4 5 6
7 "8" 9 10 11 12 $@
13 "14" 15 16 17 18 $@
1 2 3 4 5 6 7 "8" 9 10 11 12
$@ 13 "14" 15 16 17 18
"$@" $@ \$@ $@
"\$@"
bash 4.2.45trên cả tài khoản nguồn và đích.