2017-04-20 85 views
0

我已經在下面編寫了一些代碼來查找當前用戶無法讀取的文件。它向我發送的消息是文件無法在父文件夾的子目錄中讀取,即使我在循環之外的腳本底部顯式測試了其報告爲不可讀的文件之一。不過,我已經檢查過,所有的文件都設置了允許閱讀的組權限,我已經用vi打開了其中的幾個。這裏發生了什麼?Linux中的條件文件邏輯

腳本:

#!/bin/ksh 
set -A files $(ls -1 $1) 
echo "${#files[@]}" 

for((i=0; $i < ${#files[@]}; i++)); do 
    if [ ! $2 ${files[$i]} ]; then 
    echo "${files[$i]} not $2" 
    fi 
done 

echo "============" 
if [ ! -r ./tmp/feederseries.txt ]; then 
    echo "./tmp/feederseries.txt not readable" 
fi 

輸出:

$ testfiles.sh "*" -r 
212 
./buildhist: not -r 
20170109_124058.txt not -r 
20170109_124128.txt not -r 
./cmpatches: not -r 
tmp.txt not -r 
./reports: not -r 
archived not -r 
./tmp: not -r 
feederseries.txt not -r 
============ 
+0

只需添加'LS - l $ {files [$ i]}'調試輸入?而且,典型的unix/linux cmd-line選項會期望像'-r'這樣的第一個選項。那麼你不需要引用'「*」',只需讓cmd行自然擴展要處理的文件列表即可。另外,我很驚訝'ls -l $ 1'的輸出在父文件夾的子目錄中包含「文件.....」,我不認爲它會。也許我是誤解。如果你用1個文件創建了一個小的4個文件樣本,那麼會更好,我們可以測試這個問題。祝你好運。 – shellter

+0

使用'echo'$ i:$ {files [$ i]}''調試for循環內的輸入顯示了ULick提到的子目錄中的文件正在被輸入到沒有它們的子目錄路徑的數組中,所以當文件測試完成後,它正在錯誤的位置查找文件。當星號沒有被引用時,shell在將它提供給腳本之前展開它,這意味着'-r'是最後一個參數(即參數$ 213)。我可以切換參數的順序來防止這種情況發生,正如你所說的那樣,順序並不典型。 –

+0

當文件參數爲'*'時,'ls -l'將列出子目錄。因爲我希望腳本能夠靈活地搜索模式(即'* .sh')或所有文件,所以我必須爲它提供一個參數'ls -l $ 1';然而,這意味着要搜索所有文件,我必須指定一些參數來捕獲所有文件。不幸的是,這也告訴'ls'列出子目錄。 –

回答

2

做到這一點是不需要的數組。無論如何,使用ls來循環訪問文件列表並不是最好的主意。有關說明,請參見http://mywiki.wooledge.org/BashPitfalls#for_i_in_.24.28ls_.2A.mp3.29

使用ls -1 *您可以獲得實際目錄中的文件列表,子目錄後跟':'和子目錄中的文件。子目錄中的文件被報告爲不可讀,因爲它們不存在於實際目錄中(您在其中進行測試)。

讓殼採取擴張的關懷和遍歷列表:

#!/bin/ksh 
for file in $1; do 
    if [ ! $2 $file ] ; then 
     echo "$file not $2" 
    fi 
done 

如果你只是需要它們是無法讀取的文件,這會做:

find .. ! -perm /u=r -print 
+0

感謝您提供使腳本正常工作的提示。實際上,我偶然發現了'find'測試權限的能力,但我很高興你不只是告訴我使用'find',因爲我想知道我在構建這個腳本時的誤解。您突出了關於循環瀏覽文件的一些重要觀點,並且您建議的鏈接非常有幫助。謝謝! –