Eu tenho um script curto que é executado por um daemon do sistema para eventos específicos. Sei que o evento está ocorrendo e o script está sendo executado, mas não faz o que pretendo. Estranhamente, quando o executo manualmente, estou muito confuso.
Como posso descobrir o que está acontecendo? O script é basicamente uma série de comandos como este:
/bin/foo on 3
sudo bar a
U&L
. Eu interpretei mal o título e sugeriria que "Registrar a saída de um script do sistema para depuração" tornaria o objetivo mais claro. Além disso, meu cérebro congela quando leio essesfoo
bar
exemplos; prefiro algo que parece mais real. Estou relutante em editar qualquer postagem, por isso deixarei isso para você, se você acha que pode ser melhorado.Respostas:
Primeiro, se o script for executado por um daemon do sistema e esse daemon estiver em execução com privilégios de root, você não precisará usá-lo
sudo
. Isso incluiinit
(esystemd
), o que incluirc.local
. Se esse daemon não estiver sendo executado com privilégios de root, elesudo
não funcionará, a menos que/etc/sudoers
esteja configurado para permitir isso (e sem uma senha). Os usuários do Raspbian podem ficar confusos com isso, já que opi
usuário pode fazer qualquer coisa por padrão (e se você olhar/etc/sudoers
, verá como isso é feito).Em seguida, você pode capturar a saída de qualquer
bash
script ou qualquer conjunto de comandos dentro de um script bash, executando-os em uma subshell como esta: 1O
()
indica um subshell . Toda a saída de qualquer coisa dentro disso está sendo redirecionada para um/var/log/myTestLog.txt
arquivo. Algumas notas:&>
é um basismo , portanto, se o script for executado através de um shebang na primeira linha, deve ser#!/bin/bash
, não apenas/bin/sh
. "Bashisms" funcionam apenas nobash
shell.Isso inclui
/etc/rc.local
, que por padrão usa/bin/sh
(ou seja, sim, você pode alterar isso com segurança/bin/bash
)./var/log
requer privilégios de root para gravar. Se o processo não tiver, use ou crie um diretório que você sabe que pode. Em caso de dúvida, se você puder testar isso sem precisar desligar ou reiniciar o sistema, use/tmp
, que é gravável mundialmente (ou seja, por qualquer pessoa). No entanto/tmp
, não persiste entre as botas. Também é uma pequena partição baseada em RAM, portanto, não grave gigs de dados nela. Não é o seu cartão SD [na verdade, nas versões atuais do Raspbian, mas não conte com isso na prática] .&>
sobrescreverá qualquer coisamyTestLog.txt
. Se você deseja anexar a um log existente, o que pode ser uma boa ideia para fins de depuração, use&>>
. Você pode então adicionar um comando ao início desse subshell assim:Para separar as informações de cada execução. Se você não tiver certeza do que isso faz, tente na linha de comando.
Este último ponto é uma boa ilustração de algo que você pode fazer com relação aos comandos que não produzem nada - mas a maioria deles faz se você incluir, por exemplo,
-v
"verboso". Cuidado com alguns comandos-v
significa "informações sobre a versão impressa". Dê uma olhada na página de manual para saber se o comando e como isso funcionará (alguns comandos também usam uma opção diferente-v
).Por convenção, os comandos também retornam um valor 0 quando concluídos. Às vezes, isso é chamado de "status de saída" e você normalmente não o vê, mas o shell mostrará a você
echo $?
. TentarVocê receberá 0 e 2. Se você procurar na página de manual
ls
em "Status de saída", verá o enigmático bastante inespecífico:O que pode ou não ser melhor que nada, mas lá vai você.
No mínimo, isso indica que o comando falhou por algum motivo. O status de saída também permite que você faça coisas como estas:
A
&&
neste meio de caso "se o primeiro comando for bem-sucedido", presumindo que o primeiro comando usa a convenção de retornar 0 (que é por isso que eles costumam fazer). Se/bin/foo
não funcionar, não puder ser encontrado, etc.,sudo bar
nunca acontecerá.O uso de uma combinação de mensagens de log e execução condicional (
&&
) deve levá-lo muito mais perto de descobrir o problema ou, pelo menos, obter informações que possam ser úteis para outras pessoas para ajudá-lo a resolver o problema. Sem isso, o máximo que qualquer outra pessoa pode fazer é adivinhar.1. Você pode realizar o mesmo redirecionamento de saída para um script inteiro de dentro usando:
No topo (ou em qualquer lugar, e isso se aplicará a tudo subsequente).
fonte
Um aspecto importante que as pessoas tendem a esquecer ao executar scripts como daemons é o ambiente de shell e a
$PATH
variável em particular. No seu exemplo, a segunda linha conta com$PATH
: o nome completo desudo
é/usr/bin/sudo
e o shell do usuário sabe disso apenas porque foi instruído a pesquisar/usr/bin
ao procurar por executáveis. O mesmo vale parabar
.Considerando que
sudo
não é necessário ao executar scripts como daemons, sua segunda linha deve se parecer com:fonte