2014-04-06 44 views
1
#!/bin/bash 
for dir in "/home/$USER/sessions/out/*/"; do 
    size=$(stat -c %s $dir/log) 
    if [ 1 -ne 0 ]; then 
     echo $size. 
    fi 
done 

今天開始使用bash。我試圖檢查家庭/會話/出所有目錄中日誌文件的大小。如果1!= 0(總是作爲測試),則應打印日誌的文件大小。我得到的是:Bash:通過目錄迭代行爲很奇怪

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 57344001 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 966904. 

我期望在每個文件大小後,我實際上得到一個時期。所有文件大小是否在達到if子句之前附加到可變大小?我很困惑。

+1

試着在/家庭/ $ USER刪除引號/會話/縮小/ */ – mbonneau

+0

完美。 :)當您將評論移至答案時,我會將您的答案標記爲正確。 – Aich

+0

未來,請不要包含如下內容:if [1 -ne 0];那麼...',因爲他們所做的只是造成混亂(儘管你的解釋)。 – mklement0

回答

4

的問題是,路徑擴展(的「*」擴張)發生在stat調用,而不是在循環聲明,因爲在循環路徑被引用,但在stat調用路徑不。

I.e.只有一次迭代循環發生,dir的值爲/home/$USER/sessions/out/*/。然後在stat調用中擴展,提供匹配/home/$USER/sessions/out/*/logstat的所有路徑。

解決方法是取消引用循環聲明中的路徑並在stat調用中引用它。

像這樣:

#!/bin/bash 
for dir in /home/$USER/sessions/out/*/; do 
    size=$(stat -c %s "$dir/log") 
    if [ 1 -ne 0 ]; then 
     echo $size. 
    fi 
done 
+1

儘管在這種情況下沒有必要,但通常可以引用可能需要引用的模式部分(如參數擴展):'for/dir in「/ home/$ USER/sessions/out /」* /; do'。 – chepner

+1

如果僅僅爲了證明引用變量插值應該是標準,你還應該在雙引號中使用'echo「$ size」'。 – tripleee

+0

@triplee我同意總是引用是好的。不過,我在這裏引用的話並不是絕對必要的,爲了更好地說明這一點,保持原文的變化更清楚。 – spbnick

1

你的整個程序可以簡化到只有一行

stat -c %s /home/$USER/sessions/out/*/log 
0

不明白爲什麼你有1測試條件= 0,這總是計算!在那裏真實。但是,下面的循環會爲你做它:

for LOGFILE in `find $LOGPATH -type f -iname 'log'` 
do 
    echo `stat -c %s $LOGFILE`'.' 
done 

我使用的變量LOGPATH,你會用一個「/ home/$ USER /會話/出。」如果這在腳本文件中,那麼在腳本的頂部使用類似這樣的變量是明智的,以便稍後可以在需要時更改它。

'-type f'存在以防萬一有名稱日誌的目錄,您可能不想分析。如果情況並非如此,那麼你可以忽略它。

我使用了find命令,因爲你對它有更精細的控制。您可以設置搜索深度,文件類型,文件大小等。爲了得到最後的時間段,只需簡單地在echo語句的末尾引用一個句點。

如果你所需要的文件名,然後大小,只是改變了echo語句,就像這樣:

echo "$LOGFILE" `stat -c %s $LOGFILE`'.' 
+1

您的'find'命令將在目標目錄的子樹中找到'log'文件_anywhere_,而不僅僅是在子文件夾中,就像在OP的代碼中一樣。例如,用'for'解析'find'輸出從來就不是一個好主意,因爲它會打破含有空格的路徑。 – mklement0

+0

你絕對是對的@ mklement0。但是,如果變量名是雙引號的,那就算了。我將編輯我的答案以反映這一點。謝謝。 – xizdaqrian

+1

不幸的是,在'for'循環中沒有安全的方法來解析命令替換('\'... \''或 - 最好是'$(...)')的輸出。在命令替換中雙引號變量可能會使命令本身更加健壯,但for循環對於包含例如嵌入空格的輸出行或看起來像glob(例如'*')仍然存在問題。將整個命令替換爲雙引號也不起作用,因爲這會將*整個*輸出分配給'for'變量_at once_;有關背景信息,請參閱http://mywiki.wooledge.org/ParsingLs。 – mklement0