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.
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.
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"
Tags ssh bash find shell-script quoting