ฉันติดตั้ง gnome-terminal และ Guake แล้ว ฉันต้องการที่จะให้ข้อความเริ่มต้นที่แตกต่างกันที่จะแสดงบนเทอร์มินัลอีมูเลเตอร์เมื่อเริ่มต้น ฉันควรเขียนโค้ดอะไรใน. bashrc เพื่อให้บรรลุผล?
ฉันติดตั้ง gnome-terminal และ Guake แล้ว ฉันต้องการที่จะให้ข้อความเริ่มต้นที่แตกต่างกันที่จะแสดงบนเทอร์มินัลอีมูเลเตอร์เมื่อเริ่มต้น ฉันควรเขียนโค้ดอะไรใน. bashrc เพื่อให้บรรลุผล?
คำตอบ:
ฟังก์ชั่นนี้ควรทำงาน:
container() {
pid=$$
while true; do
pid=$(ps -h -o ppid -p $pid 2>/dev/null)
case $(ps -h -o comm -p $pid 2>/dev/null) in
(gnome-terminal) echo "Running in gnome terminal";return;;
(xterm) echo "Running in xterm";return;;
(rxvt) echo "Running in rxvt";return;;
(python) if [ ! -z "$(ps -h -o args -p $pid 2>/dev/null | grep guake)" ]; then echo "Running in Guake"; return; fi ;;
esac
[[ $(echo $pid) == 1 ]] && break
done
}
container
bash: [: too many arguments
ให้ข้อผิดพลาด มีทุบตี v4.2.24, python v2.7.3 ถ้ามันช่วยได้
ลองสิ่งนี้:
echo $TERM
สิ่งนี้มีสิทธิ์มากกว่า แต่อาจทำให้โปรแกรมของคุณยุ่งเหยิง อย่างไรก็ตามในของฉันมันพูดxterm
และ ttys มันพูดlinux
ซึ่งฉันคิดว่าหมายถึง Linux Console
$TERM
เป็นตัวแปรที่อ้างถึงสเปคตามที่รายงานด้วยตนเองโดยเทอร์มินัลอีมูเลเตอร์ที่คุณใช้ไม่ใช่ตัวจำลองที่แท้จริง ตัวอย่างเช่นในระบบของฉันecho $TERM
คืนค่าxterm
แม้ว่าฉันกำลังเรียกใช้ lxterminal สิ่งที่เกิดขึ้นคือการปฏิบัติตามรายงาน xterm ด้วยตนเอง lxterminal lxterminal ไม่สอดคล้องกับ xterm จริง ๆ ดังนั้นคุณต้องระวัง /usr/share/terminfo
ไฟล์ข้อมูลจำเพาะมักจะอยู่ใน
คุณสามารถรับชื่อเทอร์มินัลอีมูเลเตอร์โดยการ grepping ชื่อกระบวนการผู้ปกครอง ดังนั้นจึงสามารถใช้งานได้กับเครื่องจำลองการทำงาน
ใน bash, zsh ฯลฯ :
basename "/"$(ps -f -p $(cat /proc/$(echo $$)/stat | cut -d \ -f 4) | tail -1 | sed 's/^.* //')
ด้วยเปลือกปลา:
basename "/"(ps -f -p (cat /proc/(echo %self)/stat | cut -d \ -f 4) | tail -1 | sed 's/^.* //')
ในหลายระบบecho $TERM
กลับlinux xterm
ดูโพสต์ stazher ข้างต้น
ในการรับเครื่องที่ใช้งานจริงให้ทำสิ่งนี้:
1: ปิดทุกอินสแตนซ์เทอร์มินัลที่กำลังทำงานอยู่
2: เปิดเทอร์มินัลใหม่โดยใช้วิธีการปกติของคุณ
3: ป้อนคำสั่งดังนี้:
ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)
4: การกลับมาควรมีลักษณะดังนี้:
lxterminal --geometry=135x20
นี่คือรายละเอียด:
ดังนั้น: ps
คือ "สถานะกระบวนการ"
ตัวเลือก ps -o
คือแสดงข้อมูลที่เกี่ยวข้องกับช่องว่างหรือรายการคำหลักที่คั่นด้วยเครื่องหมายจุลภาคที่ระบุ ฟังดูซับซ้อน แต่ไม่ได้จริงๆ (เว้นวรรคหรือเครื่องหมายจุลภาค) คั่น (รายการคำหลัก) ที่ระบุ
ดังนั้น (รายการคำหลัก) เป็น'cmd='
เพียงหนึ่งคำหลักในรายการ ดังนั้นเพียงแค่ขอให้แสดงคำสั่งเพื่อเปิดเทอร์มินัล
ตัวเลือก ps -p
คือ "รหัสกระบวนการ" ว้าวนี่เป็นตัวเลือกที่ดีมากสำหรับ ps ปัญหาคือคุณต้องส่งไปยัง ps รหัสกระบวนการนี้ ดังนั้นวิธีรับ id กระบวนการ? เราแกะการแสดงออก $(ps -o 'ppid=' -p $$)
ที่นี่เราจะต้องเริ่มคิดลึกลงไปอีกหน่อย ฉันหวังว่าฉันจะประดิษฐ์นี้ bash หนึ่งซับ แต่ฉันไม่ได้ ฉันคิดว่าฉันขโมยมันจากhttps://wiki.archlinux.org/ที่ไหนสักแห่งฉันหาอีกไม่พบ พวกนั้นยอดเยี่ยม แต่หลายครั้งฉันไม่สามารถเข้าใจสิ่งที่พวกเขาบอกว่าจะทำจนกระทั่งหลังจากการศึกษามาก สิ่งที่เราทำได้คือเข้าใจในตอนนี้เพราะฉันจะอธิบาย
ดังนั้นเราจึงรู้ว่า$
ผู้ประกอบการส่วนขยายในทุบตี ฉันชอบคิดว่า "un-wrap" ดังนั้น$(foo -opt bar)
จะแกะหรือขยาย "foo -opt bar" แต่ในทุบตีรั้งรอบเดียว(...)
เปิด subshell
ดังนั้น$(foo -opt bar)
ขยาย "foo -opt บาร์" เป็นระยะในเปลือกลูกสาว แปลกมากและเข้าใจยาก
ตกลงดังนั้นตอนนี้เราจะใช้คำสั่งเหมือนกันเกือบอีกครั้งps -o 'ppid=' -p $$
แต่คราวนี้ PS เวลาสถานะกระบวนการแสดงให้เราเห็นสิ่งที่เขาสามารถมองเห็นจากภายในเช่นเปลือกลูกสาว
-o
รายการคำหลักเพียงคำเดียวก่อนหน้าppid=
นี้แต่จะขอรหัสกระบวนการโดยตรงของเปลือกหอย !! จากภายในเปลือกหอย! ฉลาดมากใช่ไหม ฉันตื่นเต้นมากเมื่อฉันเข้าใจสิ่งนี้!
-p
อีกครั้ง "ตามกระบวนการ id" และใน bash $$
คือรหัสกระบวนการ
หากคุณโทรps -o 'ppid=' -p $$
หรือคำสั่งอื่น ๆ ที่ขอ$$
โดยตรงจากเชลล์แรกเขาอาจพูดว่า pid = 1 หรือ pid จาก xWindow หรือจากโปรแกรมเดสก์ท็อปของคุณหรือคุณอาจได้รับ pid เชลล์จริง หากคุณถามหลายครั้งคุณอาจได้รับคำตอบที่แตกต่างกันในแต่ละครั้ง!
แต่ถ้าคุณเรียกลูกสาวและถามเธอว่า "ใครคือพ่อของคุณ" เธอจะบอกคุณ! ฉลาดมาก. ฉันหวังว่าฉันจะเป็นอัจฉริยะเช่นนี้ในการคิดค้นวิธีการนี้
การใช้pstree
และawk
เป็นวิธีที่ง่ายที่สุด:
pstree -sA $$ | awk -F "---" '{ print $2 }'
pstree
ของ$$
(กระบวนการ atual)pstree
ข้อโต้แย้ง:
-s
: แสดงพาเรนต์ของกระบวนการ-A
: แสดงผลใน pure ASCIIawk
เครื่องมือสแกนรูปแบบและ-F
ข้อโต้แย้งที่จะใช้ในการแยกกระบวนการ
'{ print $2 }'
บอกให้awk
ส่งออกเฉพาะรูปแบบการจับคู่ที่ 2 (ในกรณีนี้ชื่อจำลองเทอร์มินัล)$2
เหรอ ในกรณีของฉันสิ่งที่ส่งเข้ามาawk
นั้นจริง ๆ แล้วsystemd---lightdm---lightdm---upstart---gnome-terminal----bash---pstree
...
xfsettingsd
แทนที่จะใช้เทอร์มินัล
pstree -sA $$ | head -n1 | awk -F "---" '{ print $(NF-1) }'
คุณถูกต้องฉันทำเพียงคำตอบสำหรับคำถามหัวข้อไม่ใช่คำถามในร่างกาย ดังนั้นที่นี่คุณไปและลุงของบ๊อบ
ฉันไม่แน่ใจว่าสวิตช์ตัวเรือนเป็นอย่างไรในหนึ่งคำตอบที่แสดงไว้ด้านบน ไม่จำเป็นต้องสลับสวิตช์กรณีดังกล่าว สคริปต์ ~ / .bashrc ของฉันเป็นเพียงหนึ่งบรรทัดง่ายๆคำสั่ง echo ทั้งหมดนั้นสนุก จะอธิบายอย่างไร ...
คำใด ๆ เมื่อเริ่มอ่าน ~ / .bashrc และดำเนินการคำสั่งอะไรก็ตามที่เขาจะเห็นใน. bashrc ดังนั้นไม่ว่าจะเรียกคำใดคำหนึ่งเขาจะอ่าน. bashrc และดำเนินการคำสั่งดังนั้นโครงสร้างที่จำเป็นใน. bashrc เท่านั้นที่จะแก้ไขพฤติกรรมของหรือแยกคำหนึ่งหรืออีกคำหนึ่งออก พฤติกรรมที่ต้องการสำหรับทุกคำศัพท์ในการดำเนินการคำสั่งเดียวกันดังนั้นไม่จำเป็นต้องสลับกรณี เทอร์มินัลจะบอกคุณว่าเขาถูกเรียกดังนั้นจึงไม่จำเป็นต้องแยกความแตกต่าง
หมายเหตุ (1) ฉันไม่ได้ทดสอบการหลอกลวง แต่ทำงานเพื่อคนอื่น ๆ ที่กล่าวถึงในคำตอบแรกโดย jlliagre
หมายเหตุ (2) เนื่องจากการจัดรูปแบบใน markdown สำหรับ wiki คุณไม่สามารถตัดและวางตามที่แสดง คุณต้องลบแต่ละbacktickรวมทั้งการลบตัวอักษรที่ขีดเส้นใต้และเพิ่ม backtick ที่เกิดขึ้นจริงกับไม่มีช่องว่างก่อนหรือหลังps
-p $$)
สคริปต์สำหรับ ~ / .bashrc
# show welcome message for actual terminal in use
echo "Welcome. You are attempting to use"
echo ""
echo _backtick_ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)_backtick_
echo ""
echo "Good Luck and God Speed."
มันสนุกมาก ฉันได้เพิ่มสิ่งนี้ใน ~ / .bashrc ของฉันเอง
หากคุณกำลังใช้ bash ฉันจะใช้คำสั่งนี้:
which $(ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$))
หากคุณกำลังใช้ ZSH จะมีวิธีแก้ปัญหาที่ดีกว่า (เร็วกว่า) ซึ่งใช้ ZSH builtins และจัดการ/proc/$pid/{stat,cmdline}
โดยตรงเท่านั้น
get-terminal-emulator() {
if [[ $TTY = "/dev/tty"* ]]; then
echo "linux-console"
return
fi
local pid=$$ name=''
while true; do
proc_stat=(${(@f)$(</proc/${pid}/stat)})
name=${proc_stat[2]//[()]/}
case "${name}" in
gnome-terminal|konsole|rxvt|xterm)
echo "${name}"; return ;;
python*)
local cmdline=(${(@f)$(</proc/${pid}/cmdline)})
if [[ "$cmdline" =~ "\\bguake.main\\b" ]]; then
echo "guake"; return
fi
;;
esac
if test "$pid" = "1" -o "$pid" = ""; then
echo "unknown"
return
fi
pid=${proc_stat[4]}
done
}
container
หลังจากนิยาม