find com exec: como executar a ação condicional de várias etapas em cada arquivo

2

Eu tenho um monte de arquivos php na estrutura de diretórios, diz / mylibs
Eu quero executar um simples php -l $file em cada arquivo php que verifica erros de sintaxe

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

é o primeiro passo, o & > / dev / null usa a saída detalhada do php (encontrou erros de sintaxe ou não)

O php -l retorna 0 se nenhum erro for encontrado, dependendo de qual, eu quero copiá-los para outra pasta, digamos /mybin . Para verificar se isso funciona como esperado, tentei

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

mas isso simplesmente imprime 1 no terminal e não pede confirmação (-ok atua como -exec após confirmação interativa)

O que estou fazendo de errado aqui? não é possível fazer isso?

    
por Sudhi 30.09.2011 / 13:33

2 respostas

3

; é o separador de comandos do shell . Tudo após ele será um comando separado e não será passado para find , já que a análise de comando é feita antes da execução. Da mesma forma, &>/dev/null aplica-se ao comando inteiro find , não apenas a php , independentemente de onde esteja localizado (antes, no meio ou depois ).

Para usar esses operadores em -exec ou -ok , você terá que chamar explicitamente um shell:

find ... -exec bash -c 'php -l "{}" >&/dev/null; echo $?' \;

Observe que os caracteres especiais estão entre aspas, o que significa que eles serão transmitidos literalmente para find e, em seguida, para bash .

Isso é menos simples, mas pode ser mais confiável com nomes de arquivos "estranhos":

find ... -exec bash -c 'php -l "$1" >&/dev/null; echo $?' -- {} \;

Isso exibirá os resultados de uma forma mais legível: (isso é totalmente sobre bash scripting agora, não sobre find anymore)

find ... -exec bash -c '
    if php -l "$1" >&/dev/null; then
        echo "$1: pass"
    else
        echo "$1: fail"
    fi' -- {} \;
    
por 30.09.2011 / 14:38
0

Eu salvaria seus arquivos encontrados em uma matriz e executaria seu php -l em cada item em um loop for ou while, com um if ["$?" !="0"] como um passo.

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

Eu mudaria para

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
    
por 18.02.2013 / 22:54

Tags