Como saber se você está em um texto datilografado?

11

Estou usando o scriptcomando para salvar toda a saída do terminal em um arquivo chamado typescript. Ou script foopara salvar no arquivo foo.

Agora, digamos que eu estou digitando comando após comando e esqueço se estou digitando ou não um texto datilografado.

Como posso descobrir se estou dentro de um texto datilografado ou não?

Rob Avery IV
fonte

Respostas:

7

Talvez com:

if lsof -tac script "$(tty)" > /dev/null; then
  echo "I'm running under script"
else
  echo "I'm not"
fi

Você pode adicionar algo como:

lsof -tac script "$(tty)" > /dev/null && PS1="[script] $PS1"

Para o seu ~/.zshrcou ~/.bashrc, então as informações sobre se você está scriptou não seriam visíveis no prompt do shell.

Como alternativa, se você não pode garantir a lsofinstalação, poderá fazê-lo (assumindo um IFS não modificado):

terminal=$(ps -o comm= -p $(ps -o ppid= -p $(ps -o sid= -p "$$")))
[ "$terminal" = script ] && PS1="[script] $PS1"

A heurística é fazer com que o nome do comando do pai do líder da sessão que geralmente seria o emulador de terminal ( xterm, script, screen...).

Stéphane Chazelas
fonte
1
@teikakazura, a parte heurística foi porque você não tem garantia de que será o processo pai do líder da sessão. Nada a ver com reutilização de pid aqui, pois o líder da sessão e seu pai normalmente ainda estarão por perto quando você executar esse comando. Você poderia dizer que o primeiro é heurístico e estamos apenas verificando o nome do processo. Qualquer comando cujo nome também seja scripte tenha o tty aberto também causaria um falso positivo.
Stéphane Chazelas 23/02
1
@teikakazura Sobre (2), que verificaria o ppid do shell atual. Aqui, você deseja verificar o ppid do líder da sessão (normalmente, esse seria o shell que foi scriptiniciado).
Stéphane Chazelas 23/02
Não consigo entender o comentário do @StephaneChazelas aqui (o que é "(2)", provavelmente um comentário excluído), mas a segunda parte da resposta é muito interessante, pois pode detectar não apenas scriptmas também outras situações, como su -l, sshconsole Linux e talvez outros, e forneça (através de outros argumentos de ps) muito mais informações.
Stéphane Gourichon
5

Problema interessante. Eu descobri que um pequeno script bash poderia fazer o trabalho com bastante segurança:

#!/bin/bash

PP=$(ps -o ppid= $$)

while [[ $PP != 1 ]]
do
    LINE=$(ps -o ppid= -o comm= $PP | sed 's/^  *//')
    COMM=${LINE#* }
    PP=${LINE%% *}
    if [[ $COMM == script ]]  # Might need a different comparison
    then
        echo "In script"
        exit 0
    fi
done
echo "Not in script"

Eu acho que isso é um pouco diferente do proposto por Stephane Chazelas, na medida em que meu script cria a relação pai: filho que os processos Linux / Unix mantêm até encontrar o PID 1 ou encontrar "script" como o processo.

Bruce Ediger
fonte
4
Abordagem interessante. No entanto, observe que, por exemplo, se você iniciar uma xtermsessão de script, esse script exibirá o shell no xterm sendo executado sob script. Bem, é de certa forma, mas a saída não está indo para o texto datilografado. Minha abordagem verifica o terminal associado à sessão atual, para não ter esse problema.
Stéphane Chazelas 20/03/2013
0

Se você tiver um diretório / bin pessoal em seu caminho (por exemplo, / home / user / bin, coloque um shell script com o nome 'script' (mesmo nome que o binário), com o seguinte conteúdo:

#!/bin/bash
export SCRIPT_RUNNING=1
exec /usr/bin/script # full path to your script(1) binary

Agora, na execução do script, você pode testar a variável de ambiente SCRIPT_RUNNING e fazer o que quiser com base nela.

EDITAR:

Na verdade, há uma maneira muito mais fácil. O seguinte diz tudo, crie três arquivos, ~ / bin / script, ~ / bin / script-shell e ~ / .scriptrc:

~ > ls ~/bin/script ~/bin/script-shell ~/.scriptrc
-rw-r--r-- 1 roadowl users 23 Oct 18 16:52 /home/roadowl/.scriptrc
-rwx------ 1 roadowl users 49 Oct 18 16:53 /home/roadowl/bin/script
-rwx------ 1 roadowl users 56 Oct 18 16:55 /home/roadowl/bin/script-shell

~/bin > cat script
#!/bin/bash
exec /usr/bin/script -c script-shell

~/bin > cat script-shell
#!/bin/bash
exec /bin/bash --rcfile /home/bjd/.scriptrc

~/bin > cat ~/.scriptrc
export PS1="[script] "

Se o seu shell atual for bash, não se esqueça de executar hash -rdepois de criar esses arquivos, para garantir que ~ / bin / script seja executado quando 'script' for inserido como um comando (verifique com which script).

Como antes, observe que você deve ter ~ / bin em seu PATH, precedendo o caminho padrão para que isso funcione.

Roadowl
fonte