Comando remoto SSH con! (Lista de patrones)

5

Estoy tratando de eliminar todos los archivos y directorios en /path/to/dir/ salvo dos directorios ( dir1 y dir2 ) desde un host remoto utilizando SSH. Cuando ejecuto un comando similar a este en mi caja de Ubuntu 14.04 local, funciona como se esperaba:

user@host1:~$ cd /path/to/dir/ && rm -rf !(dir1|dir2)

Si intento ejecutar el mismo comando a través de SSH en otro host con la misma estructura de directorios, falla.

user@host1:~$ ssh user@host2 'cd /path/to/dir/ && rm -rf !(dir1|dir2)'
bash: -c: line 0: syntax error near unexpected token `('
bash: -c: line 0: `cd /path/to/dir/ && rm -rf !(dir1|dir2)'

¿Cómo debo escapar del comando para que funcione? Pensé que usar comillas simples era suficiente.

Steve
fuente
1
¿Cuál es la salida de ssh user@host2 'shopt -p extglob'?
John1024
@ John1024 Buena captura. De hecho, el otro anfitrión regresa shopt -u extglob lo que parece significar extglob = off.
Steve

Respuestas:

3

Si realmente quieres usar patrones de bash puedes hacer esto:

user@remote:~$ ls del/
1  2  3
user@desktop:~$ ssh remote.example 'PATTERN="!(1|2)" bash -O extglob -c "cd del && echo rm \$PATTERN"'
rm 3

Prefiero usar encontrar (sin embargo, adjuntar -delete Si realmente quieres borrar los archivos):

 user@desktop:~$ ssh remote.example 'cd del && find . ! -path . ! \( -name 1 -or -name 2 \)'
./3

Ejemplo con directorios:

user@remote:~/del$ tree -F
.
├── 1/
│   └── 11/
├── 2/
│   └── 22/
└── 3/
    └── 33/
user@remote:~/del$ find . -maxdepth 1 -type d '!' -path . ! \( -name 1 -or -name 2 \) -print0 | xargs -0 echo rm -r
rm -r ./3
11181
fuente
Gracias a esto lo tengo para trabajar. Añadiendo dotblob. Mi versión final es ssh user@host2 'bash -O extglob -O dotglob -c "cd /path/to/dir/ && rm -rf !(dir1|dir2)"'. Al principio me atrajo el enfoque de la lista de patrones debido a su elegancia y suavidad, pero tiene razón: después de agregar todas las opciones necesarias find parece más simple
Steve