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
得到同樣的錯誤:
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
作為解釋器,您基本上是在積極破壞所有幫助您的嘗試,因為sh
與sh -c COMMAND
. 如果你的解釋器不是 Bash,使用 Bashisms 可能會失敗(正如你所見證的)。如果您希望這種失敗“更可靠”,您可以使用
#!/bin/sh
hashbang(而不是建議的)將其刻在石頭上,這將產生與將腳本交給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(無論是硬編碼還是 withenv
)來定位bash
為解釋器,確保腳本是可執行的並像往常一樣呼叫它……要檢查 BOM,請使用:
xxd -g 1 daily_ori.sh|head -n 2
…並將其編輯到您的問題中。
在腳本的第一行添加 shebang :(
來自評論)
#!/usr/bin/env bash
或者,如果您知道路徑。
#!/bin/bash
或者
#!/usr/bin/bash
無論它位於何處。