Salida de registro de fondo o script de arranque

10

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
Ricitos de oro
fuente
Entiendo que esto pretende ser un tutorial sobre la depuración de los scripts del sistema, pero también es un poco 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 estos foo barejemplos, 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.
Milliways
1
@Milliways Tienes razón, "script de sistema" era un nombre inapropiado de todos modos, así que he cambiado el título. No estoy de acuerdo con la cuestión de los foobar: las personas deben aprender a reconocer la jerga / coloquialismos comunes como lo harían en cualquier cultura. Además, sigue siendo una buena risa una vez que los unes.
Ricitos de oro

Respuestas:

8

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 incluye init(y systemd), que incluye rc.local. Si ese demonio no se ejecuta con privilegios de root, sudono funcionará a menos que /etc/sudoersesté configurado para permitirlo (y sin una contraseña). Esto puede confundir a los usuarios de Raspbian, ya que el piusuario 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 bashscript, o cualquier conjunto de comandos dentro de un script bash, ejecutándolos en un subshell como este: 1

(
    /bin/foo on 3
    sudo bar a
) &> /var/log/myTestLog.txt

El ()indica una subshell . Toda la salida de cualquier cosa dentro de esto se redirige a un /var/log/myTestLog.txtarchivo. 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 el bashcaparazón.

    Esto incluye /etc/rc.local, que por defecto utiliza /bin/sh(es decir, sí, puede cambiar eso de forma segura /bin/bash).

  • /var/logrequiere 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 en myTestLog.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:

    echo Starting $(date)

    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 -vsignifica "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 $?. Tratar

 ls /
 echo $?
 ls /nonexistantdir
 echo $?

Obtendrá 0 y 2. Si luego busca en la página de manual lsdebajo de "Estado de salida", verá el críptico bastante inespecífico:

2      if serious trouble (e.g., cannot access command-line argument).

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:

/bin/foo && sudo bar

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/foono funciona, no se puede encontrar, etc., sudo barnunca 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:

exec &> /var/log/myTestLog.txt

En la parte superior (o en cualquier lugar, y se aplicará a todo lo posterior).

Ricitos de oro
fuente
2

Un aspecto importante que las personas tienden a olvidar cuando ejecutan scripts como daemons es el entorno de shell, y la $PATHvariable en particular. En su ejemplo, la segunda línea se basa en $PATH: el nombre completo de sudois /usr/bin/sudo, y su shell de usuario solo lo sabe porque le dijeron que buscara /usr/bincuando buscaba ejecutables. Lo mismo es cierto para bar.

Teniendo en cuenta que sudono es necesario al ejecutar scripts como daemons, su segunda línea debería verse así:

/path/to/bar a
Dmitry Grigoryev
fuente