【问题标题】:Check for readable files for a directory in bash检查 bash 中目录的可读文件
【发布时间】:2014-07-28 04:58:28
【问题描述】:

我是 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)-release

我会失去什么吗?

【问题讨论】:

  • 您的脚本将打印名称没有空格且可读的常规文件的名称。你有什么问题?
  • @John1024 我的问题是为什么它不打印可读的文件(检查例如 requirements.txt)

标签: bash for-loop ls


【解决方案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" ]。这可以防止分词并确保此测试适用于所有文件名。

【讨论】:

  • +1 - 注意当前目录中的所有文件将for name in $HOME/* 更改为for name in *,文件掩码也可以使用,例如for name in *.ext,你可以为一个变量分配一个路径并像这样使用for name in "$DIR_PATH"/*,假设你已经设置了DIR_PATH='/path/to/directory'。 HTH。
  • 首选[ -f "$name" ] && [ -r "$fname" ] 而不是-a(按照POSIX 规范的建议)。不过,您实际上并不需要-f-r会在检查是否可读的过程中检查文件是否存在。
  • 感谢您的回答,我正在尝试此页面中的示例:pconstantino.wordpress.com/2008/12/14/… 但似乎有一些问题
【解决方案2】:

最好的方法是调试你的脚本,这样你就可以发现问题:

#!/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 IFS= read -r file; do ...; done < <(exec ls -1 "$HOOME"),因为它可以防止分词和路径名扩展。并使用-1 选项。

【讨论】:

    猜你喜欢
    • 2019-12-17
    • 2011-04-25
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 2014-03-03
    • 2020-11-01
    • 1970-01-01
    • 2014-12-28
    相关资源
    最近更新 更多