Мне любопытно, какова эта разница между программами; запускается с systemd при включении через systemctl, против тех, которые запускаются с помощью /etc/rc.local
или через CLI.
Например, недавно я использовал shairport-sync для Raspberry Pi. Изначально я установил запуск shairport-sync с помощью sudo systemctl с включенным shairport-sync.
Позже я использовал функциональность shairport-sync
для запуска сценариев и публикации сообщений для подключения к устройствам.
К моему удивлению, сценарии , когда выполняется shairport-sync
не kill
arecord
илиaplay
Тем не менее, когда я запускаю скрипт через терминал, скрипт выполняется и убивается arecord
и aplay
.
Чтобы еще больше запутать себя, я убил shairport-sync
и запустил его через терминал, чтобы увидеть вывод происходящего. Когда я это сделал, скрипты работали так, как я ожидал, когда устройство подключалось и отключалось arecord
и aplay
. Так что , как исправить я отключил shairport-sync
в sysmtectl
и установить его для работы в /etc/rc.local
качестве быстрого решения. После того, как reboot
он функционировал, как я ожидал.
Это наводит меня на мысль, что есть некоторая разница между программой, запускаемой отдельно, systemd
и программой, которая запускается при запуске через /etc/rc.local
CLI.
Почему это происходит? Это из-за разных уровней запуска? Немного темной магии?
Сценарий, который запускается при подключении устройства, shairport-sync
выглядит следующим образом:shairportstart.sh
#!/bin/sh
/usr/bin/sudo /bin/pkill arecord
if [ $(date +%H) -ge "18" -o $(date +%H) -le "7" ]; then
/usr/bin/amixer set Speaker 40%
else
/usr/bin/amixer set Speaker 100%
fi
/home/pi/shScripts/shairportfade.sh&
exit 0
Вот сценарий исчезновения: shairportfade.sh
#!/bin/sh
/usr/bin/amixer set Speaker 30-
for (( i=0; i<30; i++))
do
/usr/bin/amixer set Speaker 1+
done
exit 0
Сценарий, который запускается при отключении устройства, shairport-sync
выглядит следующим образом:shairportend.sh
#!/bin/sh
/usr/bin/amixer set Speaker 70%
/usr/bin/arecord -D plughw:1 -f dat | /usr/bin/aplay -D plughw:1 -f dat&
exit 0
Я обнаружил следующую ошибку /var/log/syslog
только в том случае, если shairport-sync изначально запускался отдельно systemd
. Когда shairport-sync
запускался из CLI или /etc/rc.local
ошибок не было.
Jan 24 00:38:45 raspberrypi shairport-sync[617]: sudo: no tty present and no askpass program specified
Обратите внимание, что единственная разница заключается в том, как shairport-sync
изначально запускается, когда устройства подключаются или отключаются, shairport-sync
продолжает работать.
источник
ps ... awk ... grep ...
материал может быть заменен более простымpkill
/home/pi/shScripts/shairportfade.sh
?rc.local
Ответы:
Вариации "Почему вещи ведут себя по-разному в systemd?" часто задаваемый вопрос
Каждый раз, когда что-то запускается из CLI, а не из systemd, есть несколько широких категорий возможностей для учета различий.
systemd
документирует переменные окружения, которые он передает, вman systemd.exec
разделе Переменные окружения в порожденных процессах . Если вы хотите проверить разницу самостоятельно, вы можете использовать ееsystemd-run /path/to/binary
, она будет запускать ваше приложение во временной области, как если бы оно выполнялось службой systemd. Вы получите выход , как:Running as unit: run-u160.service
. Затем вы можетеjournalctl -u run-u160.service
просмотреть вывод. Измените ваше приложение, чтобы выгрузить полученные переменные среды, и сравните запуск CLI с запуском systemd. Если приложение не было удобно модифицировано, вы можете просто использовать,systemd-run env
чтобы увидеть переменные среды, которые будут переданы, и просмотреть итоговую запись в журнале. Если вы пытаетесь запустить приложение X11 GUI,DISPLAY
необходимо установить переменную среды, В этом случае рассмотрите возможность использования функции автозапуска вашего рабочего стола вместоsystemd
.man systemd.resource-control
значения конфигурации, которые могут ограничить потребление ресурсов. Используйтеsystemctl show your-unit-unit.service
для проверки полных значений конфигурации, влияющих на службу, которую вы пытаетесь запустить.bash
среда CLI представляет собой интерактивную оболочку входа в систему . Он получил файлы, как.bashrc
этоsystemd
не имеет. Помимо установки переменных среды, эти сценарии могут выполнять множество других действий, таких как подключение агента SSH, чтобы действия SSH не требовали входа в систему. См. Также Разница между Оболочкой входа в систему и Оболочкой без регистрации?sudo
иssh
ожидают при запросе паролей. Смотрите также sudo: tty отсутствует и не задана программа askpassman systemd.service
указано в документе , первым аргументомExecStart=
должен быть абсолютный путь к двоичному файлу.systemd
командной строки оболочки поддерживают множество метасимволов, но имеют очень ограниченный синтаксис командной строки . В зависимости от ваших потребностей, вы сможете реплицировать синтаксис оболочки сsystemd
помощью явного запуска вашей команды через оболочку:ExecStart=/bin/bash -c '/my/bash $(syntax) >/goes-here.txt'
Это функция, которая запускает ваш код в согласованной среде с элементами управления ресурсами. Это помогает воспроизводить стабильные результаты в долгосрочной перспективе, не перегружая оборудование.
источник
sudo
сценарий оболочки, лучше запускаемыйsudo shairportstart.sh
из терминала, так как systemd запускает сценарий от имени пользователя root, нет необходимости использовать sudo от имени пользователя root./usr/bin/echo "mypassword" | /usr/bin/sudo /bin/pkill arecord
. Позже сегодня я попытаюсь удалить командыsudo
and изecho
моей команды kill и посмотреть, даст ли это те же результаты. Я предполагаю, что это будет работать, так как кажется, что ошибка была вызвана тем, что пароль не был отправлен сsudo
командой. Спасибо за помощь в понимании того, почему есть разница междуsystemd
CLI