请找到下面的脚本
if [ "$#" -eq 0 ]; then
dbs=('test_db_1' 'test_db_2')
path='/var/backups/'
else
dbs=( "$@" )
path='/app/mybackups/'
fi
dbuser='test_user_name'
dbpassword='test_pass_word'
now="$(date +'%d-%m-%Y_%T')"
currentDate="$(date)"
dayToSubtract=365
cd ${path}
echo "location: $path"
for element in ${dbs[@]}
do
echo $element
echo "Starting backup now for db: $element on $now"
mongodump -u ${dbuser} -p ${dbpassword} --authenticationDatabase 'admin' -d $element --gzip --archive=${element}_$now.archive
dateToBeRemoved=$(date --date="${currentDate} -${dayToSubtract} day" +%d-%m-%Y)
echo $dateToBeRemoved
fileToBeRemoved="${element}_${dateToBeRemoved}"
echo Removing $fileToBeRemoved
rm $fileToBeRemoved*
done
echo All Done!
echo "location: $path"
我已经使用这个脚本一年多了,每天备份服务器上的数据库,并且我还使用它通过向该脚本传递命令行参数来进行手动备份。
最近我得到了一个新的服务器,有 ubuntu 并给出以下错误
daily.sh: 2: daily.sh: Syntax error: "(" unexpected (expecting "fi")
请参阅以下屏幕截图以供参考:
添加后:
#!/usr/bin/env bash
得到同样的错误:
运行which bash,得到以下内容
根据 bash 结果添加了 shebang 但仍然面临同样的问题
从当前文件夹运行时:
检查 BOM:
乌班图信息: 发行商 ID:Ubuntu 描述:Ubuntu 18.04.3 LTS 版本:18.04 代号:bionic
答案1
在脚本的第一行添加 shebang :(
来自评论)
#!/usr/bin/env bash
或者如果您知道路径。
#!/bin/bash
或者
#!/usr/bin/bash
无论它位于何处。
答案2
我将在下面留下旧的答案,因为它添加了上下文和细节。但我认为你的误解源于你认为sh yourscript
应该做的事情。
它的作用是使用sh
(正如您所注意到的,这因系统而异......)翻译员对于您传递的脚本名称。
你什么似乎不过,打算是
sh -c "your command ... whatever it is"
现在,为什么你坚持使用sh
as翻译员当您在评论和两个答案中完全被告知这是错误的时,我不知道。
如果你的脚本是可执行的,有一个正确的 hashbang,并且位于PATH
或使用其相对或绝对路径调用,它将工作。
但如果坚持使用sh
口译员,你基本上就是积极地破坏所有帮助您的尝试,因为sh
与 不同sh -c COMMAND
。如果你的解释器不是 Bash,那么使用 Bashism 可能会失败(正如你所见证的)。
如果您希望这种失败“更可靠”,您可以通过使用#!/bin/sh
hashbang(而不是建议的)来将其刻在石头上,这将产生与sh
在命令行上传递脚本相同的结果。
你这里有几个问题。您的屏幕截图显示您的脚本不可执行(由root:root
文件模式 0644 拥有)。因此,当您尝试使用它执行它时,sh
它将使用sh
您系统上恰好存在的任何 Shell。
失败的原因有三个:
- 您的脚本不可执行且不在
PATH
sh yourscript
使它 - 因为它不可执行 - 用作sh
解释器(在 Ubuntu 的情况下是dash
并且不理解所有 Bashisms)- 你的脚本缺少一个 hashbang,它为加载程序提供了使用哪个解释器来处理你的“二进制文件”的线索
但是,如果您添加一个 hashbang,例如:
#!/usr/bin/env bash
...如果您确保您的脚本不包含物料清单如果您确定它是可执行的:
chmod +x daily_ori.sh
...并使用相对路径(或将当前路径添加到PATH
,但是,这是一个坏主意!):
sh ./daily_ori.sh
... 这应该成功。除非您的问题缺少更多信息。
但最后一步确实让人质疑,sh
如果您的目的是调用 Bash,为什么您坚持首先执行脚本呢?只需使用 hashbang(无论是硬编码还是使用env
)来定位bash
解释器,确保脚本可执行并像平常一样调用它......
要检查 BOM 使用:
xxd -g 1 daily_ori.sh|head -n 2
...并将其编辑到您的问题中。