2015-12-18 57 views
1

我有一個bash腳本,它將一堆命令放在一個文本文件中。然後將其cat的文件轉換爲sh來運行這些命令。我想要做的只是在目錄不存在的情況下運行命令。嘗試將管道命令轉換爲if語句

下面是我:像這樣的東西

的文本文件:

mkdir /path/to/a/directory 
mkdir /path/to/another/directory 
mkdir /path/to/yet/another/directory 

在我的劇本我有這樣

cat /path/to/my/file.txt | sh 

線,但有什麼辦法做這樣的事情?

cat /path/to/my/file.txt | if path already exists then go to the next, if not | sh 

換句話說,我想跳過企圖使目錄,如果路徑已經存在。

+2

無法將命令輸入到「if」中。你的項目聽起來過於雄心勃勃。獲得更簡單的版本,並確定它是否真的值得重建shell腳本範例;-)。對於dir存在的傳統測試是'if! [[-d「$ dir」]];那麼mkdir -p「$ dir」; fi'。祝你好運。 – shellter

+0

問題不是你不能通過管道傳遞一個'if'語句(你可以),這就是你真的需要一個循環。 – chepner

+0

@chepner:你*可以*管道到'if'語句!?酷,你可以在這裏作爲評論給出一個1/2內膽的例子嗎?謝謝 – shellter

回答

1

我不是,如果你想檢查文件或目錄的存在..清楚,但這裏是如何把它:

運行命令的文件是否存在:

[ -f /path/to/my/file.txt ] && cat /path/to/my/file.txt | sh 

或檢查目錄:

[ -d /path/to/my/directory ] && cat /path/to/my/file.txt | sh 
+0

這是最有幫助的。我實際上是這樣使用的: '[-d/path/to/dir] || mkdir/path/to/dir' 同樣,如上所述,我實際上並沒有使用mkdir,但是我能夠合併這個答案,並且我使用'||'而不是'&&',因爲我只希望它運行如果路徑不存在。 謝謝! – VanCityGuy

3

更新:該OP自澄清,使用mkdir只是一個例子,而他需要一個通用機制,有條件地從一個文本文件,其中包含shell命令,根據命令是否指的是現有目錄或不執行行:

while read -r cmd dir; do [[ -d $dir ]] || eval "$cmd $path"; done < /path/to/my/file.txt 
  • while循環讀取包含文本文件shell命令一行一行。
  • read -r cmd dir將每一行解析爲第一個標記 - 假定爲命令(示例輸入中的mkdir) - 其餘的,假定爲目錄路徑。
  • [[ -d $dir ]]測試目錄路徑的存在,並且只有||如果測試失敗,即執行其RHS,如果該目錄不存在
  • eval "$cmd $path"然後執行該行;注意在這裏使用eval的安全性不如管道到sh安全 - 在這兩種情況下,您都必須信任代表命令的字符串。 (從當前的Bash shell使用eval意味着Bash將執行該命令,而不是sh,但我認爲這不是問題。)

原來的答覆,基於該mkdir實際使用的假設:

你的情況,最簡單的方法是將-p選項添加到您的mkdir調用,這會悄悄地忽略嘗試創建一個已經存在的目錄:

mkdir -p /path/to/a/directory 
mkdir -p /path/to/another/directory 
mkdir -p /path/to/yet/another/directory 

換句話說:mkdir -p確保存在目標目錄,不管該目錄是否存在。已經存在或必須創建。 (mkdir -p仍然可能失敗,例如當目標路徑是文件,而不是一個目錄,或者如果你沒有足夠的權限來創建目錄。)

然後,您可以簡單地將文件傳遞給sh(無需cat和管道,這是低效率):

sh /path/to/my/file.txt  

如果你不控制輸入文件的創建,您可以使用sed插入-p選項:

sed 's/^mkdir /&-p /' /path/to/my/file.txt | sh 
+0

非常感謝你,這很好理解,但我實際上並沒有使用mkdir,我使用的另一個腳本基本上是作爲mkdir運行的,但在我們的內部網絡上工作。該腳本可悲的是沒有-p標誌,但這又是對未來有用的信息! – VanCityGuy

+1

@VanCityGuy:我很高興你找到了解決方案,我的答案仍然有幫助。將來,請從頭說明所有約束條件,以及樣本輸入的哪些方面是偶然的。我在我的答案頂部添加了一個通用解決方案,希望能夠涵蓋您的用例。 – mklement0

0

編寫您自己的mkdir函數。

假設你的文件沒有在任何地方使用mkdir -p這應該工作。

mkdir() { 
    for dir; do 
     [ -d "$dir" ] || mkdir "$dir" 
    done 
} 
export -f mkdir 

sh < file 
+0

謝謝你的建議,但它稍微超出了我。看起來很有趣,但我必須做一些研究來編寫我自己的功能,這可能對其他項目非常有用。 謝謝! – VanCityGuy