Shell脚本直接运行,但通过crontab出现语法错误

Shell脚本直接运行,但通过crontab出现语法错误

我有一个 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/shPOSIXshell(基于 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 特定语法的脚本。

相关内容