Tengo un script corto que es ejecutado por un demonio del sistema para eventos particulares. Sé que el evento está ocurriendo y el script se está ejecutando, pero no hace lo que pretendo. Curiosamente, lo hace cuando lo ejecuto manualmente, por lo que estoy muy confundido.
¿Cómo puedo averiguar qué está pasando? El script es básicamente una serie de comandos como este:
/bin/foo on 3
sudo bar a
U&L
. Leí mal el título y sugeriría "Registrar el resultado de una secuencia de comandos del sistema para la depuración" aclararía el propósito. Además, mi cerebro se congela cuando leo estosfoo
bar
ejemplos, prefiero algo que parezca más real. Soy reacio a editar cualquier publicación, por lo que te dejaré esto si crees que se puede mejorar.Respuestas:
Primero, si el script es ejecutado por un demonio del sistema y ese demonio se está ejecutando con privilegios de root, no necesita usarlo
sudo
. Esto incluyeinit
(ysystemd
), que incluyerc.local
. Si ese demonio no se ejecuta con privilegios de root,sudo
no funcionará a menos que/etc/sudoers
esté configurado para permitirlo (y sin una contraseña). Esto puede confundir a los usuarios de Raspbian, ya que elpi
usuario puede hacer cualquier cosa de forma predeterminada (y si observa/etc/sudoers
, verá cómo se logra).A continuación, puede capturar la salida de cualquier
bash
script, o cualquier conjunto de comandos dentro de un script bash, ejecutándolos en un subshell como este: 1El
()
indica una subshell . Toda la salida de cualquier cosa dentro de esto se redirige a un/var/log/myTestLog.txt
archivo. Algunas notas&>
es un bashismo , por lo que si el script se ejecuta a través de un shebang en la primera línea, debería serlo#!/bin/bash
, no solo/bin/sh
. Los "bashismos" solo funcionan en elbash
caparazón.Esto incluye
/etc/rc.local
, que por defecto utiliza/bin/sh
(es decir, sí, puede cambiar eso de forma segura/bin/bash
)./var/log
requiere privilegios de root para escribir. Si el proceso no lo tiene, use o cree un directorio que sepa que puede. En caso de duda, si puede probar esto sin tener que apagar o reiniciar el sistema, use/tmp
, que es de escritura mundial (es decir, por cualquier persona). Sin embargo/tmp
, no persiste a través de las botas. También es una pequeña partición basada en RAM, así que no le escribas datos. No es su tarjeta SD [en realidad en las versiones actuales de Raspbian, pero no cuente con esto en la práctica] .&>
sobrescribirá cualquier cosa enmyTestLog.txt
. Si, en cambio, desea agregar a un registro existente, lo que podría ser una buena idea para fines de depuración, use&>>
. Luego puede agregar un comando al comienzo de esa subshell como este:Para separar la información de cada ejecución. Si no está seguro de lo que hace, intente en la línea de comando.
Este último punto es una buena ilustración de algo que puede hacer con respecto a los comandos que no generan nada, pero la mayoría de ellos lo hacen si incluye, por ejemplo,
-v
"verbose". Cuidado con algunos comandos-v
significa "imprimir información de la versión". Eche un vistazo en la página de manual para el comando para asegurarse de si esto funcionará (y algunos comandos también usan un modificador diferente al-v
).Por convención, los comandos también devuelven un valor de 0 cuando se completa. Esto a veces se denomina "estado de salida" y normalmente no lo ve, pero el shell le mostrará con
echo $?
. TratarObtendrá 0 y 2. Si luego busca en la página de manual
ls
debajo de "Estado de salida", verá el críptico bastante inespecífico:Lo que puede o no ser mejor que nada, pero ahí lo tienes.
Como mínimo, esto indica que el comando falló por alguna razón. El estado de salida también le permite hacer cosas como esta:
En
&&
este caso, significa "si el primer comando tiene éxito", suponiendo que el primer comando utiliza la convención de devolver 0 (por lo que generalmente lo hacen). Si/bin/foo
no funciona, no se puede encontrar, etc.,sudo bar
nunca sucederá.El uso de una combinación de mensajes de registro y ejecución condicional (
&&
) debería acercarlo mucho más a resolver el problema, o al menos obtener información que podría ser útil para que otros lo ayuden a resolver el problema. Sin eso, lo más que cualquiera puede hacer es adivinar.1. Puede lograr la misma redirección de salida para un script completo desde adentro usando:
En la parte superior (o en cualquier lugar, y se aplicará a todo lo posterior).
fuente
Un aspecto importante que las personas tienden a olvidar cuando ejecutan scripts como daemons es el entorno de shell, y la
$PATH
variable en particular. En su ejemplo, la segunda línea se basa en$PATH
: el nombre completo desudo
is/usr/bin/sudo
, y su shell de usuario solo lo sabe porque le dijeron que buscara/usr/bin
cuando buscaba ejecutables. Lo mismo es cierto parabar
.Teniendo en cuenta que
sudo
no es necesario al ejecutar scripts como daemons, su segunda línea debería verse así:fuente