Câu trả lời:
Chức năng này sẽ thực hiện công việc:
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
. Có bash v4.2.24, python v2.7.3 nếu nó giúp.
Thử đi:
echo $TERM
Điều này có thẩm quyền hơn, nhưng có thể bị các chương trình của bạn làm rối tung lên. Tuy nhiên, đối với tôi, nó nói xterm
và trên ttys nó nói linux
, mà tôi nghĩ là viết tắt của Linux Console.
$TERM
là một biến trong đó đề cập đến đặc tả là trình tự mô phỏng đầu cuối mà bạn đang sử dụng, chứ không phải cho trình giả lập thực tế. Ví dụ, trên hệ thống của tôi, echo $TERM
trả về xterm
mặc dù tôi thực sự đang chạy lxterminal. Điều gì đang xảy ra là lxterminal tự báo cáo tuân thủ xterm. lxterminal không thực sự hoàn toàn tuân thủ xterm, vì vậy bạn phải coi chừng. Các tập tin spec thường được đặt trong /usr/share/terminfo
.
Bạn có thể lấy tên trình giả lập thiết bị đầu cuối, bằng cách lấy tên của tiến trình cha mẹ. Do đó, nó hoạt động với mọi trình giả lập thiết bị đầu cuối.
Trong bash, zsh, vv.:
basename "/"$(ps -f -p $(cat /proc/$(echo $$)/stat | cut -d \ -f 4) | tail -1 | sed 's/^.* //')
Với vỏ cá:
basename "/"(ps -f -p (cat /proc/(echo %self)/stat | cut -d \ -f 4) | tail -1 | sed 's/^.* //')
Trên nhiều hệ thống linux echo $TERM
trở lạixterm
xem bài stazher ở trên.
Để có được thiết bị đầu cuối thực tế đang sử dụng, hãy làm điều này:
1: Đóng mọi phiên bản đầu cuối hiện đang chạy.
2: Mở thiết bị đầu cuối mới bằng phương pháp thông thường của bạn.
3: Nhập lệnh như sau:
ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)
4: Trả về phải là một cái gì đó như thế:
lxterminal --geometry=135x20
Đây là sự cố:
Vậy: ps
là "trạng thái quá trình"
Tùy chọn ps -o
là Hiển thị thông tin được liên kết với danh sách từ khóa được phân tách bằng dấu cách hoặc dấu phẩy được chỉ định. Nghe có vẻ phức tạp, nhưng thực sự không phải vậy. (dấu cách hoặc dấu phẩy) được phân tách (danh sách từ khóa) được chỉ định.
Vì vậy, (danh sách từ khóa) 'cmd='
chỉ có một từ khóa trong danh sách. Vì vậy, chỉ cần yêu cầu hiển thị lệnh để mở terminal.
Tùy chọn ps -p
là "by process id" Wow đây là tùy chọn rất hay cho ps. Vấn đề là, bạn phải chuyển đến ps quá trình id này. Vì vậy, làm thế nào để có được quá trình id? Chúng tôi mở biểu hiện $(ps -o 'ppid=' -p $$)
Ở đây chúng ta phải bắt đầu suy nghĩ sâu hơn một chút. Tôi ước tôi đã phát minh ra bash one-liner này, nhưng tôi đã không làm thế. Tôi nghĩ rằng tôi đã đánh cắp nó từ https://wiki.archlinux.org/ ở đâu đó, tôi không thể tìm lại được. Những người đó thật tuyệt vời, nhưng nhiều lần tôi không thể hiểu họ nói phải làm gì cho đến khi học nhiều. Những gì chúng ta có thể làm, là hiểu nó bây giờ, bởi vì tôi sẽ giải thích.
vì vậy chúng tôi biết $
là toán tử mở rộng trong bash. Tôi thích nghĩ "un-quấn". Vì vậy, $(foo -opt bar)
sẽ mở khóa hoặc mở rộng "thanh foo -opt". Nhưng trong bash, nẹp tròn đơn (...)
mở ra subshell.
Vì vậy, $(foo -opt bar)
mở rộng "thanh foo -opt" như chạy trong vỏ con gái . Rất kỳ lạ và khó hiểu.
OK, vì vậy bây giờ chúng tôi đang chạy lại lệnh gần như giống hệt nhau, ps -o 'ppid=' -p $$
nhưng lần này, trạng thái quá trình, cho chúng ta thấy những gì anh ta có thể nhìn thấy từ bên trong vỏ con gái .
-o
danh sách các từ khóa, chỉ có một từ khóa như trước đây, nhưng ppid=
đây là yêu cầu trực tiếp cho id quá trình của shell cha !! Từ ININ DAUGHTER SHELL! Rất thông minh, phải không? Tôi rất vui mừng khi tôi có thể hiểu điều này!
-p
một lần nữa, "by id process" và trong bash $$
là process id.
Nếu bạn gọi ps -o 'ppid=' -p $$
, hoặc bất kỳ lệnh nào khác yêu cầu $$
trực tiếp từ shell đầu tiên, anh ta có thể nói pid = 1 hoặc pid từ xWindow hoặc từ chương trình máy tính để bàn của bạn, hoặc bạn có thể nhận được pid shell thực sự. Nếu bạn hỏi nhiều lần, bạn có thể nhận được câu trả lời khác nhau mỗi lần!
Nhưng, nếu bạn gọi một cô con gái và hỏi cô ấy "Ai là bố của bạn", cô ấy sẽ nói với bạn! Rất thông minh. Tôi ước tôi có thể là thiên tài như vậy để phát minh ra phương pháp này.
Sử dụng pstree
và awk
là cách dễ nhất:
pstree -sA $$ | awk -F "---" '{ print $2 }'
pstree
các $$
(quá trình atual).Các pstree
đối số:
-s
: hiển thị cha mẹ của một quá trình-A
: hiển thị đầu ra trong ASCII thuần túy.Công awk
cụ quét một mẫu và -F
đối số được sử dụng để phân chia các quy trình.
'{ print $2 }'
cho awk
đầu ra mẫu khớp thứ 2 (trong trường hợp này là tên giả lập thiết bị đầu cuối).$2
? Trong trường hợp của tôi, những gì được đưa vào awk
thực sự là systemd---lightdm---lightdm---upstart---gnome-terminal----bash---pstree
...
xfsettingsd
thay vì thiết bị đầu cuối tôi đang sử dụng.
pstree -sA $$ | head -n1 | awk -F "---" '{ print $(NF-1) }'
Bạn đã đúng, tôi chỉ đưa ra câu trả lời cho câu hỏi tiêu đề, không phải câu hỏi trong cơ thể. Vì vậy, bạn đi đây, và Bob's yer chú.
Tôi không chắc chắn về việc chuyển đổi trường hợp là gì, trong một câu trả lời hiển thị ở trên. Trường hợp chuyển đổi như vậy là không cần thiết. Kịch bản ~ / .bashrc của tôi thực sự chỉ là một dòng đơn giản, tất cả các lệnh echo chỉ để giải trí. Làm thế nào để giải thích ...
Bất kỳ thuật ngữ nào khi bắt đầu đọc ~ / .bashrc và thực thi bất kỳ lệnh nào anh ta sẽ thấy trong .bashrc. Vì vậy, bất kể thuật ngữ nào được gọi, anh ta sẽ đọc .bashrc và thực thi các lệnh, do đó, chỉ có cấu trúc cần thiết trong .bashrc là để sửa đổi hành vi của hoặc loại trừ thuật ngữ này hay thuật ngữ khác. Hành vi mong muốn là cho mọi thuật ngữ để thực hiện cùng một lệnh, vì vậy không cần chuyển đổi trường hợp. Bản thân Terminal sẽ cho bạn biết anh ta được gọi như thế nào, vì vậy không cần phải phân biệt.
Lưu ý (1) Tôi đã không kiểm tra guake, nhưng hoạt động cho tất cả những người khác được đề cập trong câu trả lời đầu tiên của jlliagre.
Lưu ý (2) Do định dạng trong đánh dấu cho wiki, bạn không thể cắt và dán như hiển thị. Bạn phải xóa từng backtick , bao gồm để xóa các ký tự gạch chân và thêm backtick thực tế, không có khoảng trắng trước ps
hoặc sau -p $$)
.
tập lệnh cho ~ / .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."
Điều này thật thú vị. Tôi đã thêm cái này vào ~ / .bashrc của riêng tôi.
nếu bạn đang sử dụng bash, tôi biết lệnh này sẽ giúp bạn:
which $(ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$))
Nếu bạn đang sử dụng ZSH, có một giải pháp tốt hơn (nhanh hơn), chỉ sử dụng các nội dung ZSH và thao tác /proc/$pid/{stat,cmdline}
trực tiếp.
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
sau định nghĩa.