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 set
tiệ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ó set
thể - 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à set
4, 5 và 6 và sau đó được chuyển đến lớp con được gọi su
thô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-DOCUMENT
sẽ 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à root
người dùng, anh ta sẽ gặp lỗi về quyền. Khi tôi trả lời tôi đề nghị ông chown
hoặc chgrp
cá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 root
là được cấp read
quyề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 exec
cuộ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.45
trên cả tài khoản nguồn và đích.