简化bash脚本

  • 本文关键字:脚本 bash 简化 bash
  • 更新时间 :
  • 英文 :


必须有一种方法来流式传输下面我粗略构建的脚本中的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 $''参数会导致它们各自使用一个空字符作为分隔符,这在文件名中是无效的。

相关内容

  • 没有找到相关文章

最新更新