1

У меня есть сценарий оболочки для автоматизации git commit и push каждую ночь:

auto_git_push.sh

#!/bin/sh

function automate(){
    git add .
    git commit -am "automated push $(date +"%Y-%m-%d")"
    git push -u
}

cd ~/htdocs
automate

Если я запускаю эту команду, скрипт работает , как . ~/bin/auto_git_push.sh

Тем не менее, с этой строкой crontab (устанавливается на каждую минуту для тестирования)

* * * * * sh /home/hookedonwinter/bin/auto_git_push.sh

Я получаю следующую ошибку:

/home/hookedonwinter/bin/auto_git_push.sh: 3: Syntax error: "(" unexpected

Что вызывает эту синтаксическую ошибку?

Спасибо!

Редактировать на основе принятого ответа:

Изменен скрипт на:

#!/bin/bash

automate() {
    git add .
    git commit -am "automated push $(date +"%Y-%m-%d")"
    git push -u
}

cd ~/htdocs
automate

И строка crontab для:

* * * * * /bin/bash /home/hookedonwinter/bin/auto_git_push.sh

3 ответа3

3

Как упоминал Джон, дело в том, что ваш скрипт интерпретируется по-разному в двух средах (использование /bin/sh в cron и использование вашей существующей оболочки, которая, вероятно, /bin/bash когда вы вводите ее напрямую). На самом деле, /bin/sh - это просто символическая ссылка на /bin/bash , и исполняемый файл bash ведет себя по-разному в зависимости от имени, под которым он был вызван, но это всего лишь отступление.

Здесь самый простой способ исправить вашу проблему, вероятно, просто указать

/bin/bash /home/hookedonwinter/bin/auto_git_push.sh

как команда для запуска под cron.

2

Среда cron интерпретирует встроенную команду иначе, чем ваша оболочка. Я предполагаю, что ваша оболочка - /bin /bash, что означает, что она работает в другой оболочке полностью, чем в cron (конструкция "." Считывает поток команд в оболочку, она не вызывает оболочку в shebang линия). Я не уверен, какой синтаксис вам нужен в /bin /sh, но я бы начал с простых обратных галочек вместо $ (и). Как только вы найдете то, что работает, вы можете использовать его или продолжить поиск чего-то более привлекательного для вашей эстетики.

1

Здесь работают 2 разных снаряда. /bin/sh - это оболочка POSIX (синтаксис основан на оболочке Bourne). /bin/bash - это оболочка Bourne Again, она же Bash. Он совместим с POSIX, но помимо всего прочего добавляет собственный синтаксис. В зависимости от настроек вашей системы, /bin/sh может быть символической ссылкой на какую-либо другую POSIX-совместимую оболочку, такую как dash или ash. Важным моментом является то, что он ожидает синтаксис оболочки POSIX без дополнений Bash.

В сценариях Bash функции могут быть объявлены с помощью зарезервированного слова function , что делает скобки необязательными. Это означает, что в Bash все следующие допустимые объявления функций:

function foo() { true; }
function bar { true; }
baz() { true; }

Но в соответствии с синтаксисом оболочки POSIX, только последний, baz() { true; } , действительно.

Основываясь на ответе, который вы выбрали на этот вопрос, вы можете увидеть, что вызов сценария напрямую с помощью /bin/bash заставит Bash интерпретировать ваш сценарий без проблем. Однако для дальнейшего использования используйте синтаксис POSIX только в сценариях, начинающихся с #!/bin/sh shebang, и используйте #!/bin/bash для скриптов, которые содержат специфичный для Bash синтаксис.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .