2017-11-11 270 views
0

mkdir $ 2 ||回聲「我無法創建目錄$ 2」 & &出口8「mkdir || echo && exit」即使mkdir成功退出

大家好,這是我在這裏的第一篇文章,所以要善良。

我正在製作一個腳本,現在這條線困擾着我。

只有在無法創建目錄$ 2時纔會出現8號出口。 運行腳本併成功創建該目錄後,它仍然在8上退出。

我錯過了什麼嗎?我認爲只有在左側出現錯誤時,「||」後面的命令纔會發生。

我是Linux界的新手,作爲一個具有中小C經驗的人,我很困惑,幫忙! (使用Ubuntu,慶典,順便說一句)

+2

我認爲這是因爲運營商的優先。你可以放圓括號。如果mkdir失敗,則執行echo並返回true,以便執行第三個命令。也許你可以使用括號 – fernand0

+2

他是來自Unix和Linux SE的答案:https://unix.stackexchange.com/questions/88850/precedence-of-the-shell-logical-operators –

回答

4

正如@ fernand0建議,問題是||&&符的優先級。您希望它運行類似mkdir || (echo && exit)的東西 - 即,如果mkdir失敗,則運行echo && exit部件。但是它實際上做的是運行類似(mkdir || echo) && exit的東西 - 也就是說,如果mkdirecho命令成功,它將運行exit部件。 echo幾乎總會成功,所以它幾乎總是會退出。

因此,您需要明確地對命令進行分組,以覆蓋此優先級。但不要使用(),因爲它在子shell中運行其內容,並且exit將僅僅退出子shell,而不是主腳本;您可以改爲使用{ },也可以使用明確的if塊。另外,您實際上不需要echo && exit,因爲只有在echo命令成功時才運行exitecho幾乎總是成功,但在罕見的情況下,它失敗了,我敢肯定你想腳本退出。

當我需要做這樣的事情在腳本中,我通常使用這個成語:

mkdir "$2" || { 
    echo "I can't create directory $2" >&2 
    exit 8 
} 

(注:如@CharlesDuffy建議,我加了周圍$2雙引號 - 雙引號變量如果它們包含任何空格,通配符等,引用幾乎總是一個好主意。我也送錯誤消息到標準錯誤(>&2),而不是標準輸出,這也是通常一個更好的方式來做事)

如果你想成爲更簡潔,你可以把它全部在一行。

mkdir "$2" || { echo "I can't create directory $2" >&2; exit 8; } 

注意,最終;(或換行)的}之前需要,或shell認爲}只是一個參數exit。你也可以去其他的方式,並使用一個明確的if塊:

if ! mkdir "$2"; then 
    echo "I can't create directory $2" >&2 
    exit 8 
fi 

這個選項是一樣聰明,簡潔的,但是這是一件好事 - 巧妙而簡潔的到底是什麼造成了首位這個問題;清晰明確的代碼更好。

+0

@CharlesDuffy完成! –

+0

你知道我有多愛你嗎?另外,你能幫我解決這個問題:> var = $(file -b $ 1 | grep「ISO」) 我在腳本中有這一行。如果文件失敗(例如:當沒有參數時),我收到一條關於它的用法的巨大錯誤消息。如何使用2>將該錯誤消息發送到/ dev/null?我嘗試了幾個選項,但都沒有工作。 – NuSuntStudent

+0

@NuSuntStudent你需要重定向打印錯誤命令的stderr,所以'var = $(file -b「$ 1」2>/dev/null | grep「ISO」)''。請注意,我還在'$ 1'周圍添加了雙引號,這會將錯誤消息更改爲關於未找到沒有名稱的文件。我建議在腳本的開頭添加腳本參數的健全性檢查(例如'if [-z「$ 1」];然後echo「Usage:...」>&2; exit 1; fi')。這允許您給出一個描述性錯誤,而不是用戶必須從腳本的哪些部分失敗中找出哪些問題。 –

-1

嘗試:

mkdir $1 
if [ $? -ne 0 ] ; then 
    echo "I can't create directory $1" 
    exit 8 
fi 
+1

這裏的降價引擎不是Github-flavored - 三重引號不會創建塊。在選擇多行代碼區域時,使用編輯器中的「{}」按鈕創建的四格縮進。 –

+1

不必要地測試'$?'是不好的形式。更好地寫'如果! mkdir「$ 1」;那麼' - 這樣,額外的日誌記錄或其他代碼更改就無法將您想要測試的操作與檢查本身解耦。 –

1

||&&沒有你習慣於在其他語言的優先級。沒有語法化,它相當於(a || b) && c(嚴格爲從左到右),而不是a || (b && c)(其中&&||具有更高的優先級)。將命令與||&&混合在一起並不是一個好主意;而是使用if語句。

if ! mkdir "$2"; then 
    echo "I can't create directory $2" >&2 
    exit 8 
fi 

如果你真的想用列表的運營商,使用{ ... }到組適當的命令。

mkdir "$2" || { echo "I can't create directory $2" >&2; exit 8; } 
+2

'echo && exit'是不好的形式 - 如果'echo'失敗,我們真的想避免退出嗎?這應該是'mkdir「$ 2」|| {echo「...」>&2; 8號出口; }' –

+0

同意,雖然如果簡單的'echo'失敗了,你可能有更大的問題需要解決。 – chepner