必须有一种方法可以在下面粗略构建的脚本中对这3条查找行进行流式处理...
#!/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
答案 0 :(得分:4)
您可以将其更改为以下内容:
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
:一旦在400
中找到具有权限/data
的第一个文件,它就会打印文件名并立即终止查找。打印件保存到变量found
(因此我们知道是否输出“无需修改的文件”或不在以后输出。)-exec echo Modifying {} \; -exec chmod 755 {} \;
:您可以通过此链接语法find
会在找不到任何内容时返回0
,因此使用$?
无效。答案 1 :(得分:4)
while read -d $'\0' 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
这使用process substitution feature in 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
参数和-d $'\0'
的{{1}}参数会导致它们各自使用空字符作为分隔符,这在文件名中无效。