Ответы:
Эта функция должна делать работу:
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. То, что происходит, - это самоотчеты о соблюдении условий. lxterminal на самом деле не полностью совместим с xterm, поэтому вам следует остерегаться. Спецификационные файлы обычно находятся в /usr/share/terminfo
.
Вы можете получить имя эмулятора терминала, изменив имя родительского процесса. Поэтому он работает с каждым эмулятором терминала.
В 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/^.* //')
На многих системах Linux echo $TERM
возвращение xterm
см. Пост постера выше.
Чтобы получить действующий терминал, сделайте это:
1: Закройте все запущенные в данный момент терминальные экземпляры.
2: Откройте новый терминал, используя ваш обычный метод.
3: введите команду следующим образом:
ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)
4: Возвращение должно быть примерно таким:
lxterminal --geometry=135x20
Вот разбивка:
Итак: ps
это «статус процесса»
Параметр ps -o
отображает информацию, связанную с указанным пробелом или разделенным запятыми списком ключевых слов Звучит сложно, но не совсем. (пробел или запятая) указан отдельно (список ключевых слов).
Итак, (список ключевых слов) - это 'cmd='
только одно ключевое слово в списке. Итак, просто с просьбой отобразить команду на открытие терминала.
опция ps -p
"by id процесса" Ого, это очень хорошая опция для ps. Проблема в том, что вы должны передать ps этот идентификатор процесса. Итак, как получить идентификатор процесса? Развернем выражение $(ps -o 'ppid=' -p $$)
Здесь мы должны начать думать немного глубже. Я хотел бы изобрести этот bash однострочник, но я этого не сделал. Я думаю, что украл его из 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
опять же "по идентификатору процесса", а в bash $$
- идентификатор процесса.
Если вы вызываете ps -o 'ppid=' -p $$
или любую другую команду, запрашивающую $$
напрямую из первой оболочки, он может сказать pid = 1, или pid из xWindow, или из вашей настольной программы, или вы можете получить реальный pid оболочки. Если вы спросите много раз, вы можете получить разные ответы каждый раз!
Но если вы вызовете дочь и спросите ее «Кто твой папочка», она скажет тебе! Очень умно. Я хотел бы быть таким гением, чтобы изобрести этот метод.
Использование pstree
и awk
самый простой способ:
pstree -sA $$ | awk -F "---" '{ print $2 }'
pstree
of $$
(атуальный процесс).В pstree
аргументах:
-s
: показать родителей процесса-A
: отображать вывод в чистом ASCII.awk
Инструмент сканирование шаблона и -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) Я не тестировал guake, но работает для всех остальных, упомянутых в первом ответе jlliagre.
Примечание (2) Из-за форматирования в уценке для вики вы не можете вырезать и вставлять, как показано. Вы должны удалить каждый обратный удар , включая удаление символов подчеркивания, и добавить фактический обратный удар без пробела перед 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
после определения.