Вопрос или проблема
Этот test.sh
скрипт:
cd test-1
source .venv/bin/activate
python test.py
deactivate
работает нормально из терминала на Ubuntu 20.04.6 с этой командой:
nick@jetson:~$ ./test.sh
Когда я добавляю его в параметры автозагрузки с:
он не запускается. В чем проблема?
Этот вопрос отличается от Как автоматически запускать приложения при входе в систему?. Я не спрашиваю, как автоматически запускать приложения при входе в систему. Я спрашиваю, почему для Command
в Add Startup program
нужно использовать другую команду, чем ту, которую я ввожу в терминале в папке ~
.
Этот вопрос отличается от Как автоматически запускать приложения при входе в систему?. Я не спрашиваю, как автоматически запускать приложения при входе в систему. Я спрашиваю, почему для
Command
вAdd Startup program
нужно использовать другую команду, чем ту, которую я ввожу в терминале в папке~
.
Когда вы создаете “Приложение автозагрузки”, что происходит под капотом:
- Создается файл .desktop в
~/.config/autostart
, содержащий строкуExec
, которая содержит “команду”, которую вы указали; - При запуске сессии файл рабочего стола разбирается и оценивается в соответствии с спецификациями Freedesktop.
Цитируя соответствующий раздел со страницы (выделение мое):
Ключ Exec должен содержать командную строку. Командная строка состоит из исполняемой программы, за которой при желании следуют один или несколько аргументов. Исполняемая программа может быть указана либо с полным путем, либо только по имени исполняемого файла. Если полный путь не предоставлен, исполняемый файл ищется в $PATH, используемом средой рабочего стола. Имя или путь исполняемой программы не могут содержать знак равенства (“=”). Аргументы разделяются пробелом.
Таким образом, причина, по которой ./test.sh
не работает, проста: он не соответствует ни одной из спецификаций Freedesktop, так как это не полный путь и не имя исполняемого файла.
Также обратите внимание, что есть и другие правила, которым должна подчиняться “команда” (вы можете найти их на странице, на которую я ссылаюсь), но прохождение этих проверок обычно помогает:
- Если вам нужно запустить что-то, что не находится в
PATH
, вы должны указать полный путь, иначе можете просто указать bare имя исполняемого файла; - Вы не можете использовать оболочечные конструкции (переменные, алиасы, функции, переадресации, конвейеры и т. д.). Переменные могут быть вставлены в окружение исполняемой программы с помощью
env
(env foo=bar executable
). Если вам нужно что-то большее, вы, как правило, можете использоватьsh -c
/bash -c
(sh -c '<input command1 | command2'
), или создать обертку-скрипт вокруг вашего фактического скрипта.
Если у вашего скрипта действительно нет шебанга (#!/bin/bash
), одним из решений будет запустить:
bash /home/ваше_имя_пользователя/test.sh
вместо этого. Однако “правильное” решение будет добавить шебанг в скрипт и запустить просто:
/home/ваше_имя_пользователя/test.sh
Шебанг необходим в других контекстах (например, при запуске скрипта из оболочки, отличной от Bash), чтобы использовать функции Bash, такие как, например, source
, когда скрипт запускается из sh
.
Ответ или решение
Ваш скрипт test.sh
не запускается при старте системы по нескольким причинам, связанных с нюансами работы среды рабочего стола и спецификаций Freedesktop. Давайте подробно рассмотрим все вероятные факторы, которые могут повлиять на запуск.
1. Неправильный путь к исполняемому файлу
Когда вы добавляете скрипт в «Запуск приложений», система ожидает, что вы укажете либо полный путь к исполняемому файлу, либо его имя, находящееся в $PATH
. Если вы указали просто ./test.sh
, операционная система не сможет найти данный файл, так как текущая директория (откуда должно выполняться выполнение) не будет определена при запуске из автозагрузки.
Решение
Убедитесь, что вы указываете полный путь к вашему скрипту:
/home/your_username/test.sh
2. Отсутствие шебанга (shebang)
Шебанг — это строка, которая указывает интерпретатору, каким образом исполнять файл. Если в вашем скрипте не указан шебанг, система может не понимать, как его запускать, особенно если выполняется в другой оболочке, которая не поддерживает специфические команды Bash, такие как source
.
Решение
В начале файла test.sh
добавьте следующую строку:
#!/bin/bash
Это обеспечит запуск вашего скрипта именно с помощью Bash, что важно для правильной обработки команд внутри скрипта.
3. Условия среды выполнения
При запуске через «Запуск приложений» окружение может сильно отличаться от терминального. Переменные сред, такие как $PATH
и другие, могут быть настроены иначе. Это может влиять на поведение команды source
, если .venv/bin/activate
не может быть найден. Также переменные окружения могут отсутствовать или отличаться от тех, что у вас в интерактивной сессии терминала.
Решение
Можно явно установить переменные окружения внутри вашего скрипта или сделать обертку с использованием env
:
#!/bin/bash
cd /path/to/test-1
source /path/to/.venv/bin/activate
python /path/to/test.py
deactivate
Также может быть полезным использовать env
:
#!/bin/bash
env /bin/bash -c 'cd /path/to/test-1 && source .venv/bin/activate && python test.py && deactivate'
4. Логи выполнения
Иногда бывает полезно логировать вывод вашего скрипта, чтобы видеть, что происходит при запуске. Для этого можно использовать перенаправление вывода:
/home/your_username/test.sh >> /home/your_username/test.log 2>&1
Это позволит вам отслеживать все ошибки, которые могут возникнуть при выполнении скрипта.
Заключение
Итак, чтобы ваш скрипт test.sh
корректно запускался при старте системы, выполните следующие действия:
- Убедитесь, что вы используете полный путь к скрипту.
- Добавьте шебанг в начало вашего скрипта.
- Убедитесь, что все пути в скрипте прописаны правильно и соответствуют текущему окружению.
- Рассмотрите ведение логов для отладки проблем.
Следуя этим рекомендациям, вы сможете успешно запускать ваш скрипт при старте системы.