Bash 脚本在 Centos 7 上运行完美,但在 Ubuntu Bionic 上出现异常

Bash 脚本在 Centos 7 上运行完美,但在 Ubuntu Bionic 上出现异常

请找到下面的脚本

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"

现在,为什么你坚持使用shas翻译员当您在评论和两个答案中完全被告知这是错误的时,我不知道。

如果你的脚本是可执行的,有一个正确的 hashbang,并且位于PATH或使用其相对或绝对路径调用,它将工作

但如果坚持使用sh口译员,你基本上就是积极地破坏所有帮助您的尝试,因为sh与 不同sh -c COMMAND。如果你的解释器不是 Bash,那么使用 Bashism 可能会失败(正如你所见证的)。

如果您希望这种失败“更可靠”,您可以通过使用#!/bin/shhashbang(而不是建议的)来将其刻在石头上,这将产生与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

...并将其编辑到您的问题中。

相关内容