หมายความว่าอะไรต่อไปนี้:
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
ฉันสนใจเป็นพิเศษในส่วนนี้:
varible=$(...)
ฉันรู้ว่าจะใช้วงเล็บในการดำเนินการ subprocess แต่ถ้าพวกเขาจะใช้ร่วมกับ$?
หมายความว่าอะไรต่อไปนี้:
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
ฉันสนใจเป็นพิเศษในส่วนนี้:
varible=$(...)
ฉันรู้ว่าจะใช้วงเล็บในการดำเนินการ subprocess แต่ถ้าพวกเขาจะใช้ร่วมกับ$?
คำตอบ:
จากคู่มือ Bash ( man bash):
การทดแทนคำสั่ง
การทดแทนคำสั่งอนุญาตให้เอาต์พุตของคำสั่งเพื่อแทนที่
ชื่อคำสั่ง มีสองรูปแบบ:
$ (คำสั่ง)
หรือ
`command`
Bash ทำการขยายตัวโดยการดำเนินการคำสั่งใน subshell
สภาพแวดล้อมและแทนที่การทดแทนคำสั่งด้วยมาตรฐาน
เอาต์พุตของคำสั่งโดยลบบรรทัดใหม่ต่อท้าย ที่ฝัง
การขึ้นบรรทัดใหม่จะไม่ถูกลบ แต่อาจถูกลบระหว่างคำ
รุนแรง การแทนที่คำสั่ง $ (ไฟล์ cat) สามารถถูกแทนที่ด้วย
เทียบเท่า แต่เร็วกว่า $ (ไฟล์ <)
(ซึ่งถือเป็นจริงสำหรับทุกบอร์นเหมือนเปลือกหอยคือsh, ksh, zsh, bashฯลฯ และzshยังสามารถที่จะจับข้อมูลที่มีตัวอักษร NUL ฝังตัวในลักษณะนี้)
คำสั่ง
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
จะกำหนดชื่อของไดเรกทอรีที่สคริปต์ตั้งอยู่ (ในขณะที่ยังมีการเปลี่ยนแปลงเครื่องหมายทั้งหมดลงทับ) basedirให้กับตัวแปร ข้อผิดพลาดคำเตือนหรือข้อความวินิจฉัยอื่น ๆ ที่ถูกส่งไปยังสตรีมข้อผิดพลาดมาตรฐานจะยังคงแสดงอยู่บนเครื่อง ( $(...)จับเฉพาะเอาต์พุตมาตรฐานของคำสั่ง)
เชลล์จะเริ่มต้นด้วยการดำเนินการแทนค่าคำสั่ง innermost:
echo "$0" | sed -e 's,\\,/,g'
การส่งออกของที่จะได้รับเป็นสตริงไปและเอาท์พุทของการที่จะได้รับมอบหมายให้กับตัวแปรdirnamebasedir
เครื่องหมายคำพูดคู่อยู่ที่นั่นเพื่อให้แน่ใจว่าไม่มีการแบ่งคำหรือชื่อไฟล์ที่จะทำมิฉะนั้นคุณอาจพบว่าสคริปต์ล้มเหลวหรือสร้างผลลัพธ์แปลก ๆ เมื่อ$0(ชื่อของสคริปต์รวมถึงเส้นทางที่ใช้เรียกใช้) มีช่องว่าง ตัวอักษรหรือชื่อไฟล์ตัวอักษรกลม (เช่น?หรือ*)
โดยทั่วไปแล้วเป็นความคิดที่ดีที่จะอ้างอิงการขยาย (การขยายตัวแปรการแทนที่คำสั่งและการขยายเลขคณิต) ดูคำถามนี้และคำตอบสำหรับคำอธิบายที่ดีว่าทำไมนี่เป็นความคิดที่ดี
หากสคริปต์ถูกเรียกใช้งานเป็น
$ /usr/local/bin/script.sh
แล้วจะได้รับค่าของbasedir/usr/local/bin
หรือบน Cygwin:
$ bash c:\\Users\\Me\\script.sh
แล้วจะได้รับค่าของbasedir c:/Users/Meแบ็กสแลชคู่บนบรรทัดคำสั่งในกรณีนี้คือเพื่อหลีกเลี่ยงแบ็กสแลชเดี่ยวจากเชลล์ มูลค่าที่แท้จริงของการมี$0c:\Users\Me\script.sh
อีกวิธีหนึ่งในการทำสิ่งเดียวกันโดยไม่ต้องใช้dirname, echoและsedจะเป็น
basedir="${0//\\//}"
basedir="${basedir%/*}"
/bin/shของ Solaris 10 หรือก่อนหน้า) $(...)ไม่ได้รับการสนับสนุน
มันหมายถึงการเรียกใช้สิ่งที่อยู่ภายในวงเล็บในsubshellและกลับมาว่าเป็นความคุ้มค่าvaribleในกรณีของคุณกำหนดว่า
การทดแทนคำสั่งที่varible=$(..)เรียกว่าและมันไม่มีความหมายอะไรนอกจากการเรียกใช้คำสั่งเชลล์และเก็บเอาต์พุตไปยังตัวแปรหรือแสดงกลับโดยใช้คำสั่ง echo ตัวอย่างเช่นแสดงวันที่และเวลา:
echo "Today is $(date)"
และเก็บไว้ในตัวแปร:
SERVERNAME=$(hostname)
สำหรับข้อมูลเพิ่มเติม: https://www.cyberciti.biz/faq/unix-linux-bsd-appleosx-bash-assign-variable-command-output/
man bashและค้นหาการทดแทนคำสั่ง