: ในเชลล์คือ คำสั่งว่าง (null command) ที่ไม่ทำงานใด ๆ นอกจากประเมินอาร์กิวเมนต์แล้วทิ้งไป และเมื่อใช้ร่วมกับการขยายพารามิเตอร์ จะช่วยจัดการการตรวจสอบอาร์กิวเมนต์ที่จำเป็นและการตั้งค่าเริ่มต้นได้อย่างกระชับ
: "${1:?missing argument, aborting!}" จะพิมพ์ข้อความวินิจฉัยไปยัง stderr และจบการทำงานด้วยสถานะที่ไม่ใช่ 0 หาก $1 ไม่มีหรือว่างเปล่า
- เมื่อส่ง
${VAR:=default} เป็นอาร์กิวเมนต์ของ : การขยายจะถูกดำเนินการแต่สตริงผลลัพธ์จะถูกทิ้งไป จึงสามารถ ตั้งค่าเริ่มต้นเท่านั้น โดยไม่รันผลลัพธ์ของการขยายเป็นคำสั่ง
- สามารถใช้
: ได้กับการล้างไฟล์ผ่าน redirection และการตรวจสอบว่าสามารถเข้าถึงได้หรือไม่, คำสั่งว่างใน trap, การตรวจสอบตัวแปรในสภาพแวดล้อม set -u และแขนงเงื่อนไขที่ว่างเปล่า
: "${VAR:=default}" ช่วยลดโอกาส พิมพ์ผิด เพราะเขียนชื่อตัวแปรเพียงครั้งเดียว และใน while : จะกลายเป็นเงื่อนไขที่สำเร็จเสมอ ใช้แทน ลูปไม่รู้จบ
คำสั่งว่างและการขยายพารามิเตอร์
: คือคำสั่ง built-in แบบ คำสั่งว่าง ที่ประเมินอาร์กิวเมนต์แล้วทิ้งผลลัพธ์ไป
- ย้อนกลับไปได้ถึง Thompson shell ในปี 1971 และในเวลานั้นยังถูกใช้เป็น label รวมถึงเป็นเครื่องหมายคอมเมนต์แรกของ Unix ด้วย
- แทนที่จะใช้เงื่อนไขสี่บรรทัด สามารถตรวจสอบอาร์กิวเมนต์ที่จำเป็นได้ด้วยบรรทัดเดียวต่อไปนี้
: "${1:?missing argument, aborting!}"
echo "Hello $1!"
- ไวยากรณ์ การขยายพารามิเตอร์
${name:?diagnostic} ใช้ตรวจสอบว่า $name ไม่ได้ถูกตั้งค่าหรือว่างเปล่าหรือไม่
- หากไม่มีค่า จะพิมพ์
diagnostic ไปยัง stderr และทำให้เชลล์จบการทำงานด้วยสถานะที่ไม่ใช่ 0
- หากมีค่า จะให้ผลลัพธ์เหมือน
$name
- หากรันแค่
${HELLO:=123} โดยไม่มีคำสั่งว่าง ผลลัพธ์จากการขยายคือ 123 จะถูกมองเป็นคำสั่งและเกิด command not found
: ${HELLO:=123} จะประเมินการขยาย ตั้งค่า HELLO=123 แล้วทิ้งผลลัพธ์ไป
: "${DATA_DIR:=/var/data}" ต่างจาก DATA_DIR="${DATA_DIR:-/var/data}" ตรงที่เขียนชื่อตัวแปรเพียงครั้งเดียว จึงลด โอกาสพิมพ์ผิด เช่น DATA_DRI
วิธีใช้ :
-
ตั้งค่าเริ่มต้น
- ตั้งค่าเริ่มต้นให้ตัวแปรพร้อมทิ้งผลลัพธ์จากการขยาย โดยไม่รันผลลัพธ์นั้น
: "${DATA_DIR:=/var/data}"
: "${RETRIES:=3}"
-
ล้างไฟล์และตรวจสอบการเข้าถึง
- เมื่อใช้ร่วมกับ redirection จะสามารถ ล้างไฟล์ หนึ่งไฟล์หรือมากกว่าได้
: > error.log
: > error.log > access.log
- สามารถใช้ subshell และ redirection เพื่อตรวจสอบว่าไฟล์อ่านหรือเขียนได้หรือไม่
( : < dataset.json ) && echo YES
( : >> result.json ) && echo YES
-
ตำแหน่งที่ต้องการคำสั่งว่าง
- ใช้ได้เมื่อไวยากรณ์ต้องมีคำสั่ง เช่น
trap แต่ไม่ควรทำงานจริงใด ๆ
trap : INT
sleep 60
- วางไว้ในแขนงของเงื่อนไขที่ต้องการปล่อยว่างได้เช่นกัน
if some-command; then
:
else
echo "command failed"
fi
-
ตรวจสอบหลายตัวแปร
- ตรวจสอบพร้อมกันว่ามีการตั้งค่าหลายตัวแปรแล้วหรือไม่ ในสถานะที่เปิดใช้
set -u
set -u
: "$DEPLOY_ENV" "$HOST"
-
ลูปไม่รู้จบ
: เป็นเงื่อนไขที่สำเร็จเสมอ จึงใช้เขียน ลูปไม่รู้จบ ได้อย่างกระชับ
while :; do
echo "I love colons"
sleep 1
done
1 ความคิดเห็น
ความคิดเห็นบน Lobste.rs
: hayalci@tassadar ~/src/dool ; jj rebase -s dxw -d mrnautocdของเชลล์กับรูปแบบต่อไปนี้ด้วย~/directoryname; <command>ทุกครั้งที่คัดลอกบรรทัดคำสั่งของเชลล์ ก็จะ
cdกลับไปยังไดเรกทอรีที่เคยรันคำสั่งนั้นไว้zshตั้งค่าให้เมื่อนำ ช่องว่างแบบไม่ขึ้นบรรทัดใหม่ที่มองไม่เห็น มาวาง จะลบเนื้อหาทางซ้ายmakeอาจรันหลายโปรเซสechoพร้อมกันและเขียนออกสตรีมเดียวกันจนรบกวนกันได้ หากเปลี่ยนเป็นแบบต่อไปนี้ จะไม่ใช่โปรเซสลูก แต่เป็น โปรเซสmakeเองที่แสดงผลman :หรือwhatis :ได้ยากคล้ายกับคำสั่ง
trueแต่ต่างกันตรงที่ไม่ตอบสนองเป็นพิเศษต่อ--help,--versionฯลฯ และจำนวนอักขระก็น้อยกว่าhelpแทนman:คือ นามแฝงของtrueตามตัวอักษรแต่ไม่เคยคิดจะใช้กับ ผลข้างเคียง ที่เกิดจากการประเมินอาร์กิวเมนต์
#แทน:เพื่อ บันทึกเป็นคอมเมนต์ ก็ได้ ข้อดีคือถ้าเป็นสิ่งที่จะรันภายหลัง นิพจน์ข้างในจะไม่ถูกประเมินล่วงหน้าhttps://nathangrigg.com/2014/04/zsh-push-line-or-edit/
-bash: !}": event not found"!"ออกจะทำงานได้หรือไม่while true; do...while true; doยาวกว่าwhile :; doแค่สามตัวอักษร จึงสั้นพออยู่แล้ว และโค้ดนั้นดูไม่ใช่ตัวอย่างที่เหมาะกับประเด็นที่ผู้เขียนต้องการสื่อ