Bisakah scp membuat direktori jika tidak ada?

89

Saya ingin menggunakan scpuntuk mengunggah file tetapi terkadang direktori target mungkin tidak ada.

Apakah mungkin membuat folder secara otomatis? Jika ya, bagaimana caranya? Jika tidak, cara alternatif apa yang bisa saya coba?

AGamePlayer
sumber

Jawaban:

72

Ini adalah salah satu dari banyak hal yang rsyncdapat dilakukan.

Jika Anda menggunakan versi yang rsyncdirilis dalam beberapa tahun terakhir, ¹ sintaks perintah dasarnya mirip dengan scp: ²

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

Itu akan menyalin local-sourcedan isinya ke $HOME/path/local-dirpada mesin jarak jauh, membuat direktori apa pun yang diperlukan.³

rsyncmemang memiliki beberapa batasan di sini yang dapat mempengaruhi apakah ini akan berhasil dalam situasi khusus Anda. Itu tidak akan membuat beberapa level direktori remote yang hilang, misalnya; itu hanya akan membuat hingga satu level yang hilang pada remote. Anda dapat dengan mudah menyiasati ini dengan mendahului rsyncperintah dengan sesuatu seperti ini:

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

Itu akan membuat $HOME/foo/bar/quxpohon jika tidak ada. Ini tidak akan mengeluh atau melakukan hal lain yang buruk jika tidak sudah ada.

rsyncterkadang memiliki perilaku mengejutkan lainnya. Pada dasarnya, Anda memintanya untuk mencari tahu apa yang ingin Anda salin, dan tebakannya mungkin tidak cocok dengan asumsi Anda. Cobalah dan lihatlah. Jika tidak berperilaku seperti yang Anda harapkan dan Anda tidak dapat melihat alasannya, posting lebih detail tentang pengaturan direktori lokal dan jauh Anda, dan berikan perintah yang Anda coba.


Catatan kaki :

  1. Sebelum rsync2.6.0 (1 Jan 2004), diperlukan -e sshbendera untuk membuatnya berperilaku seperti scpkarena default ke protokol RSH yang sudah usang .

  2. scpdan rsyncberbagi beberapa bendera, tetapi hanya ada sedikit tumpang tindih.

  3. Saat menggunakan SSHsebagai protokol transfer, rsyncgunakan default yang sama. Jadi, sama seperti scp, itu akan menganggap ada pengguna dengan nama yang sama dengan pengguna lokal Anda pada mesin remote secara default.

Warren Young
sumber
Saya menggunakan Mac OSX, apakah saya perlu menginstal rsync pada sisi lokal dan jarak jauh?
AGamePlayer
rsynchalaman dokumentasi yang dicari , tidak menemukan cara menggunakan ssh-key untuk login. Saya tidak ingin menggunakan nama pengguna / kata sandi untuk masuk
AGamePlayer
1
@AwQiruiGuo: Mac OS X disertakan bersama rsync. Dan ya, Anda perlu rsyncdi sisi yang jauh juga, sama seperti dengan scp. Adapun kunci SSH, rsyncsebenarnya menggunakan SSH di bawahnya dengan default -e ssh, jadi jika Anda memiliki kunci yang diatur untuk digunakan scp, mereka akan bekerja rsyncjuga.
Warren Young
1
@ WarrenYoung -rtidak ada bedanya. Skenario yang Anda uraikan hanya berfungsi jika Anda menyalin direktori dan jika direktori induk target ada. Jadi, rsync foo/ u@h:~/akan membuat direktori target footetapi rsync foo/ u@h:~/bar/tidak akan membuat direktori target bar. Yang itu bar/foohanya akan dibuat jika bar/ada. Bagaimanapun, OP mengunggah file dan bahkan dalam kasus di mana ini bekerja, OP hanya berfungsi untuk seluruh direktori.
terdon
1
Ya, saya juga bermain-main dengannya. Sepertinya menetapkan nama file juga membuatnya gagal. Jadi rsync file host:/foo/filegagal jika foo/tidak ada tetapi rsync file host:/foo/membuat direktori dan tempat filedi dalamnya. Aneh. Bagaimanapun, Anda benar dan skenario dasarnya berfungsi, saya akan menarik kembali downvote saya.
terdon
35

Jika Anda menyalin sekelompok file, tidak juga. Jika Anda menyalin direktori dan semua konten di bawahnya, ya. Diberi perintah ini:

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

Jika directorytidak ada ~/the/targetaktif host, itu akan dibuat. Namun, jika ~the/targettidak ada, Anda mungkin akan memiliki masalah - saya tidak ingat hasil pasti dari kasus ini, tetapi bersiaplah untuk yang dimaksudkan scpuntuk gagal.

John
sumber
1
scp: /home/madmike/test_bin: No such file or directorySegera setelah direktori target hilang, ini rusak pada pengaturan saya. Menggunakan cygwin di klien dan RHEL 6.9 di server. Apa pengaturan Anda?
MadMike
16

Sejauh yang saya tahu, scpitu sendiri tidak bisa melakukan itu, tidak. Namun, Anda bisa langsung sshke mesin target, membuat direktori lalu menyalin. Sesuatu seperti:

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

Perhatikan bahwa jika Anda menyalin seluruh direktori, hal di atas tidak diperlukan. Misalnya, untuk menyalin direktori ~/fooke host jarak jauh, Anda bisa menggunakan -rbendera (rekursif):

scp ~/foo/ user@host:~/

Itu akan membuat direktori target ~/foopada host jarak jauh. Namun, itu tidak dapat membuat direktori induk. scp ~/foo user@host:~/bar/fooakan gagal kecuali direktori target barada. Bagaimanapun, -rflag tidak akan membantu membuat direktori target jika Anda menyalin file individual.

terdon
sumber
3

Ya kamu bisa. Menurut halaman manual scp:

man scp

.....

-r Salin seluruh direktori secara rekursif. Perhatikan bahwa scp mengikuti tautan simbolik yang ditemui di traversal pohon.

....

YoMismo
sumber
7
Itu tidak akan membuat direktori induk target. Itu dapat menyalin direktori ke lokasi yang ada. Jadi, scp -r foo/ u@h:~/barakan membuat bar/foojika remote bar/ada tetapi akan gagal jika tidak.
terdon
1
Itu tidak akan gagal. Ini akan menyalin fookonten ke direktori baru /bar. Tentu saja namanya telah diubah yang mungkin bukan yang diinginkan OP. Jika yang Anda inginkan adalah struktur pohon baru yang dibuat di mesin tujuan maka scptidak akan melakukan pekerjaan, jika apa yang Anda inginkan adalah mereplikasi struktur pohon dari cabang tertentu di pohon maka struktur itu dibuat.
YoMismo
6
Ya, tetapi ini hanya berfungsi jika Anda menyalin direktori , bukan file. scp -r file host:~/bar/tidak akan membuat bar/.
terdon
3

Saya menggunakan fungsi berikut sebelum mentransfer btrfsfoto 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
}

Cukup panggil fungsi dalam skrip Anda dengan:

check_remote_dir /my/remote/path

Stuart Cardall
sumber
Saya melakukan hal yang hampir sama, tetapi saya harus mengetikkan kata sandi secara manual (untuk alasan keamanan), jadi saya akhirnya mengetiknya setidaknya dua kali ...
Stefan Reich
0

Anda bisa mengaitkan perintah dengan perintah mkdir dan kemudian merujuk ke folder yang Anda buat:

mkdir ~/new-folder/ && scp -P 22 <remote/url>:~/new-folder/
Ducky
sumber
3
(1) Pertanyaannya mengatakan "secara otomatis". Tampaknya ini tidak otomatis. (2) Ini tampaknya hanya variasi sepele pada jawaban terdon .
G-Man
0

Ketika dibatasi hanya scp atau sftp tanpa ssh tersedia (oleh rssh), dimungkinkan untuk membuat direktori dengan menyalin pohon direktori kosong dengan rsync dan kemudian menyalin file.

Itulah cara saya meletakkan kunci ssh publik ke host jarak jauh ketika ssh-copy-id tidak berfungsi dan direktori .ssh tidak ada:

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

Dimungkinkan untuk menggabungkan perintah-perintah ini menjadi satu rsync menambahkan satu lagi filter sertakan di tengah, jika nama file target adalah sama.

pengguna3132194
sumber