使用 exec 查找:如何对每个文件执行多步条件操作

使用 exec 查找:如何对每个文件执行多步条件操作

我在目录结构中有很多 php 文件,比如 /mylibs
我想php -l $file在每个 php 文件上运行一个简单的检查语法错误的程序

find /mylibs -type f -iname "*.php" -exec php -l {} &>/dev/null \;

这是第一步,&>/dev/null 占用了 php 的详细输出(无论是否发现语法错误)

如果没有发现错误,则返回php -l0,这取决于哪个,我想将它们复制到其他目录/mybin。为了检查这是否按预期工作,我尝试了

find /mylibs -type f -iname "*.php" -ok php -l {} &>/dev/null ; echo $? \;

但这只是在终端上打印 1 并且不要求确认(-ok 在交互式确认后的作用与 -exec 相同)

我在这里做错了什么?这不可能吗?

答案1

;是个壳牌命令分隔符。它后面的所有内容都将是单独的命令,不会传递给find,因为命令解析是在执行之前完成的。同样,&>/dev/null适用于全部的 find命令,不是只是php,无论它位于何处(之前,中间或之后)。

要在-execor中使用此类运算符-ok,您必须明确调用 shell:

查找...-execbash -c'php -l“{}”>&/dev/null;回显$?'\;

请注意,特殊字符位于引号内,这意味着它们将被逐字传递给,find然后传递给bash

这并不那么简单,但对于“奇怪”的文件名来说可能更可靠:

查找...-execbash -c ‘php -l “$1” >&/dev/null; echo $?’ -- {}\;

这将以更易读的形式显示结果:(现在这完全与 bash 脚本有关,不再与此有关find

查找...-execbash -c '
    如果 php -l "$1" >&/dev/null; 那么
        回显“$1:通过”
    别的
        echo "$1: 失败"
    FI' -- {}\;

答案2

我会将您找到的文件保存到一个数组中,然后在 for 或 while 循环中对每个项目运行 php -l,以 if [ "$!" != "0" ] 作为步骤。

find /mylibs -type f -iname "*.php" -exec php -l {} &>/dev/null \;

我会改成

MYFILES=$(find /mylibs -type f -iname "*.php")
SAVEIFS=$IFS

IFS=$(echo -en "\n\b")
for FILE in ${MYFILES}
do
  php -l ${FILE} 2&>1 >>/dev/null
  if [ "$?" != "0" ]
    then
      echo "ERROR on ${FILE}
  else
      /bin/cp ${FILE} ${NEWPATH}
  fi
done
IFS=$SAVEIFS

相关内容