必须有一种方法来流式传输下面我粗略构建的脚本中的3行find行。。。
#!/usr/bin/bash
#
#
if [ "find /data -type f -perm 400 -print" ] ; then
find /data -type f -perm 400 -exec echo Modifying {} ;
find /data -type f -perm 400 -print | xargs chmod 755
else
echo 'No files to modify'
fi
您可以将其更改为以下内容:
found=$(find /data -type f -perm 400 -print -quit)
if [ "$found" ]; then
find /data -type f -perm 400 -exec echo Modifying {} ; -exec chmod 755 {} ;
else
echo 'No files to modify`
fi
解释:
find /data -type f -perm 400 -print -quit
:一旦在/data
中找到权限为400
的第一个文件,它就会打印文件名并立即终止查找。打印被保存到变量found
(因此我们知道以后是否输出"无文件可修改")-exec echo Modifying {} ; -exec chmod 755 {} ;
:您可以通过此链接语法对find返回的每个结果执行多个命令- 注意:显然
find
在未找到任何内容时返回0
,因此在此处使用$?
不起作用
while read -d $' ' file; do
found=yes
echo "Modifying $file"
chmod 755 "$file"
done < <(find /data -type f -perm 400 -print0)
if [ "x$found" != "xyes" ]; then
echo "No files found to modify"
fi
这使用了Bash中的进程替换功能。它相当于
find ... | while read ...
除了这种情况,while read
是在子shell中执行的,所以我们不能设置将在外壳中看到的变量。相反,我们可以使用过程替代。<(cmd)
在子shell中运行cmd
,其标准输出重定向到命名管道中。该管道的名称将被替换到外部命令中。
然后,我们使用<
从该管道重定向到while read
命令的标准输入,该命令依次读取每个分隔的记录,并将值存储在指定的名称中(在本例中为file
)。默认情况下,read
换行。对于大多数文件来说,这是可以的;你可以做:
while read file; do
...
done < <(find /data -type f -perm 400)
它会很好用的。但从技术上讲,在文件名中添加换行符是可能的,在这种情况下,换行符就会中断。要查找的-print0
参数和read
的-d $' '
参数会导致它们各自使用一个空字符作为分隔符,这在文件名中是无效的。