จะตรวจสอบว่าฉันใช้เชลล์ตัวไหนในเทอร์มินัล เชลล์ที่ฉันใช้ใน MacOS คืออะไร?
echo #SHELL
ไม่ได้เป็นอย่างนั้น ดูอันดับ 3 ในคำตอบโดย geekosaur
xterm -e /bin/cat
แต่ฉันไม่มีความสุขที่จะเรียก/bin/cat
เชลล์
จะตรวจสอบว่าฉันใช้เชลล์ตัวไหนในเทอร์มินัล เชลล์ที่ฉันใช้ใน MacOS คืออะไร?
echo #SHELL
ไม่ได้เป็นอย่างนั้น ดูอันดับ 3 ในคำตอบโดย geekosaur
xterm -e /bin/cat
แต่ฉันไม่มีความสุขที่จะเรียก/bin/cat
เชลล์
คำตอบ:
หลายวิธีจากมากไปน้อยเชื่อถือได้ (และมากไปน้อย):
ps -p$$ -ocmd=
. (บน Solaris สิ่งนี้อาจจำเป็นต้องใช้fname
แทนcmd
บน OSX และ BSD ควรเป็นcommand
แทนที่จะเป็นcmd
)$BASH_VERSION
, $ZSH_VERSION
และตัวแปรเปลือกเฉพาะอื่น ๆ$SHELL
; นี่เป็นทางเลือกสุดท้ายเนื่องจากมันระบุเชลล์เริ่มต้นของคุณและไม่จำเป็นต้องเป็นเชลล์ปัจจุบัน$0
เช่นกัน?
$0
เพราะมันซับซ้อนกว่า: (1) อาจเป็นเพียงชื่อฐาน (2) อาจมี '-' อยู่ด้านหน้าเพื่อระบุว่าเป็นเชลล์การเข้าสู่ระบบ
ps -p$$ -ocmd=""
is prettier :-)
$0
ก็ดูเหมือนว่ามีประโยชน์มากกว่า$SHELL
: คุณไม่เห็นด้วยไหม คุณสามารถไปป์ได้ตลอดsed
เพื่อลบ '-'
tcsh
, $tcsh
และ$version
จะถูกตั้งค่า นี่คือตัวแปรเชลล์ไม่ใช่ตัวแปรสภาพแวดล้อม หากคุณใช้เวอร์ชันที่ไม่ใช่ tcsh csh
ฉันไม่คิดว่าจะมีตัวแปรที่โดดเด่นใด ๆ และแน่นอนว่าไวยากรณ์ที่ใช้ในการตรวจสอบตัวแปรต่างกันระหว่าง csh / tcsh บนมือข้างหนึ่งและ sh / ksh / bash / zsh อีกด้านหนึ่ง
เมื่อคำถามถามถึงเชลล์ที่ใช้และไม่ได้พูดถึงข้อโต้แย้งที่อาจเกิดขึ้นผ่านไปนี่เป็นวิธีที่หลีกเลี่ยงการแสดง:
$ ps -o comm= -p $$
ksh93
หมายเหตุเกี่ยวกับการใช้งานที่เบากว่า (โทรศัพท์ Android, busybox ฯลฯ ): ps
ไม่ได้รับการสนับสนุนสำหรับ-p
สวิตช์เสมอไป แต่คุณสามารถค้นหาได้ด้วยคำสั่งเช่นps | grep "^$$ "
นั้น ( grep
regex นี้จะระบุ PID ที่ไม่ซ้ำกันดังนั้นจะไม่มีผลบวกใด ๆ
ps | grep $$
ยังคงสามารถให้ผลบวกปลอมตัวอย่างเช่นถ้ากระบวนการปัจจุบันของคุณและมีกระบวนการ1234
12345
มีสองวิธีที่ง่ายจริงๆ:
ใช้คำสั่งps :
ps -o comm= $$
หรือ
ps -h -o comm -p $$
ที่อยู่:
-h
หรือจบตัวเลือกทั้งหมดด้วย=
การไม่แสดงส่วนหัวใด ๆ-o comm
สำหรับแสดงเฉพาะชื่อกระบวนการ ( bash
แทน/bin/bash
)-p <PID>
รายการเท่านั้นดำเนินการกับรายการแบบฟอร์ม PID ที่ให้มาการใช้ระบบไฟล์หลอกข้อมูลกระบวนการ/ proc :
cat /proc/$$/comm
ตัวเลือกนี้ทำงานตรงตามps
คำสั่งด้านบน
หรือ
readlink /proc/$$/exe
/proc/PID/exe
ลิงก์นี้ไปยังไฟล์ที่กำลังดำเนินการซึ่งในกรณีนี้จะชี้ไปที่ / bin / bash, / bin / ksh ฯลฯ
เพื่อให้ได้ชื่อของเชลล์ที่คุณสามารถใช้ได้
basename $(readlink /proc/$$/exe)
นี่เป็นตัวเลือกเดียวที่จะให้ผลลัพธ์เดียวกันเสมอแม้ว่าคุณจะอยู่ในสคริปต์รหัสที่มาหรือเทอร์มินัลเป็นลิงก์ไปยังไบนารีของตัวแปลเชลล์ที่ใช้งานอยู่
คำเตือนคุณต้องระวังว่าสิ่งนี้จะแสดงไบนารีที่ดีที่สุดดังนั้น ksh อาจเชื่อมโยงกับ ksh93 หรือ sh เพื่อทุบตี
การใช้งาน/proc
มีประโยชน์จริง ๆ ผ่านทาง/proc/self
ซึ่งเชื่อมโยงไปยัง PID ของคำสั่งปัจจุบัน
การผสมผสานของคำตอบอื่น ๆ ทั้งหมดเข้ากันได้กับ Mac (comm), Solaris (fname) และ Linux (cmd):
ps -p$$ -o cmd="",comm="",fname="" 2>/dev/null | sed 's/^-//' | grep -oE '\w+' | head -n1
csh
และtcsh
มันให้ฉันAmbiguous output redirect.
หากคุณบันทึกไว้ในตัวแปรสภาพแวดล้อมของคุณคุณสามารถใช้สิ่งต่อไปนี้:
echo $SHELL
pid ของเชลล์ที่รันอยู่จะได้รับจาก var $$ (ในเชลล์ส่วนใหญ่)
whichsh="`ps -o pid,args| awk '$1=='"$$"'{print $2}'`"
echo "$whichsh"
การใช้ backticks เพื่อทำให้ jsh (เชลล์ Heirlomm) ทำงานได้
ในหลาย ๆ เชลล์การทดสอบโดยตรงของps -o args= -p $$
งาน แต่busybox ash
ล้มเหลวในเรื่องนั้น (แก้ไข)
การตรวจสอบที่$1
จะต้องเท่ากับการ$$
ลบบวกปลอมมากที่สุด
อันสุดท้าย;:
ถูกใช้เพื่อให้เชลล์รันสำหรับ ksh และ zsh
การทดสอบระบบเพิ่มเติมจะช่วยได้โปรดแสดงความคิดเห็นหากไม่ได้ผลสำหรับคุณ
ไม่ทำงานในcsh
ประเภทของกระสุน
/usr/lib/dyld
หนึ่ง/private/var/db/dyld/dyld_shared_cache_x86_64
รายการ
ฉันตั้งค่า$MYSHELL
สำหรับการทดสอบในอนาคตในผู้ไม่เชื่อเรื่องพระเจ้าเปลือกของฉัน~/.aliases
:
unset MYSHELL
if [ -n "$ZSH_VERSION" ] && type zstyle >/dev/null 2>&1; then # zsh
MYSHELL=`command -v zsh`
elif [ -x "$BASH" ] && shopt -q >/dev/null 2>&1; then # bash
MYSHELL=`command -v bash`
elif [ -x "$shell" ] && which setenv |grep builtin >/dev/null; then # tcsh
echo "DANGER: this script is likely not compatible with C shells!"
sleep 5
setenv MYSHELL "$shell"
fi
# verify
if [ ! -x "$MYSHELL" ]; then
MYSHELL=`command -v "$(ps $$ |awk 'NR == 2 { print $NF }')"`
[ -x "$MYSHELL" ] || MYSHELL="${SHELL:-/bin/sh}" # default if verify fails
fi
tcsh
ส่วนมีแนวโน้มที่จะไม่ฉลาดที่จะม้วนเป็นสคริปต์ POSIX สไตล์ตั้งแต่มันจึงแตกต่างกันอย่างสิ้นเชิง (ดังนั้นคำเตือนและห้าวินาที) (สำหรับหนึ่งcsh
- กระสุนสไตล์ไม่สามารถทำได้2>/dev/null
หรือ>&2
ตามที่ระบุไว้ในการเขียนโปรแกรม Csh ที่มีชื่อเสียงถือว่าเป็นคำพูดที่เป็นอันตราย )
คุณสามารถใช้echo $0
คำสั่งเพื่อตรวจสอบว่าคุณใช้เชลล์ตัวใดและ<name_of_the_shell> --version
ตรวจสอบเวอร์ชั่นของเชลล์ (เช่น. bash --version
)
วิธีนี้ใช้ได้เช่นกัน:
env | grep SHELL