2013-05-15 59 views
0

在Linux中,我试图监视当前目录的所有子目录并输出它们的文件数量。我公司目前拥有的命令是:Linux watch命令“没有这样的文件或目录”

watch 'for FILE in `find . -maxdepth 1 -mindepth 1 -type d | grep -v "unwanted\|directories\|here"`; do echo -n $FILE " "; find $FILE -type f | wc -l; done | column -t' 

这完美的作品,除了偶尔我得到这个错误,

find: `FILE_NAME': No such file or directory 

其中file_name是在子目录中的文件的名称。

有谁知道为什么会发生这种情况,以及如何解决它?谢谢!

+0

是否有可能'FILE_NAME'正在被别的东西删除? 'find'有一个竞争条件,在'find'确定它在请求的目录中,但在可以用一个初始值(在这种情况下,'-type f')进行测试之前,文件可以被删除。 – chepner

+0

@chepner这可能是原因。我监视目录的原因之一是确保正在清理文件。有没有解决这个问题的方法? –

+0

我没有意识到。这只是'find'的一个警告,说它不能再找到一个它不会报告的文件。你可以用'find $ FILE -type f 2>/dev/null |来压制'find'的标准错误wc -l;' – chepner

回答

0

您的命令不处理文件名中的空格。

避免运行for x in $(find)...,或者至少在运行循环时将IFS设置为$'\n'

既然你似乎只关心眼前的子目录,你甚至都不需要使用find为循环值:

watch 'for FILE in *; do [ -d "$FILE" ] && { echo -n $FILE " "; find $FILE -type f | wc -l; } done | column -t' 

(你可以使用更复杂的模式,而不是*,甚至如果你需要更多特定的匹配,则在echo "$FILE" | grep内循环过滤)

+0

所有的都是真的,但并不清楚含空格的文件名是这里的直接问题。 – chepner

+0

@SirAthos感谢您的建议。当前目录(或其子目录)中没有空格,但将来我会记住这一点! –

1

这只使用bash builtins(但AFAIK唯一的bashism是export -f,所以如果你想把它变成丑陋的,所以你可以使用/ bin/sh ,不可读的单行)

#!/bin/bash 
myfunc(){ 
for DIR in "$1/"*; do 
    case "$DIR" in 
     unwanted|dirs)continue;; 
     *)[ -d "$DIR" ] && { 
      printf "%30s " "$DIR" 
      i=0 
      for FILE in "$DIR/"*; do 
       [ -f "$FILE" ] && i=$((i+1)) 
      done 
      echo $i 
     };; 
    esac 
done 
} 
export -f myfunc 
watch myfunc "$HOME" 

请注意,任何可能带有空格的文件名都是双引号,以防止尝试使用stat 2目录:程序和文件而不是“程序文件”。这是最好的做法,双引号变量有任何机会有分隔符(顺便说一句,你可以有文件名中的制表符和换行符+一些非常奇怪的东西 - 几乎任何东西,但“/”)

相关问题