2017-04-20 82 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',因为我想知道我在构建这个脚本时的误解。您突出了关于循环浏览文件的一些重要观点,并且您建议的链接非常有帮助。谢谢! –