¿Puede scp crear un directorio si no existe?

89

Quiero usar scppara cargar archivos, pero a veces el directorio de destino puede no existir.

¿Es posible crear la carpeta automáticamente? ¿Si es así, cómo? Si no, ¿qué forma alternativa puedo probar?

AGamePlayer
fuente

Respuestas:

72

Esta es una de las muchas cosas que rsyncpuede hacer.

Si está utilizando una versión rsynclanzada en los últimos años, ¹ su sintaxis de comando básica es similar a scp: ²

$ rsync -r local-dir remote-machine:path

Eso copiará local-sourcey su contenido $HOME/path/local-diren la máquina remota, creando los directorios necesarios.

rsynctiene algunas restricciones aquí que pueden afectar si esto funcionará en su situación particular. No creará múltiples niveles de directorios remotos faltantes, por ejemplo; solo creará hasta un nivel faltante en el control remoto. Puede evitar esto fácilmente precediendo el rsynccomando con algo como esto:

$ ssh remote-host 'mkdir -p foo/bar/qux'

Eso creará el $HOME/foo/bar/quxárbol si no existe. No va a quejarse o hacer cualquier otra cosa malo si no existe ya.

rsynca veces tiene otros comportamientos sorprendentes. Básicamente, le está pidiendo que descubra lo que quería copiar, y sus suposiciones pueden no coincidir con sus suposiciones. Pruébalo y verás. Si no se comporta como espera y no puede ver por qué, publique más detalles sobre sus configuraciones de directorio local y remoto, y dé el comando que intentó.


Notas al pie :

  1. Antes de rsync2.6.0 (1 de enero de 2004), requería el -e sshindicador para que se comportara como si scpno se ajustara al protocolo RSH obsoleto .

  2. scpy rsynccompartir algunas banderas, pero solo hay un poco de superposición.

  3. Cuando se usa SSHcomo protocolo de transferencia, rsyncusa los mismos valores predeterminados. Entonces, al igual scp, asumirá que hay un usuario con el mismo nombre que su usuario local en la máquina remota de forma predeterminada.

Warren Young
fuente
Estoy usando Mac OSX, ¿necesito instalar rsync tanto en el lado local como en el remoto?
AGamePlayer
buscó rsyncen la página de documentación, no encontré cómo usar ssh-key para iniciar sesión. No quiero usar nombre de usuario / contraseña para iniciar sesión
AGamePlayer
1
@AwQiruiGuo: Mac OS X viene con rsync. Y sí, también necesita rsyncen el lado remoto, al igual que con scp. En cuanto a las claves SSH, en rsyncrealidad está utilizando SSH debajo del valor predeterminado -e ssh, por lo que si tiene claves configuradas para su uso scp, también funcionarán rsync.
Warren Young
1
@WarrenYoung -rno hace ninguna diferencia. El escenario que describe solo funciona si está copiando un directorio y si existe el directorio padre de destino. Por lo tanto, rsync foo/ u@h:~/creará el directorio de destino foopero rsync foo/ u@h:~/bar/no creará el directorio de destino bar. Ese creará bar/foosolo si bar/existe. En cualquier caso, el OP está cargando archivos e incluso en los casos en que esto funciona, solo funciona para directorios completos.
terdon
1
Sí, también he estado jugando con eso. Parece que especificar un nombre de archivo también hace que falle. Entonces rsync file host:/foo/filefalla si foo/no existe pero rsync file host:/foo/crea el directorio y lo coloca fileen él. Extraño. De todos modos, tienes toda la razón y el escenario básico funciona, retractaré mi voto negativo.
terdon
35

Si está copiando un grupo de archivos, en realidad no. Si está copiando un directorio y todos los contenidos debajo de él, sí. Dado este comando:

$ scp -pr /source/directory user@host:the/target/directory

Si directoryno existe en ~/the/targeton host, se creará. Sin embargo, ~the/targetsi no existe, es probable que tenga problemas: no recuerdo los resultados exactos de este caso, pero esté preparado para el scpfracaso previsto .

John
fuente
1
scp: /home/madmike/test_bin: No such file or directoryTan pronto como falta el directorio de destino, esto se rompe en mi configuración. Usando cygwin en el cliente y RHEL 6.9 en el servidor. ¿Cuál es tu configuración?
MadMike
16

Que yo sepa, scpno puede hacer eso, no. Sin embargo, podría simplemente sshir a la máquina de destino, crear el directorio y luego copiar. Algo como:

ssh user@host "mkdir -p /target/path/" &&
    scp /path/to/source user@host:/target/path/

Tenga en cuenta que si está copiando directorios completos, no se necesita lo anterior. Por ejemplo, para copiar el directorio ~/fooal host remoto, puede usar el -rindicador (recursivo):

scp ~/foo/ user@host:~/

Eso creará el directorio de destino ~/fooen el host remoto. Sin embargo, no puede crear el directorio padre. scp ~/foo user@host:~/bar/foofallará a menos que barexista el directorio de destino . En cualquier caso, el -rindicador no ayudará a crear un directorio de destino si está copiando archivos individuales.

terdon
fuente
3

Sí tu puedes. Según la página de manual de scp:

hombre scp

.....

-r Copiar recursivamente directorios completos. Tenga en cuenta que scp sigue los enlaces simbólicos encontrados en el recorrido del árbol.

....

YoMismo
fuente
77
Eso no creará el directorio principal de destino. Puede copiar un directorio a una ubicación existente. Por lo tanto, scp -r foo/ u@h:~/barse creará bar/foosi el control remoto bar/existe pero fallará si no existe.
terdon
1
No fallará. Copiará los foocontenidos al nuevo directorio /bar. Por supuesto, el nombre ha sido cambiado, lo que puede no ser lo que quiere el OP. Si lo que desea es una nueva estructura de árbol creada en la máquina de destino, entonces scpno hará el trabajo, si lo que quiere es replicar una estructura de árbol de una determinada rama en el árbol, entonces se crea esa estructura.
YoMismo
66
Sí, pero esto solo funciona si está copiando directorios , no archivos. scp -r file host:~/bar/no va a crear bar/.
terdon
3

Uso la siguiente función antes de transferir btrfsinstantáneas ssh:

check_remote_dir() {
        printf "\ntesting remote directory: '$1' "

        if ssh -p $PORT $ROOT@$REMOTE "[ ! -d $1 ]"; then
                printf "\nCreating: $1 on $ROOT@$REMOTE\n"
                ssh -p $PORT $ROOT@$REMOTE "mkdir -p $1"
        else
                printf "[OK]\n"
        fi
}

Simplemente llame a la función en su script con:

check_remote_dir /my/remote/path

Stuart Cardall
fuente
Hago casi lo mismo, pero tengo que escribir la contraseña manualmente (por razones de seguridad), así que termino escribiéndola al menos dos veces ...
Stefan Reich
0

Puede encadenar el comando con el comando mkdir y luego hacer referencia a la carpeta que ha creado:

mkdir ~/new-folder/ && scp -P 22 <remote/url>:~/new-folder/
Cariño
fuente
3
(1) La pregunta dice "automáticamente". Esto no parece ser automático. (2) Esto parece ser solo una variación trivial en la respuesta de terdon .
G-Man
0

Cuando se restringe a solo scp o sftp sin ssh disponible (por rssh), es posible crear directorios copiando el árbol de directorios vacío con rsync y luego copiando los archivos.

Así es como pongo la clave ssh pública en el host remoto cuando ssh-copy-id no funciona y el directorio .ssh no existe:

rsync -e 'ssh -p22' -av -f"+ */" -f"- *" ~/.ssh [email protected]:~/
scp -P22 ~/.ssh/id_rsa.pub [email protected]:~/.ssh/authorized_keys

Es posible combinar estos comandos en un rsync agregando un filtro de inclusión más en el medio, si el nombre del archivo de destino es el mismo.

usuario3132194
fuente