Bash

Bash 腳本在 Centos 7 上執行良好,在 Ubuntu Bionic 上異常

  • May 19, 2020

請在下面找到腳本

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

在此處輸入圖像描述

得到同樣的錯誤:

在此處輸入圖像描述

Ran which bash,得到了以下

在此處輸入圖像描述

根據哪個bash結果添加了shebang,但仍然面臨同樣的問題 在此處輸入圖像描述

從目前文件夾執行時:

在此處輸入圖像描述

檢查物料清單:

在此處輸入圖像描述

Ubuntu 資訊: 發行商 ID:Ubuntu 描述:Ubuntu 18.04.3 LTS 版本:18.04 代號:仿生

我將在下面留下舊答案,因為它增加了上下文和細節。但我認為你的誤解源於你認為sh yourscript應該做的事情。

它的作用是使用sh(如您所注意到的那樣因係統而異……)作為您傳遞的腳本名稱的解釋器。

但是,您似乎打算是

sh -c "your command ... whatever it is"

現在,我不知道,當您在評論和兩個答案中完全被告知這是錯誤的時,為什麼還要堅持使用sh口譯員。

如果您的腳本是可執行的,具有適當的 hashbang,並且位於PATH或使用其相對或絕對路徑呼叫,它將工作

但是通過堅持使用sh作為解釋器,您基本上是在積極破壞所有幫助您的嘗試,因為shsh -c COMMAND. 如果你的解釋器不是 Bash,使用 Bashisms 可能會失敗(正如你所見證的)。

如果您希望這種失敗“更可靠”,您可以使用#!/bin/shhashbang(而不是建議的)將其刻在石頭上,這將產生與將腳本交給sh命令行相同的結果。


你在這裡有幾個問題。您的螢幕截圖顯示您的腳本不可執行(由root:root文件模式 0644 擁有)。因此,當您嘗試使用它執行它時sh,它將使用sh您系統上碰巧出現的任何 Shell。

失敗的原因有三個:

  • 您的腳本不可執行且不在PATH
  • sh yourscript使它 - 因為它不是可執行的 -sh用作解釋器(在 Ubuntu 的情況下是dash並且不理解所有 Bashisms)
  • 您的腳本缺少一個 hashbang,它為載入程序提供了用於您的“二進制”的解釋器的線索

但是,如果您要添加一個 hashbang,例如:

#!/usr/bin/env bash 

…如果您確保您的腳本不包含BOM並且您確保它是可執行的:

chmod +x daily_ori.sh

…並使用了相對路徑(或將目前路徑添加到PATH,但這是一個壞主意!):

sh ./daily_ori.sh

…這應該成功。除非您的問題缺少更多資訊。

但是,如果您的意圖是呼叫 Bash,那麼最後一步確實讓人質疑為什麼您堅持sh首先執行腳本。只需使用 hashbang(無論是硬編碼還是 with env)來定位bash為解釋器,確保腳本是可執行的並像往常一樣呼叫它……


要檢查 BOM,請使用:

xxd -g 1 daily_ori.sh|head -n 2

…並將其編輯到您的問題中。

在腳本的第一行添加 shebang :(

來自評論)

#!/usr/bin/env bash 

或者,如果您知道路徑。

#!/bin/bash

或者

#!/usr/bin/bash

無論它位於何處。

引用自:https://unix.stackexchange.com/questions/587645