Відповіді:
Ця функція повинна виконувати роботу:
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
. Отримав bash v4.2.24, python v2.7.3, якщо це допомагає.
Спробуйте це:
echo $TERM
Це більш авторитетно, але може зіпсувати ваші програми. Однак на моєму, він говорить xterm
і на ttys він говорить linux
, що, на мою думку, означає Linux Console.
$TERM
- це змінна, яка посилається на специфікацію як на самовідповідь емулятора терміналу, який ви використовуєте, а не на власне сам емулятор. Наприклад, у моїй системі echo $TERM
повертається, xterm
хоча я фактично працюю lxterminal. Що відбувається - це xxterm відповідність lxterminal самозвітів. lxterminal насправді не повністю сумісний з xterm, тому ви повинні стежити. Файли специфікацій зазвичай розташовані в /usr/share/terminfo
.
Ви можете отримати ім'я емулятора терміналу, ввівши ім'я батьківського процесу. Тому він працює з кожним емулятором терміналу.
In 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
див. Стаджер пост вище.
Щоб отримати фактичний термінал у використанні, зробіть це:
1: Закрийте кожен запущений екземпляр терміналу.
2: Відкрийте новий термінал, використовуючи звичайний метод.
3: Введіть команду наступним чином:
ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)
4: Повернення має бути чимось таким:
lxterminal --geometry=135x20
Ось розбивка:
Отже: ps
це "статус процесу"
опція ps -o
- Відображення інформації, пов’язаної зі списком вказаних пробілом або комою ключових слів. Звучить складно, але насправді це не так. (пробіл або кома), розділені (список ключових слів).
Отже, (список ключових слів) - це 'cmd='
лише одне ключове слово у списку. Отже, просто просять відобразити команду для відкриття терміналу.
опція ps -p
- "за методом ідентифікатора". О, це дуже приємний варіант для PS. Проблема в тому, що ви повинні передати в ps цей ідентифікатор процесу. Отже, як отримати ідентифікатор процесу? Ми розгортаємо вираз $(ps -o 'ppid=' -p $$)
Тут треба почати думати трохи глибше. Мені б хотілося, щоб я винайшов цей однотонний баш, але цього не зробив. Я думаю, що я його вкрав з https://wiki.archlinux.org/ десь, я не міг знову знайти. Ці хлопці приголомшливі, але багато разів я не можу зрозуміти, що вони кажуть робити до довгого навчання. Що ми можемо зробити - це зрозуміти зараз, бо я поясню.
тому ми знаємо, що $
це оператор розширення в bash. Мені подобається думати "розмотати". Отже, $(foo -opt bar)
буде розгортати або розширювати "foo -opt bar". Але в bash, одна кругла дужка (...)
відкриває нижню частину корпусу.
Отже, $(foo -opt bar)
розгортається "foo -opt bar" під час запуску в дочірній оболонці . Дуже дивно і важко зрозуміти.
Гаразд, тому ми знову запускаємо майже ідентичну команду, ps -o 'ppid=' -p $$
але цього разу ps, статус процесу, показує нам, що він може бачити в екземплярі дочірньої оболонки .
-o
список ключових слів, лише одне ключове слово, як і раніше, але ppid=
це запитання безпосередньо для ідентифікатора процесу батьківської оболонки !! З ВІЧНОГО ДНЕГО ШЕЛА! Дуже розумно, так? Я так схвильований, коли можу це зрозуміти!
-p
знову "id id процесу", а в bash $$
- ідентифікатор процесу.
Якщо ви телефонуєте ps -o 'ppid=' -p $$
або будь-яка інша команда, яка запитує $$
безпосередньо з першої оболонки, він може сказати, що pid = 1, або pid з xWindow, або з вашої настільної програми, або ви, можливо, отримаєте фактичний pid shell. Якщо ви запитуєте багато разів, то, можливо, кожен раз отримуєте різні відповіді!
Але, якщо ви позовете дочку і запитаєте її "Хто твій тато", вона скаже тобі! Дуже розумний. Я б хотів, щоб я міг бути таким генієм, щоб винайти цей метод.
Використання pstree
та awk
найпростіший спосіб:
pstree -sA $$ | awk -F "---" '{ print $2 }'
pstree
з $$
(atual процесу).В pstree
аргументах:
-s
: відображення батьків процесу-A
: відображення виводу в чистому ASCII.awk
Інструмент сканування шаблону і -F
аргумент використовується для поділу процесів.
'{ print $2 }'
повідомляє awk
виводити лише другий шаблон відповідності (у цьому випадку ім'я емулятора терміналу).$2
? У моєму випадку те, що вкладається, awk
- це насправді systemd---lightdm---lightdm---upstart---gnome-terminal----bash---pstree
...
xfsettingsd
замість терміналу, який я використовую.
pstree -sA $$ | head -n1 | awk -F "---" '{ print $(NF-1) }'
Ви маєте рацію, я відповідав лише на заголовкове запитання, а не на тіло. Тож ось ти і дядько Боба.
Я не впевнений, в чому справа перемикача, в одній відповіді, показаній вище. Такий вимикач корпусу не потрібен. Мій сценарій ~ / .bashrc - це лише один простий рядок, усі команди ехо просто для розваги. Як пояснити ...
Будь-який термін при запуску читає ~ / .bashrc і виконує всі команди, які він побачить у .bashrc. Отже, незалежно від того, який термін називається, він буде читати .bashrc і виконувати команди, тому лише структура, потрібна в .bashrc, могла б змінити поведінку або виключити той чи інший термін. Бажана поведінка полягає в тому, щоб кожен термін виконував одну і ту ж команду, тому перемикання випадку не потрібно. Сам Термінал розповість, як його називали, тому розрізняти не потрібно.
Примітка (1) Я не тестував на guake, але працює для всіх інших, про які йшлося у першій відповіді jlliagre.
Примітка (2) Через форматування у відмітці для wiki, ви не можете вирізати та вставити, як показано. Ви повинні видалити кожні зворотні одиничні лапки , в тому числі для видалення знаків підкреслення, і додати фактичні зворотний одиничні лапки, без пробілу до 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 та маніпулює /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
після визначення.