У меня есть короткий скрипт, который выполняется системным демоном для определенных событий. Я знаю, что событие происходит, и сценарий выполняется, но он не выполняет то, что я намереваюсь. Странно, но когда я запускаю его вручную, я очень растерялся.
Как я могу понять, что происходит? Сценарий в основном представляет собой серию команд вроде этой:
/bin/foo on 3
sudo bar a
U&L
. Я неправильно прочитал заголовок и предложил бы «Записать выходные данные системного скрипта для отладки», чтобы сделать цель более понятной. Также мой мозг замирает, когда я читаю этиfoo
bar
примеры, я предпочитаю что-то, что выглядит более реальным миром. Я не хочу редактировать любой пост, поэтому оставлю это вам, если вы думаете, что это можно улучшить.Ответы:
Во-первых, если скрипт запускается системным демоном и этот демон работает с привилегиями root, вам не нужно его использовать
sudo
. Это включает в себяinit
(иsystemd
), который включает в себяrc.local
. Если этот демон не запущен с привилегиями root, онsudo
не будет работать, если/etc/sudoers
не настроен на это (и без пароля). Пользователи Raspbian могут быть смущены этим, так какpi
пользователю разрешено делать что-либо по умолчанию (и если вы заглянете внутрь,/etc/sudoers
вы увидите, как это достигается).Затем вы можете захватить выходные данные из любого
bash
скрипта или любого набора команд внутри скрипта bash, выполнив их в подоболочке следующим образом: 1()
Указывает подоболочку . Все выходные данные из этого объекта перенаправляются в/var/log/myTestLog.txt
файл. Несколько заметок:&>
это башизм , так что если скрипт выполняется с помощью шебанга в первой строке, это должно быть#!/bin/bash
не просто так/bin/sh
. «Башизмы» работают только вbash
оболочке.Это включает в себя то
/etc/rc.local
, что по умолчанию использует/bin/sh
(то есть, да, вы можете смело изменить это на/bin/bash
)./var/log
требует прав суперпользователя для записи. Если процесс не имеет такого, используйте или создайте каталог, который, как вы знаете, может. Если вы сомневаетесь, если вы можете проверить это без необходимости выключения или перезагрузки системы, используйте команду,/tmp
доступную для записи всем пользователям (т.е. кому угодно). Однако/tmp
не сохраняется через сапоги. Это также небольшой раздел на основе ОЗУ, поэтому не записывайте в него данные. Это не ваша SD-карта [на самом деле это в текущих версиях Raspbian, но на практике не рассчитывайте] .&>
перезапишет что-нибудь вmyTestLog.txt
. Если вместо этого вы хотите добавить к существующему журналу, который может быть хорошей идеей для целей отладки, используйте&>>
. Затем вы можете добавить команду в начало этой подоболочки следующим образом:Чтобы отделить информацию от каждого запуска. Если вы не уверены, что это делает, попробуйте в командной строке.
Этот последний пункт является хорошей иллюстрацией того, что вы можете сделать в отношении команд, которые ничего не выводят, но большинство из них делают, если вы включите, например,
-v
«verbose». Осторожно, некоторые команды-v
означают «информация о версии печати». Загляните на страницу man для команды, чтобы убедиться, что и как это будет работать (некоторые команды также используют другой ключ, чем-v
).По соглашению команды также возвращают значение 0 после завершения. Это иногда называется «статусом выхода», и вы обычно его не видите, но оболочка покажет вам
echo $?
. ПытатьсяВы получите 0 и 2. Если вы затем заглянете на страницу
ls
руководства в разделе «Статус выхода», вы увидите довольно неопределенное, загадочное:Который может или не может быть лучше, чем ничего, но вы идете.
По крайней мере, это означает, что по какой-то причине команда не выполнена. Статус выхода также позволяет вам делать такие вещи:
В
&&
этом случае означает «если первая команда выполнена успешно», предполагая, что первая команда использует соглашение о возврате 0 (именно поэтому они обычно делают). Если/bin/foo
не работает, не может быть найден и т. Д.,sudo bar
То никогда не произойдет.Использование комбинации сообщений регистрации и условного выполнения (
&&
) должно значительно приблизить вас к выяснению проблемы или, по крайней мере, к получению информации, которая может быть полезна другим для решения проблемы. Без этого чаще всего можно догадаться.1. Вы можете выполнить одно и то же перенаправление вывода для всего скрипта изнутри, используя:
Вверху (или где угодно, и это будет применяться ко всему последующему).
источник
Один важный аспект, который люди обычно забывают при запуске сценариев в качестве демонов, это среда оболочки и,
$PATH
в частности , переменная. В вашем примере вторая строка опирается на$PATH
: полное имяsudo
is/usr/bin/sudo
, а ваша пользовательская оболочка знает это только потому, что ей было приказано искать/usr/bin
при поиске исполняемых файлов. То же самое верно дляbar
.Учитывая, что
sudo
это не нужно при запуске сценариев как демонов, ваша вторая строка должна выглядеть так:источник