Considere o seguinte script wrapcat.sh
(um invólucro para gato) para fins ilustrativos. É executado com o busybox (ash) em uma caixa Linux 2.6 incorporada.
#!/bin/sh
cat $1
Sob certas circunstâncias, esse script nem sempre sai corretamente. Por exemplo, quando eu corro
$./wrapcat.sh /proc/pid/cmdline
para alguns pid
, às vezes vou cair dentro de um shell aguardando um comando. Depois de pressionar retorno ou similar, ele termina.
Meu diagnóstico é que cat
é interrompido por algum sinal e, portanto, o script não sai corretamente (como eu não defini nenhuma opção -e). Então, eu estou interessado no status de retorno do cat
comando. Eu modifico o script da seguinte maneira:
#!/bin/sh
cat $1
echo $? # echo the exit status
No entanto, o status de saída não é ecoado quando o script falha ao sair corretamente. Eu 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 faz o gato /proc/pid/cmdline
). O mesmo também ocorre às vezes quando se faz gatos /proc/pid/auxv
e /proc/pid/environ
. Função relevante na fonte: http://lxr.linux.no/#linux+v2.6.31/fs/proc/base.c#L253
Eu não quero necessariamente saber como 'consertar' isso, isso provavelmente pode ser feito configurando a opção -e acima mencionada.
Nota: você provavelmente não será capaz de reproduzir isso em algo como Ubuntu ou Debian - o fenômeno pode ser específico para o busybox ash, gato ou Linux incorporado. No entanto, você pode 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 ps
você verá algo como:
15610 pts/35 00:00:00 s.sh
15611 pts/35 00:00:00 sleep
Se você seguir em frente e executar kill -2 15611
(no processo filho ), você observará
$ 130 # the exit status, which does get printed
command line waits for next command without clean exit
$ 130
porque o processo em segundo plano produziu isso130
, seu shell não redesenha seu prompt, mas isso é esperado, pois não há como saber que algo foi gravado no terminal em segundo plano.Respostas:
Você está interpretando mal a saída.
Só que esses arquivos (cmdline, environment ...) não são finalizados por um caractere de nova linha.
Assim, por exemplo, se
/proc/pid/cmdline
contiverxxx
,cat /proc/pid/cmdline
será exibidaxxx
, mas como não há um caractere de nova linha (que a disciplina do terminal converte na saída em CRLF), o cursor não voltará ao início da linha (CR) nem diminuirá um (LF). )Em seguida, ao sair, seu shell emitirá seu prompt para aguardar o próximo comando, então você verá algo como:
e se houver
echo $?
, será:Se o arquivo contiver mais que
xxx
, isso pode ficar mais confuso.Se você quer um caractere de nova linha a ser adicionado quando se está faltando você poderia usar
cut
em vez decat
:fonte
tr '\0' '\n'
?xxx$
, só vejoxxx
sem ele redesenhar o prompt ou imprimir oecho $?
e simplesmente aguarda o próximo comando. O cursor ainda está naxxx
linha, como você indica.Eu posso ver, se $ 1 avalia como uma string vazia, que
cat
está esperando para ler a partir de stdin. Então você precisa pressionar Ctrl-D ou Ctrl-C para fechar o gato, para que o script possa continuar. Para esse problema especificamente, eu tentariaPara que, se $ 1 estiver vazio ou não definido, pelo menos cat obtenha um nome de arquivo válido com conteúdo finito para trabalhar.
fonte
cat "$1"
não seria um problema se$1
estivesse vazio. Melhor,cat < "$1"
para evitar problemas, se$1
houver-
ou uma opção.