Shebang не устанавливает SHELL в cron

У меня есть сценарий, содержащий:

#!/bin/bash printenv 

Когда я запускаю его из командной строки:

 env testscript.sh bash testscript.sh sh testscript.sh 

каждый раз он выводит SHELL=/bin/bash . Однако, когда он запускается из cron, он всегда выводит SHELL=/bin/sh . Почему это? Как я могу сделать cron применить shebang?

Я уже проверил cron PATH; он включает / bin.

Шебанг работает, и cron не имеет к этому никакого отношения. Когда файл выполняется, если содержимое этого файла начинается с #! , ядро ​​выполняет файл, указанный в #! и передает его исходный файл в качестве аргумента.

Ваша проблема в том, что вы, кажется, полагаете, что SHELL в сценарии оболочки отражает оболочку, выполняющую скрипт. Это не тот случай. Фактически, в большинстве контекстов SHELL означает предпочтительную интерактивную оболочку пользователя, она предназначена для приложений, таких как эмулятор терминала, для принятия решения о том, какую оболочку выполнить. В cron SHELL – это переменная, которая сообщает cron, какую программу использовать для запуска записей crontab (часть строк после указания времени).

Оболочки не устанавливают переменную SHELL если она не установлена ​​при запуске.

Тот факт, что SHELL /bin/sh вероятно, не имеет значения. В вашем скрипте есть строка #!/bin/bash , поэтому он выполняется bash. Если вы хотите убедить себя, добавьте ps $$ в скрипт, чтобы сделать ps показать информацию о оболочке, выполняющей скрипт.

В справочном руководстве Bash говорится:

SHELL – полное имя пути к оболочке хранится в этой переменной среды. Если он не установлен при запуске оболочки, Bash назначает ему полный путь к оболочке входа текущего пользователя.

man 5 crontab говорит:

Несколько параметров среды автоматически создаются демоном cron (8). SHELL установлен в / bin / sh, а LOGNAME и HOME установлены из строки / etc / passwd владельца crontab. Для параметра PATH установлено значение «/ usr / bin: / bin». HOME, SHELL и PATH могут быть переопределены настройками в crontab

Поэтому переменная SHELL устанавливается при запуске Bash.

Попробуйте SHELL=/bin/awesome/shell bash testcript.sh . Вы должны увидеть SHELL=/bin/awesome/shell

Шебанг работает. У вас есть документальное поведение 🙂

Измените shebang на

 #!/bin/env bash 

Или выполните crontab -e чтобы сценарий работал со своими собственными переменными среды, поскольку собственные cron разные.


Как примечание, в соответствии с этим сообщением на askubuntu , вам нужно дать вашему cron PATH в верхней части скрипта:

 PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin # rest of script follows 

Однако, учитывая, что вы сказали, что PATH, похоже, имеет правильные каталоги поиска, вы можете это исключить.