หมายความว่าอะไรต่อไปนี้:
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'
การส่งออกของที่จะได้รับเป็นสตริงไปและเอาท์พุทของการที่จะได้รับมอบหมายให้กับตัวแปรdirname
basedir
เครื่องหมายคำพูดคู่อยู่ที่นั่นเพื่อให้แน่ใจว่าไม่มีการแบ่งคำหรือชื่อไฟล์ที่จะทำมิฉะนั้นคุณอาจพบว่าสคริปต์ล้มเหลวหรือสร้างผลลัพธ์แปลก ๆ เมื่อ$0
(ชื่อของสคริปต์รวมถึงเส้นทางที่ใช้เรียกใช้) มีช่องว่าง ตัวอักษรหรือชื่อไฟล์ตัวอักษรกลม (เช่น?
หรือ*
)
โดยทั่วไปแล้วเป็นความคิดที่ดีที่จะอ้างอิงการขยาย (การขยายตัวแปรการแทนที่คำสั่งและการขยายเลขคณิต) ดูคำถามนี้และคำตอบสำหรับคำอธิบายที่ดีว่าทำไมนี่เป็นความคิดที่ดี
หากสคริปต์ถูกเรียกใช้งานเป็น
$ /usr/local/bin/script.sh
แล้วจะได้รับค่าของbasedir
/usr/local/bin
หรือบน Cygwin:
$ bash c:\\Users\\Me\\script.sh
แล้วจะได้รับค่าของbasedir
c:/Users/Me
แบ็กสแลชคู่บนบรรทัดคำสั่งในกรณีนี้คือเพื่อหลีกเลี่ยงแบ็กสแลชเดี่ยวจากเชลล์ มูลค่าที่แท้จริงของการมี$0
c:\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
และค้นหาการทดแทนคำสั่ง