我在目录结构中有很多 php 文件,比如 /mylibs
我想php -l $file
在每个 php 文件上运行一个简单的检查语法错误的程序
find /mylibs -type f -iname "*.php" -exec php -l {} &>/dev/null \;
这是第一步,&>/dev/null 占用了 php 的详细输出(无论是否发现语法错误)
如果没有发现错误,则返回php -l
0,这取决于哪个,我想将它们复制到其他目录/mybin
。为了检查这是否按预期工作,我尝试了
find /mylibs -type f -iname "*.php" -ok php -l {} &>/dev/null ; echo $? \;
但这只是在终端上打印 1 并且不要求确认(-ok 在交互式确认后的作用与 -exec 相同)
我在这里做错了什么?这不可能吗?
答案1
;
是个壳牌命令分隔符。它后面的所有内容都将是单独的命令,不会传递给find
,因为命令解析是在执行之前完成的。同样,&>/dev/null
适用于全部的 find
命令,不是只是php
,无论它位于何处(之前,中间或之后)。
要在-exec
or中使用此类运算符-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