@slm ได้รวมเอกสาร POSIX แล้ว - ซึ่งมีประโยชน์มาก - แต่พวกเขาไม่ได้ขยายว่าการรวมพารามิเตอร์เหล่านี้มีผลกระทบต่อกันอย่างไร ยังไม่มีการกล่าวถึงที่นี่ในแบบฟอร์มนี้:
${var?if unset parent shell dies and this message is output to stderr}
นี่คือข้อความที่ตัดตอนมาจากคำตอบของฉันอีกและฉันคิดว่ามันแสดงให้เห็นถึงวิธีการทำงานเหล่านี้:
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?
อีกตัวอย่างจากที่เดียวกัน :
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
ตัวอย่างข้างต้นใช้ประโยชน์จากการทดแทนพารามิเตอร์ POSIX ทั้ง 4 รูปแบบและการทดสอบ:colon null
หรือnot null
การทดสอบที่หลากหลาย มีข้อมูลเพิ่มเติมในการเชื่อมโยงดังกล่าวข้างต้นและที่นี่ก็เป็นอีกครั้ง
อีกสิ่งหนึ่งที่ผู้คนมักไม่คำนึงถึง${parameter:+expansion}
ก็คือมีประโยชน์มากแค่ไหนในเอกสารที่นี่ นี่เป็นข้อความที่ตัดตอนมาจากคำตอบอื่น :
TOP
ที่นี่คุณจะตั้งค่าเริ่มต้นและเตรียมพิมพ์เมื่อเรียก ...
#!/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
กลาง
นี่คือที่คุณกำหนดฟังก์ชั่นอื่น ๆ เพื่อเรียกใช้ฟังก์ชั่นการพิมพ์ของคุณขึ้นอยู่กับผลของพวกเขา ...
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
}
ด้านล่าง
คุณได้รับการตั้งค่าทั้งหมดแล้วดังนั้นนี่คือที่ที่คุณจะดำเนินการและดึงผลลัพธ์ของคุณ
_less_important_function
: "${PLACE:="the cemetery"}"
_more_important_function
: "${RESULT:="regret it."}"
_less_important_function
ผล
ฉันจะไปทำไมในไม่ช้า แต่การเรียกใช้ข้างต้นสร้างผลลัพธ์ต่อไปนี้:
_less_important_function()'s
วิ่งครั้งแรก:
ฉันไปที่บ้านแม่ของคุณและเห็นDisney on Ice
ถ้าคุณเขียนตัวอักษรคุณจะประสบความสำเร็จ
แล้วก็ _more_important_function():
ฉันไปที่สุสานและเห็น Disney on Ice
หากคุณทำคณิตศาสตร์การแก้ไขคุณจะประสบความสำเร็จ
_less_important_function()
อีกครั้ง:
ฉันไปที่สุสานและเห็น Disney on Ice
หากคุณทำคณิตศาสตร์เพื่อการเยียวยาคุณจะต้องเสียใจ
มันทำงานอย่างไร:
คุณสมบัติที่สำคัญที่นี่เป็นแนวคิดของconditional ${parameter} expansion.
คุณสามารถตั้งค่าตัวแปรให้เป็นค่าเฉพาะถ้ามันเป็น unset หรือ null โดยใช้แบบฟอร์ม:
${var_name
=desired_value}
หากคุณต้องการตั้งค่าเฉพาะตัวแปรที่ไม่มีการตั้งค่าคุณจะละเว้น:colon
และค่า Null จะยังคงเหมือนเดิม
ในขอบเขต:
คุณอาจสังเกตเห็นว่าในตัวอย่างข้างต้น$PLACE
และ$RESULT
ได้รับการเปลี่ยนแปลงเมื่อตั้งค่าผ่านparameter expansion
แม้ว่าจะ_top_of_script_pr()
ถูกเรียกไปแล้วแต่ก็น่าจะตั้งค่าพวกเขาเมื่อมันทำงาน เหตุผลที่ทำให้งานนี้_top_of_script_pr()
เป็น( subshelled )
ฟังก์ชั่น - ฉันใส่มันไว้ในตัวparens
แทนที่จะ{ curly braces }
ใช้กับคนอื่น เนื่องจากมันถูกเรียกใน subshell ตัวแปรทุกตัวที่มันตั้งค่าlocally scoped
และเมื่อมันกลับไปที่เปลือกแม่ของมันค่าเหล่านั้นจะหายไป
แต่เมื่อ_more_important_function()
ตั้งค่า$ACTION
แล้วมันจะglobally scoped
ส่งผลกระทบต่อ_less_important_function()'s
การประเมินผลที่สองของ$ACTION
เพราะ_less_important_function()
กำหนด$ACTION
ผ่านเท่านั้น${parameter:=expansion}.
man bash
; ค้นหาบล็อก "การขยายพารามิเตอร์" (ประมาณ 28%) การมอบหมายเหล่านี้เป็นเช่นฟังก์ชั่นเริ่มต้น: "ใช้ค่าเริ่มต้นเฉพาะในกรณีที่ยังไม่มีการตั้งค่า"