Tengo una if
declaración para calcular archivos y eliminar todos excepto los últimos tres archivos. Pero quiero ejecutar este comando de forma remota. ¿Cómo puedo combinar ssh
con una if
condición?
Intenté esto pero no tuve éxito.
#!/bin/bash
ssh -t test@192.168.94.139 "cd /var/www/test.com/backup ;
if [ $(ls | wc -l) -lt 3 ]
then
echo "Less"
else [ $(ls -t *.tgz|awk 'NR >3'|xargs rm -f) ]
echo "deleted"
fi"
El error que obtuve:
ls: no se puede acceder a * .tgz: no existe tal archivo o directorio
command-line
bash
ssh
Janith
fuente
fuente
$(
)
shell local ejecuta la parte delssh
comando incluso antes de que comience el comando. Eso es cierto tanto cuando$(
)
está solo como cuando está encerrado por"
s. Sin embargo, si$(
)
estuviera dentro de'
s, no sería ejecutado por el shell local.Respuestas:
NOTA: de hecho, hay dos capas para la pregunta aquí. Una es 'Quiero ejecutar una tarea no trivial en un servidor remoto accesible a través de SSH'. La otra es "Estoy tratando de pasar una cadena compleja a un comando, y el argumento termina siendo diferente de lo que pretendía". Estoy respondiendo la pregunta de bajo nivel sin discutir si el enfoque utilizado es "correcto" (conveniente, no propenso a errores, seguro, etc.) para resolver el de alto nivel. Como lo indican las otras respuestas y comentarios, posiblemente no lo sea.
Su línea de comando es mayormente correcta; solo tienes que cambiar un poco la cita.
El problema principal es que las cadenas de comillas dobles son expandidas por su shell local, por lo que las
$(...)
partes se evaluarán en su sistema local. Para pasarlos al sistema remoto, debe encerrar el script entre comillas simples.También tiene algunas comillas incrustadas. En su guión original, hay argumentos para los dos
echo
s; si cambia la cita externa a comillas simples, será la secuencia de comandos awk. Estos resultados resultan en la omisión de las comillas, lo que no molesta a laecho
s, pero desordenará el script awk, ya que el signo mayor que se convertirá en redirección de salida. Entonces, después de cambiar las comillas externas a comillas simples, cámbielas a comillas dobles.Este es su script con la cita fija. El script puede tener otros problemas, solo arreglé la sintaxis.
fuente
/var/www/test.com/backup
a una variable llamada "BACKUPDEST" ycd $BACKUPDEST
¿Me puede decir cómo hacerlo?BACKUPDEST
? Si eso sucede en el lado remoto, simplemente inclúyalo en el script normalmente. Si desea configurarlo localmente (por ejemplo, calcularlo en el script local o pasarlo como un argumento de línea de comando), puede cambiar la primera línea a, por ejemplo"cd $BACKUPDEST"' ;
, el shell expande la parte entre comillas dobles, mantiene la comilla simple parte intacta, concatena los dos y pasa el resultado como último argumento assh
."cd '$BACKUPDEST'"' ;
en caso de que la ruta en esa variable contenga algo extraño (por ejemplo, un espacio). De nuevo: solo digo que se puede hacer de esta manera, no que se debe hacer de esta manera.Sí, puede exucir scripts complejos a través de
ssh
Este ejemplo utiliza un documento bash here para generar la cadena de comando. En cualquier caso, pasar scripts a través de ssh es propenso a errores, porque es difícil citar y escapar de las variables (tenga en cuenta la barra invertida antes de los comandos). Si el script se vuelve demasiado complejo, es mejor copiarlo
scp
y luego ejecutarlo en el host de destino.No intenté arreglar su script , pero aquí hay un ejemplo de cómo podría funcionar contar y eliminar en un host remoto:
El
ls -t *.tgz
no va a funcionar, ya que el englobamiento está sucediendo solamente en el sistema local. Tampocols
es una buena idea usarlo para contar archivos, ya que también devuelve entradas como.
,..
y directorios.fuente
syntax error near unexpected token elif'
,elif [ $(ls -t |awk 'NR >3'|xargs rm -f) ]; then'
;
falta en el puño si-declaración. ¡Pero no te arreglé el script! Hay muchos más problemas, por ejemplo, ells *.tgz
$(...)
dentro de una cadena entre comillas dobles, por lo que el shell local la evaluó. Escaparlo\$(...)
como se mostró en el primer ejemplo, o usar comillas simples alrededor de todo el script, evita que el shell local lo expanda, por lo que se envía al sistema remoto, el shell remoto lo expande y el script funciona Como era la intención.printf
expandir las variables; aún así será más fácil de administrar que tratar de escapar de todas las variables de shell. ¡Además, evitaría la necesidad de usarcat
solo para capturar el documento aquí en una variable!Creo que todo este complicado asunto de citas es prueba suficiente para no usarlo, sino usar un script. Si desea evitar varias
ssh
conexiones, canalice la secuencia de comandos al otro host y deje que se ejecute allí en un comando:Archivo local, diga
myscript.sh
:Entonces:
O (evitando un uso inútil del gato ):
Esto canaliza la secuencia
myscript.sh
de comandos local al lado remoto donde se redirige a un archivo (temporal)/tmp/ms.sh
, se ejecuta y finalmente se elimina.Nota: no verifiqué el script original en busca de errores, pero solo quería mostrar la idea. No es necesaria una cita propensa a errores y todos los comandos en el script se ejecutan en el lado remoto.
fuente
ssh user@host bash <myscript.sh
.mktemp
o algo similarmente seguro.Preferiría colocar el script en la instancia remota y simplemente ejecutarlo a través de ssh, pero aquí está mi sugerencia de cómo se podría hacer de la manera que desee:
Notas:
-lt
se reemplaza por-le
.eval
- Construir comandos concatenando argumentos.\"
dentro de la$COMMAND{1..3}
expresión, pero decido agregarlas.fuente