Respostas:
Esta função deve fazer o trabalho:
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
. Obtive o bash v4.2.24, o python v2.7.3, se ajudar.
Tente o seguinte:
echo $TERM
Isso é mais autoritário, mas pode ser uma bagunça nos seus programas. No entanto, no meu, ele diz xterm
e no ttys linux
, o que eu acho que significa Linux Console.
$TERM
é uma variável que se refere à especificação relatada pelo emulador de terminal que você está usando, e não ao próprio emulador. Por exemplo, no meu sistema, echo $TERM
retorna xterm
mesmo que eu esteja executando o lxterminal. O que está acontecendo é o auto-relatório final de conformidade xterm. O lxterminal não é totalmente compatível com o xterm, portanto, você deve prestar atenção. Os arquivos de especificação geralmente estão localizados em /usr/share/terminfo
.
Você pode obter o nome do emulador de terminal, preenchendo o nome do processo dos pais. Portanto, ele funciona com qualquer emulador de terminal.
No bash, zsh, etc .:
basename "/"$(ps -f -p $(cat /proc/$(echo $$)/stat | cut -d \ -f 4) | tail -1 | sed 's/^.* //')
Com casca de peixe:
basename "/"(ps -f -p (cat /proc/(echo %self)/stat | cut -d \ -f 4) | tail -1 | sed 's/^.* //')
Em muitos sistema linux echo $TERM
retorno xterm
ver post stazher acima.
Para obter o terminal real em uso, faça o seguinte:
1: Feche todas as instâncias do terminal em execução no momento.
2: Abra um novo terminal usando seu método usual.
3: Digite o comando da seguinte maneira:
ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)
4: O retorno deve ser algo como:
lxterminal --geometry=135x20
Aqui está o detalhamento:
Então: ps
é "status do processo"
A opção ps -o
é Exibir informações associadas à lista de palavras-chave especificadas por espaço ou vírgula. Parece complicado, mas não é realmente. (espaço ou vírgula) separado (lista de palavras-chave) especificado.
Portanto, (lista de palavras-chave) é 'cmd='
apenas uma palavra-chave na lista. Então, apenas pedindo para exibir o comando para abrir o terminal.
A opção ps -p
é "por identificação do processo" Uau, essa é uma opção muito boa para ps. O problema é que você deve passar para ps esse ID do processo. Então, como obter a identificação do processo? Desembrulhamos a expressão $(ps -o 'ppid=' -p $$)
Aqui devemos começar a pensar um pouco mais fundo. Eu gostaria de ter inventado essa linha única do bash, mas não o fiz. Acho que roubei de https://wiki.archlinux.org/ em algum lugar, não consegui encontrar novamente. Esses caras são incríveis, mas muitas vezes não consigo entender o que eles dizem para fazer até depois de muito estudo. O que podemos fazer é entender agora, porque vou explicar.
então sabemos que $
é operador de expansão no bash. Eu gosto de pensar "desembrulhar". Assim, $(foo -opt bar)
desembrulhará ou expandirá "foo -opt bar". Mas no bash, a chave redonda única (...)
abre o subshell.
Então, $(foo -opt bar)
expande "foo -opt bar" como executado no shell da filha . Muito estranho e difícil de entender.
OK, agora estamos executando o comando quase idêntico novamente, ps -o 'ppid=' -p $$
mas desta vez ps, status do processo, mostra o que ele pode ver na instância do shell filha .
-o
lista de palavras-chave, apenas uma palavra-chave como antes, mas ppid=
isso está solicitando diretamente a identificação do processo do shell pai !! DENTRO DA CASCA DA FILHA! Muito esperto, sim? Estou tão empolgado quando consigo entender isso!
-p
novamente, "por identificação do processo" e em bash $$
é a identificação do processo.
Se você chamar ps -o 'ppid=' -p $$
, ou qualquer outro comando que solicite $$
diretamente do primeiro shell, ele pode dizer pid = 1, ou o pid do xWindow, ou do seu programa de desktop, ou talvez você tenha um pid real do shell. Se você perguntar muitas vezes, talvez obtenha respostas diferentes a cada vez!
Mas, se você invocar uma filha e perguntar "quem é seu pai", ela lhe dirá! Muito esperto. Eu gostaria de poder ser tão gênio para inventar esse método.
Usando pstree
e awk
é a maneira mais fácil:
pstree -sA $$ | awk -F "---" '{ print $2 }'
pstree
de $$
(o processo atual).Os pstree
argumentos:
-s
: exibe os pais de um processo-A
: exibe a saída em ASCII puro.A awk
ferramenta varre um padrão e -F
argumento é usado para dividir os processos.
'{ print $2 }'
diz para awk
enviar apenas o segundo padrão de correspondência (neste caso, o nome do emulador de terminal).$2
? No meu caso, o que é canalizado em awk
é realmente systemd---lightdm---lightdm---upstart---gnome-terminal----bash---pstree
...
xfsettingsd
vez do terminal que estou usando.
pstree -sA $$ | head -n1 | awk -F "---" '{ print $(NF-1) }'
Você está correto, eu só respondi a pergunta principal, não a pergunta no corpo. Então aqui está, e o tio de Bob.
Não sei ao certo o motivo da troca de caso, em uma resposta mostrada acima. Essa troca de gabinete não é necessária. Meu script ~ / .bashrc é na verdade apenas uma linha simples, todos os comandos echo são apenas para diversão. Como explicar...
Qualquer termo ao iniciar lê ~ / .bashrc e executa os comandos que ele verá em .bashrc. Portanto, não importa qual termo seja chamado, ele lerá .bashrc e executará os comandos; portanto, apenas a estrutura necessária no .bashrc seria modificar o comportamento ou excluir um termo ou outro. O comportamento desejado é que cada termo execute o mesmo comando, portanto, a troca de maiúsculas e minúsculas não é necessária. O próprio Terminal lhe dirá como ele foi chamado, então não há necessidade de se diferenciar.
Nota (1) Não testei o guake, mas funciona para todos os outros mencionados na primeira resposta por jlliagre.
Nota (2) Devido à formatação na marcação para wiki, você não pode recortar e colar como mostrado. Você deve excluir cada backtick , inclusive para excluir os caracteres de sublinhado, e adicionar backtick real, sem espaço antes ps
ou depois do -p $$)
.
script para ~ / .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."
Isso foi muito divertido. Eu adicionei isso ao meu próprio ~ / .bashrc.
se você estiver usando o bash, acho que este comando irá ajudá-lo:
which $(ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$))
Se você estava usando o ZSH, existe uma solução melhor (mais rápida), que usa apenas os componentes internos do ZSH e manipula /proc/$pid/{stat,cmdline}
diretamente.
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
após a definição.