我有一个 shell 脚本用于每晚自动执行 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
答案1
正如 John 所提到的,这是您的脚本在两种环境中被不同地解释的问题(/bin/sh
在 下使用cron
,并使用您现有的 shell,这可能是/bin/bash
您直接将其引入时)。实际上,/bin/sh
通常只是 的符号链接/bin/bash
,并且 bash 可执行文件的行为根据调用它的名称而不同,但这只是题外话。
在这里,解决问题的最简单方法可能就是指定
/bin/bash /home/hookedonwinter/bin/auto_git_push.sh
作为在 cron 下运行的命令。
答案2
cron 环境对内联命令的解释与您的 shell 环境不同。我猜您的 shell 是 /bin/bash,这意味着它在与 cron 完全不同的 shell 中运行(“。” 构造将命令流读入 shell,它不会在 shebang 行中调用 shell)。我不确定您需要在 /bin/sh 中使用什么语法,但我会先尝试用简单的反引号代替 $( 和 )。一旦找到可行的东西,您就可以使用它,也可以继续寻找更符合您审美的东西。
答案3
这里有两种不同的 shell 在工作/bin/sh
。POSIXshell(基于 Bourne shell 的语法)。/bin/bash
是重回重生壳牌,又名 Bash。它符合 POSIX 标准,但添加了自己的语法等。根据您的系统设置,/bin/sh
可能是指向其他符合 POSIX 标准的 shell 的符号链接,例如短跑或者灰。重点是它期望POSIX shell 语法,无需 Bash 附加功能。
在 Bash 脚本中,可以使用function
保留字声明函数,这使得括号成为可选项。这意味着在 Bash 中,以下都是有效的函数声明:
function foo() { true; }
function bar { true; }
baz() { true; }
但根据 POSIX shell 语法,只有最后一个,baz() { true; }
是有效的。
根据你对这个问题选择的答案,你可以看到直接使用 调用脚本/bin/bash
将导致 Bash 解释你的脚本,没有任何问题。不过,为了将来参考,只在以 开头的脚本中使用 POSIX 语法#!/bin/sh
舍邦,并用于#!/bin/bash
包含 Bash 特定语法的脚本。