Журнал вывода фона или загрузочного скрипта

10

У меня есть короткий скрипт, который выполняется системным демоном для определенных событий. Я знаю, что событие происходит, и сценарий выполняется, но он не выполняет то, что я намереваюсь. Странно, но когда я запускаю его вручную, я очень растерялся.

Как я могу понять, что происходит? Сценарий в основном представляет собой серию команд вроде этой:

/bin/foo on 3
sudo bar a
Златовласка
источник
Я понимаю, что это учебник по отладке системных скриптов, но тоже немного U&L. Я неправильно прочитал заголовок и предложил бы «Записать выходные данные системного скрипта для отладки», чтобы сделать цель более понятной. Также мой мозг замирает, когда я читаю эти foo barпримеры, я предпочитаю что-то, что выглядит более реальным миром. Я не хочу редактировать любой пост, поэтому оставлю это вам, если вы думаете, что это можно улучшить.
Milliways
1
@Milliways Вы правы, системный скрипт в любом случае был неправильным, поэтому я изменил название. Я не согласен с вещью foobar - люди должны научиться распознавать общепринятые языковые / разговорные выражения, как в любой культуре. Кроме того, это все еще хороший хихиканье, когда вы соединяете их вместе.
Златовласка

Ответы:

8

Во-первых, если скрипт запускается системным демоном и этот демон работает с привилегиями root, вам не нужно его использовать sudo. Это включает в себя initsystemd), который включает в себя rc.local. Если этот демон не запущен с привилегиями root, он sudoне будет работать, если /etc/sudoersне настроен на это (и без пароля). Пользователи Raspbian могут быть смущены этим, так как piпользователю разрешено делать что-либо по умолчанию (и если вы заглянете внутрь, /etc/sudoersвы увидите, как это достигается).

Затем вы можете захватить выходные данные из любого bashскрипта или любого набора команд внутри скрипта bash, выполнив их в подоболочке следующим образом: 1

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

()Указывает подоболочку . Все выходные данные из этого объекта перенаправляются в /var/log/myTestLog.txtфайл. Несколько заметок:

  • &>это башизм , так что если скрипт выполняется с помощью шебанга в первой строке, это должно быть #!/bin/bashне просто так /bin/sh. «Башизмы» работают только в bashоболочке.

    Это включает в себя то /etc/rc.local, что по умолчанию использует /bin/sh(то есть, да, вы можете смело изменить это на /bin/bash).

  • /var/logтребует прав суперпользователя для записи. Если процесс не имеет такого, используйте или создайте каталог, который, как вы знаете, может. Если вы сомневаетесь, если вы можете проверить это без необходимости выключения или перезагрузки системы, используйте команду, /tmpдоступную для записи всем пользователям (т.е. кому угодно). Однако /tmpне сохраняется через сапоги. Это также небольшой раздел на основе ОЗУ, поэтому не записывайте в него данные. Это не ваша SD-карта [на самом деле это в текущих версиях Raspbian, но на практике не рассчитывайте] .

  • &>перезапишет что-нибудь в myTestLog.txt. Если вместо этого вы хотите добавить к существующему журналу, который может быть хорошей идеей для целей отладки, используйте &>>. Затем вы можете добавить команду в начало этой подоболочки следующим образом:

    echo Starting $(date)

    Чтобы отделить информацию от каждого запуска. Если вы не уверены, что это делает, попробуйте в командной строке.

Этот последний пункт является хорошей иллюстрацией того, что вы можете сделать в отношении команд, которые ничего не выводят, но большинство из них делают, если вы включите, например, -v«verbose». Осторожно, некоторые команды -vозначают «информация о версии печати». Загляните на страницу man для команды, чтобы убедиться, что и как это будет работать (некоторые команды также используют другой ключ, чем -v).

По соглашению команды также возвращают значение 0 после завершения. Это иногда называется «статусом выхода», и вы обычно его не видите, но оболочка покажет вам echo $?. Пытаться

 ls /
 echo $?
 ls /nonexistantdir
 echo $?

Вы получите 0 и 2. Если вы затем заглянете на страницу lsруководства в разделе «Статус выхода», вы увидите довольно неопределенное, загадочное:

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

Который может или не может быть лучше, чем ничего, но вы идете.

По крайней мере, это означает, что по какой-то причине команда не выполнена. Статус выхода также позволяет вам делать такие вещи:

/bin/foo && sudo bar

В &&этом случае означает «если первая команда выполнена успешно», предполагая, что первая команда использует соглашение о возврате 0 (именно поэтому они обычно делают). Если /bin/fooне работает, не может быть найден и т. Д., sudo barТо никогда не произойдет.

Использование комбинации сообщений регистрации и условного выполнения ( &&) должно значительно приблизить вас к выяснению проблемы или, по крайней мере, к получению информации, которая может быть полезна другим для решения проблемы. Без этого чаще всего можно догадаться.


1. Вы можете выполнить одно и то же перенаправление вывода для всего скрипта изнутри, используя:

exec &> /var/log/myTestLog.txt

Вверху (или где угодно, и это будет применяться ко всему последующему).

Златовласка
источник
2

Один важный аспект, который люди обычно забывают при запуске сценариев в качестве демонов, это среда оболочки и, $PATHв частности , переменная. В вашем примере вторая строка опирается на $PATH: полное имя sudois /usr/bin/sudo, а ваша пользовательская оболочка знает это только потому, что ей было приказано искать /usr/binпри поиске исполняемых файлов. То же самое верно для bar.

Учитывая, что sudoэто не нужно при запуске сценариев как демонов, ваша вторая строка должна выглядеть так:

/path/to/bar a
Дмитрий Григорьев
источник