@slm đã bao gồm các tài liệu POSIX - rất hữu ích - nhưng chúng không thực sự mở rộng về cách các tham số này có thể được kết hợp để ảnh hưởng lẫn nhau. Vẫn chưa có bất kỳ đề cập nào ở đây của mẫu này:
${var?if unset parent shell dies and this message is output to stderr}
Đây là một đoạn trích từ một câu trả lời khác của tôi và tôi nghĩ nó thể hiện rất rõ cách thức hoạt động của chúng:
sh <<-\CMD
_input_fn() { set -- "$@" #redundant
echo ${*?WHERES MY DATA?}
#echo is not necessary though
shift #sure hope we have more than $1 parameter
: ${*?WHERES MY DATA?} #: do nothing, gracefully
}
_input_fn heres some stuff
_input_fn one #here
# shell dies - third try doesnt run
_input_fn you there?
# END
CMD
heres some stuff
one
sh: line :5 *: WHERES MY DATA?
Một ví dụ khác từ cùng :
sh <<-\CMD
N= #N is NULL
_test=$N #_test is also NULL and
v="something you would rather do without"
( #this subshell dies
echo "v is ${v+set}: and its value is ${v:+not NULL}"
echo "So this ${_test:-"\$_test:="} will equal ${_test:="$v"}"
${_test:+${N:?so you test for it with a little nesting}}
echo "sure wish we could do some other things"
)
( #this subshell does some other things
unset v #to ensure it is definitely unset
echo "But here v is ${v-unset}: ${v:+you certainly wont see this}"
echo "So this ${_test:-"\$_test:="} will equal NULL ${_test:="$v"}"
${_test:+${N:?is never substituted}}
echo "so now we can do some other things"
)
#and even though we set _test and unset v in the subshell
echo "_test is still ${_test:-"NULL"} and ${v:+"v is still $v"}"
# END
CMD
v is set: and its value is not NULL
So this $_test:= will equal something you would rather do without
sh: line 7: N: so you test for it with a little nesting
But here v is unset:
So this $_test:= will equal NULL
so now we can do some other things
_test is still NULL and v is still something you would rather do without
Ví dụ trên tận dụng lợi thế của cả 4 hình thức thay thế tham số POSIX và các thử nghiệm :colon null
hoặc khác nhau của chúng not null
. Có nhiều thông tin hơn trong liên kết ở trên, và đây là một lần nữa .
Một điều khác mà mọi người thường không cân nhắc ${parameter:+expansion}
là nó có thể hữu ích như thế nào trong tài liệu ở đây. Đây là một đoạn trích từ một câu trả lời khác :
HÀNG ĐẦU
Tại đây bạn sẽ đặt một số giá trị mặc định và chuẩn bị in chúng khi được gọi ...
#!/bin/sh
_top_of_script_pr() (
IFS="$nl" ; set -f #only split at newlines and don't expand paths
printf %s\\n ${strings}
) 3<<-TEMPLATES
${nl=
}
${PLACE:="your mother's house"}
${EVENT:="the unspeakable."}
${ACTION:="heroin"}
${RESULT:="succeed."}
${strings:="
I went to ${PLACE} and saw ${EVENT}
If you do ${ACTION} you will ${RESULT}
"}
#END
TEMPLATES
Ở GIỮA
Đây là nơi bạn xác định các chức năng khác để gọi chức năng in của mình dựa trên kết quả của chúng ...
EVENT="Disney on Ice."
_more_important_function() { #...some logic...
[ $((1+one)) -ne 2 ] && ACTION="remedial mathematics"
_top_of_script_pr
}
_less_important_function() { #...more logic...
one=2
: "${ACTION:="calligraphy"}"
_top_of_script_pr
}
CHAI
Bạn đã có tất cả thiết lập ngay bây giờ, vì vậy đây là nơi bạn sẽ thực hiện và lấy kết quả của mình.
_less_important_function
: "${PLACE:="the cemetery"}"
_more_important_function
: "${RESULT:="regret it."}"
_less_important_function
CÁC KẾT QUẢ
Tôi sẽ đi vào lý do tại sao ngay lập tức, nhưng chạy ở trên tạo ra kết quả sau:
_less_important_function()'s
lần chạy đầu tiên:
Tôi đã đến nhà mẹ bạn và thấy Disney trên Ice.
Nếu bạn làm thư pháp bạn sẽ thành công.
sau đó _more_important_function():
Tôi đến nghĩa trang và thấy Disney trên Ice.
Nếu bạn làm toán khắc phục, bạn sẽ thành công.
_less_important_function()
lần nữa:
Tôi đến nghĩa trang và thấy Disney trên Ice.
Nếu bạn làm toán học khắc phục, bạn sẽ hối tiếc.
LÀM THẾ NÀO NÓ HOẠT ĐỘNG:
Tính năng chính ở đây là khái niệm conditional ${parameter} expansion.
Bạn chỉ có thể đặt biến thành giá trị nếu nó không được đặt hoặc null bằng cách sử dụng biểu mẫu:
${var_name
: =desired_value}
Nếu thay vào đó, bạn chỉ muốn đặt một biến không đặt, bạn sẽ bỏ qua các :colon
giá trị null và vẫn giữ nguyên.
TRÊN PHẠM VI:
Bạn có thể nhận thấy rằng trong ví dụ trên $PLACE
và $RESULT
được thay đổi khi được đặt qua parameter expansion
mặc dù _top_of_script_pr()
đã được gọi, có lẽ là đặt chúng khi nó chạy. Lý do công việc này _top_of_script_pr()
là một ( subshelled )
chức năng - Tôi đã đính kèm nó parens
thay vì { curly braces }
sử dụng cho các chức năng khác. Bởi vì nó được gọi trong một lớp con, mọi biến nó đặt locally scoped
và khi nó trở về vỏ mẹ, các giá trị đó sẽ biến mất.
Nhưng khi _more_important_function()
thiết lập $ACTION
thì globally scoped
nó ảnh hưởng đến _less_important_function()'s
đánh giá thứ hai $ACTION
vì chỉ _less_important_function()
thiết lập $ACTION
thông qua${parameter:=expansion}.
man bash
; tìm kiếm khối "Mở rộng tham số" (khoảng 28%). Các bài tập này là các hàm mặc định: "Chỉ sử dụng giá trị mặc định nếu chưa có giá trị nào được đặt."