Usando exec em find over ssh from shell script

1

Então, estou tentando executar o seguinte a partir de um script de shell;

ssh -q $CUR_HOST "cd $LOGS_DIR; echo cd $LOGS_DIR; find . -name *.log -mmin +1440 -exec gzip {} \; exit"

Quando isso é executado, gera o seguinte erro:

find: paths must precede expression
Usage: find [-H] [-L] [-P] [path...] [expression]

Eu tentei várias variações com base nas coisas encontradas no Google, mas nenhuma parece resolver esse problema. Alguém poderia me dizer o que há de errado com isso?

Como uma nota lateral, quando eu login manualmente no host de destino e executo o mesmo comando find lá, ele funciona muito bem. Então, eu sou levado a pensar que é algo a ver com o comando sendo incorporado nas aspas duplas do comando ssh.

    
por Skittles 29.06.2014 / 11:17

2 respostas

0

Você esqueceu de adicionar um ';':

ssh -q $CUR_HOST "cd $LOGS_DIR; echo cd $LOGS_DIR; find . -name *.log -mmin +1440 -exec gzip {} \;; exit"

Devido à falta do ; , encontre interprets exit como caminho.

    
por 29.06.2014 / 12:02
2

Existem vários problemas de sintaxe, um dos quais é fatal e outro que provavelmente o morderá em algum momento.

A propósito, você pode usar + em vez de ; para finalizar a diretiva -exec ; Dessa forma, gzip será executado em lotes, o que é um pouco mais rápido.

Se o valor de LOGS_DIR for /somewhere/with/logs , o seguinte comando será executado no host remoto:

cd /somewhere/with/logs; echo cd /somewhere/with/logs; find . -name *.log -mmin +1440 -exec gzip {} \; exit

ou, substituindo newlines pelo operador de ponto-e-vírgula equivalente:

cd /somewhere/with/logs
echo cd /somewhere/with/logs
find . -name *.log -mmin +1440 -exec gzip {} \; exit

Quando find vê esse espúrio exit após a diretiva -exec … ; , não sabe o que fazer com ele; isso prejudica a (errada) suposição de que você quis dizer que é um caminho a ser percorrido. Você precisa de um separador de comando: coloque outro ; após \; (com ou sem um espaço antes).

Um segundo problema é que o padrão curinga *.log será expandido no diretório /somewhere/with/logs . Se houver um arquivo correspondente (ou seja, se houver um arquivo no formato /somewhere/with/logs/something.log ), o padrão será substituído pelo arquivo correspondente. É somente se não houver correspondência que *.log permaneça inalterado pelo shell remoto e seja visto por find. Adicione aspas ao redor do padrão para evitar isso.

Um terceiro problema é com o valor de LOGS_DIR . Ele é expandido localmente em uma string que é executada como um script de shell no lado remoto. Portanto, se houver algum caractere especial do shell (espaço em branco, $ , etc.) nele, isso poderá executar um comando remoto arbitrário. Uma maneira rápida e suja de citar a maioria dos caracteres é colocar aspas simples ao redor da expansão da variável; isso será quebrado apenas se o valor contiver aspas simples. Se o seu script local estiver executando o bash, você poderá substituir aspas simples pela sequência de 4 caracteres '\'' para proteger o valor de LOGS_DIR :

ssh -q "$CUR_HOST" "cd '${LOGS_DIR//\'/\'\\'\'}'; find . -name '*.log' -mmin +1440 -exec gzip {} +; exit"
    
por 29.06.2014 / 16:20