O script ash do Busybox não sai corretamente após a execução do cat; incapaz de obter o código de saída

2

Considere o seguinte script wrapcat.sh (um wrapper para cat) para fins ilustrativos. É executado com busybox (ash) em uma caixa Linux 2.6 incorporada.

#!/bin/sh
cat $1

Em determinadas circunstâncias, esse script nem sempre sairá corretamente. Por exemplo, quando eu corro

$./wrapcat.sh /proc/pid/cmdline

para alguns pid , às vezes eu vou cair em um shell aguardando um comando. Depois de bater o retorno ou algo parecido, ele termina.

Meu diagnóstico é de que cat é interrompido por algum sinal e, portanto, o script não sai corretamente (já que não configuro nenhuma opção -e). Então, estou interessado no status de retorno do comando cat . Eu modifico o script da seguinte forma:

#!/bin/sh
cat $1
echo $? # echo the exit status

No entanto, o status de saída não é ecoado quando o script não consegue sair corretamente. Gostaria de saber por que o status de saída $? não é ecoado (e talvez mais especificamente, por que uma saída limpa nem sempre acontece particularmente quando se está indicando /proc/pid/cmdline ). O mesmo também ocorre às vezes quando catting /proc/pid/auxv e /proc/pid/environ . Função relevante na fonte: link

Eu não quero necessariamente saber como "consertar" isso, isso provavelmente pode ser feito definindo a opção -e mencionada anteriormente.

Nota: você provavelmente não conseguirá reproduzir isso em algo como o Ubuntu ou o Debian - o fenômeno pode ser específico de busybox ash, cat ou embedded Linux. Você pode, no entanto, simulá-lo interrompendo um processo filho sleep executado dentro de um script.

Por exemplo execute um script s.sh :

#!/bin/sh
sleep 1000
echo $?

Então, $./s.sh , ctrl-z, bg , disown %1 para executar o script em seu próprio processo. Agora em ps você verá algo como:

15610 pts/35   00:00:00 s.sh
15611 pts/35   00:00:00 sleep

Se você prosseguir e executar kill -2 15611 (no processo filho ), você observa

$ 130 # the exit status, which does get printed
command line waits for next command without clean exit
    
por user54945 19.12.2013 / 13:08

2 respostas

1

Você está interpretando mal a saída.

É só que esses arquivos (cmdline, environ ...) não são terminados por um caractere de nova linha.

Assim, por exemplo, se /proc/pid/cmdline contiver xxx , cat /proc/pid/cmdline produzirá xxx , mas como não há caractere de nova linha (que a disciplina terminal converte em saída para CRLF), o cursor não voltará para o início da linha (CR), nem descer por um (LF).

Em seguida, ao sair, seu shell exibirá seu prompt para aguardar o próximo comando, para que você veja algo como:

xxx$ 

e se houver um echo $? , isso será:

xxx0
$ 

Se o arquivo contiver mais de xxx , isso poderá ficar mais confuso.

Se você quiser adicionar um caractere de nova linha quando estiver faltando, use cut em vez de cat :

#! /bin/sh -
cut -b1- < "$1"
    
por 21.12.2013 / 00:10
0

Eu posso ver, se $ 1 for avaliado como uma string vazia, que cat está esperando para ler stdin. Então você precisa pressionar Ctrl-D ou Ctrl-C para fechar o gato para que o script possa continuar. Para este problema especificamente, eu tentaria

cat "${1:-/dev/null}"

Assim, se $ 1 estiver vazio ou não configurado, então pelo menos cat receberá um nome de arquivo válido com conteúdo finito para trabalhar.

    
por 19.12.2013 / 17:49