繁体   English   中英

检查bash中目录的可读文件

[英]Check for readable files for a directory in bash

我是Bash脚本的新手,并且一直在使用它,但是我有一个我不理解的脚本:

#!/bin/bash
for name in $(ls $HOME)
do
    if [ -f $name -a -r $name ]
    then
        echo "$name is file"
    fi
done

如果我运行它,它什么也不打印。 我很确定我的主目录中有可读文件。 例如:

-rw-r--r--  1 user user        368 feb 17 22:39 requirements.txt

如果我用另一个目录测试它,它告诉我有两个可读文件:

-rwxr-xr-x 1 user user  442 jul 27 23:47 longest-and-shortest-username.sh
-rwxr-xr-x 1 user user 1155 jul 28 00:39 options-for-files-in-directory.sh

我的Bash版本是:4.2.45(1)-发行版

我在丢东西吗?

该代码试图获取HOME目录中的文件名。 但是,当时正在测试该名称是否在当前目录中存在(必须存在差异)。

解决方案是将目录附加到文件名。 尝试:

for name in "$HOME"/*
do
    if [ -f "$name" -a -r "$name" ]
    then
        echo "$name is file"
    fi
done

上面的另一个优点是,它适用于带有空格和所有其他恶意字符的文件名。

bash看到$(ls $HOME) ,它将运行ls $HOME ,然后将单词拆分应用于结果。 因此,如果您有一个名为my file ,则bash会将其分为两个参数myfile 你不要这个 相比之下,当bash看到$HOME/* ,它将返回所有未修改的文件名。

另请注意,我把双引号$name中的[ -f "$name" -a -r "$name" ] 这样可以防止单词分裂,并确保此测试适用于所有文件名。

最好的方法是调试脚本,以便找出问题所在:

#!/bin/bash
echo "Current directory is $PWD."
echo "HOME is $HOME."
for name in $(ls $HOME)
do
    echo "Checking $file."
    if [ -f $name -a -r $name ]
    then
        echo "$name is file"
    fi
done

这里有一些技巧,但是请在发现问题原因之前,不要修改脚本。

  • 将打开的变量括在双引号对之间,以防止单词分裂和路径名扩展。
  • 首选[[ ]]不是[ ]因为它不会进行单词拆分和路径名扩展。
  • 可能不需要使用ls 您可以只使用"$HOME"/*
  • 如果必须使用ls ,请考虑while read使用带有进程替换的while read循环: while IFS= read -r file; do ...; done < <(exec ls -1 "$HOOME") while IFS= read -r file; do ...; done < <(exec ls -1 "$HOOME") while IFS= read -r file; do ...; done < <(exec ls -1 "$HOOME")因为它可以防止单词拆分和路径名扩展。 并使用-1选项。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM