scp สามารถสร้างไดเรกทอรีได้หรือไม่?


88

ฉันต้องการใช้scpเพื่ออัปโหลดไฟล์ แต่บางครั้งอาจไม่มีไดเรกทอรีเป้าหมาย

เป็นไปได้หรือไม่ที่จะสร้างโฟลเดอร์อัตโนมัติ ถ้าเป็นเช่นนั้นได้อย่างไร ถ้าไม่ฉันจะลองอีกวิธีได้อย่างไร

คำตอบ:


71

นี่คือหนึ่งในหลาย ๆ สิ่งที่rsyncสามารถทำได้

หากคุณกำลังใช้รุ่นที่วางrsyncจำหน่ายในช่วงหลายปีที่ผ่านมา command ไวยากรณ์คำสั่งพื้นฐานจะคล้ายกับscp: ²

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

ที่จะคัดลอกlocal-sourceและเนื้อหาไปยัง$HOME/path/local-dirบนเครื่องระยะไกลสร้างไดเรกทอรีใด ๆ ที่จำเป็น³

rsyncมีข้อ จำกัด บางอย่างที่นี่ซึ่งอาจส่งผลต่อการทำงานในสถานการณ์เฉพาะของคุณ มันจะไม่สร้างไดเรกทอรีระยะไกลที่ขาดหายไปหลายระดับเช่น มันจะสร้างได้เพียงหนึ่งระดับที่หายไปบนรีโมท คุณสามารถหลีกเลี่ยงสิ่งนี้ได้ง่ายๆโดยนำหน้าrsyncคำสั่งด้วยสิ่งนี้:

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

มันจะสร้าง$HOME/foo/bar/quxต้นไม้ถ้ามันไม่มีอยู่จริง มันจะไม่บ่นหรือทำอะไรอย่างอื่นไม่ดีถ้ามันไม่อยู่แล้ว

rsyncบางครั้งมีพฤติกรรมที่น่าแปลกใจอื่น ๆ โดยทั่วไปคุณจะต้องให้มันเข้าใจว่าคุณตั้งใจจะทำสำเนาอะไรและการเดานั้นอาจไม่ตรงกับสมมติฐานของคุณ ลองและดู หากมันไม่ทำงานตามที่คุณคาดหวังและคุณไม่สามารถเห็นสาเหตุให้โพสต์รายละเอียดเพิ่มเติมเกี่ยวกับการตั้งค่าไดเรกทอรีท้องถิ่นและระยะไกลของคุณและให้คำสั่งที่คุณลอง


เชิงอรรถ :

  1. ก่อนที่rsync2.6.0 (1 มกราคม 2004) ก็จำเป็นต้องใช้-e sshธงที่จะทำให้มันทำตัวเหมือนscpเพราะมันจะผิดนัดล้าสมัยโปรโตคอล RSH

  2. scpและrsyncแชร์ธงบางส่วน แต่มีการทับซ้อนกันเพียงเล็กน้อย

  3. เมื่อใช้SSHเป็นโปรโตคอลการถ่ายโอนให้rsyncใช้ค่าเริ่มต้นเดียวกัน ดังนั้นเหมือนscpจะถือว่ามีผู้ใช้ที่มีชื่อเดียวกันกับผู้ใช้ท้องถิ่นของคุณบนเครื่องระยะไกลตามค่าเริ่มต้น


ฉันใช้ Mac OSX ฉันจำเป็นต้องติดตั้ง rsync ทั้งในและต่างประเทศหรือไม่?
AGamePlayer

rsyncหน้าเอกสารของการสืบค้นไม่พบวิธีใช้ ssh-key เพื่อเข้าสู่ระบบ ฉันไม่ต้องการใช้ชื่อผู้ใช้ / รหัสผ่านเพื่อเข้าสู่ระบบ
AGamePlayer

@AwQiruiGuo: เรือ Mac OS X rsyncกับ และใช่คุณต้องการrsyncด้านรีโมตด้วยเช่นscpกัน สำหรับคีย์ SSH rsyncนั้นจริง ๆ แล้วใช้ SSH ภายใต้ค่าเริ่มต้น-e sshดังนั้นหากคุณมีการตั้งค่าคีย์สำหรับใช้งานด้วยscpก็จะใช้งานได้rsyncเช่นกัน
Warren Young

1
@WarrenYoung -rไม่ได้สร้างความแตกต่าง สถานการณ์ที่คุณอธิบายจะใช้งานได้เฉพาะในกรณีที่คุณคัดลอกไดเรกทอรีและหากมีไดเรกทอรีเป้าหมายหลักอยู่ ดังนั้นrsync foo/ u@h:~/จะสร้างไดเรกทอรีเป้าหมายfooแต่จะไม่สร้างไดเรกทอรีเป้าหมายrsync foo/ u@h:~/bar/ barอันนั้นจะสร้างbar/fooก็ต่อเมื่อbar/มีอยู่ ไม่ว่าในกรณีใด OP กำลังอัปโหลดไฟล์และแม้ในกรณีที่ใช้งานได้มันจะใช้ได้กับไดเรกทอรีทั้งหมดเท่านั้น
terdon

1
ใช่ฉันได้เล่นกับมันเช่นกัน ดูเหมือนว่าการระบุชื่อไฟล์ทำให้มันล้มเหลว ดังนั้นrsync file host:/foo/fileล้มเหลวหากfoo/ไม่มีอยู่ แต่rsync file host:/foo/สร้างไดเรกทอรีและตำแหน่งfileในนั้น แปลก. อย่างไรก็ตามคุณพูดถูกและสถานการณ์พื้นฐานก็ใช้ได้ฉันจะถอนการโหวตของฉัน
terdon

35

หากคุณกำลังคัดลอกกลุ่มไฟล์จริงๆ หากคุณกำลังคัดลอกไดเรกทอรีและเนื้อหาทั้งหมดด้านล่างใช่ ให้คำสั่งนี้:

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

หากdirectoryไม่อยู่ใน~/the/targetบนhostมันจะถูกสร้างขึ้น อย่างไรก็ตามหาก~the/targetไม่มีอยู่คุณอาจมีปัญหา - ฉันไม่สามารถจดจำผลลัพธ์ที่แน่นอนของคดีนี้ แต่ต้องเตรียมพร้อมสำหรับจุดประสงค์ที่scpจะล้มเหลว


1
scp: /home/madmike/test_bin: No such file or directoryทันทีที่ไดเรกทอรีเป้าหมายขาดตัวแบ่งนี้ในการตั้งค่าของฉัน ใช้ cygwin บนไคลเอนต์และ RHEL 6.9 บนเซิร์ฟเวอร์ การตั้งค่าของคุณคืออะไร?
MadMike

16

เท่าที่ฉันรู้ตัวscpเองไม่สามารถทำอย่างนั้นไม่ อย่างไรก็ตามคุณสามารถsshไปที่เครื่องเป้าหมายสร้างไดเรกทอรีแล้วคัดลอก สิ่งที่ต้องการ:

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

โปรดทราบว่าหากคุณกำลังคัดลอกไดเรกทอรีทั้งหมดไม่จำเป็นต้องใช้ข้างต้น ตัวอย่างเช่นหากต้องการคัดลอกไดเรกทอรี~/fooไปยังโฮสต์ระยะไกลคุณสามารถใช้การ-rตั้งค่าสถานะ (เรียกซ้ำ):

scp ~/foo/ user@host:~/

ที่จะสร้างไดเรกทอรีเป้าหมาย~/fooบนโฮสต์ระยะไกล อย่างไรก็ตามไม่สามารถสร้างไดเรกทอรีหลักได้ scp ~/foo user@host:~/bar/fooจะล้มเหลวเว้นแต่ว่ามีไดเรกทอรีเป้าหมายbarอยู่ ไม่ว่าในกรณีใดการ-rตั้งค่าสถานะจะไม่ช่วยสร้างไดเรกทอรีเป้าหมายหากคุณคัดลอกแต่ละไฟล์


3

ใช่คุณสามารถ. ตามหน้า man ของ scp:

SCP

.....

-r ซ้ำไดเรกทอรีทั้งหมด โปรดทราบว่า scp ติดตามลิงค์ syma bolic ที่พบในการแวะผ่านต้นไม้

....


7
ที่จะไม่สร้างไดเรกทอรีเป้าหมายเป้าหมาย มันสามารถคัดลอกไดเรกทอรีไปยังตำแหน่งที่มีอยู่ ดังนั้นscp -r foo/ u@h:~/barจะสร้างbar/fooหากรีโมทbar/มีอยู่ แต่จะล้มเหลวหากไม่มี
terdon

1
มันจะไม่ล้มเหลว มันจะคัดลอกเนื้อหาไปยังไดเรกทอรีใหม่foo /barแน่นอนว่ามีการเปลี่ยนชื่อซึ่งอาจไม่ใช่สิ่งที่ OP ต้องการ หากสิ่งที่คุณต้องการคือโครงสร้างต้นไม้ใหม่ที่สร้างขึ้นในเครื่องปลายทางแล้วscpจะไม่ทำงานหากสิ่งที่คุณต้องการคือการทำซ้ำโครงสร้างต้นไม้จากสาขาที่แน่นอนในต้นไม้แล้วโครงสร้างนั้นจะถูกสร้างขึ้น
YoMismo

6
ใช่ แต่ใช้งานได้เฉพาะเมื่อคุณคัดลอกไดเรกทอรีไม่ใช่ไฟล์ จะไม่สร้างscp -r file host:~/bar/ bar/
terdon

3

ฉันใช้ฟังก์ชั่นต่อไปนี้ก่อนถ่ายโอนสbtrfsแนปชอตผ่าน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
}

เพียงเรียกใช้ฟังก์ชันในสคริปต์ด้วย:

check_remote_dir /my/remote/path


ฉันทำสิ่งเดียวกัน แต่ฉันต้องพิมพ์รหัสผ่านด้วยตนเอง (เพื่อเหตุผลด้านความปลอดภัย) ดังนั้นฉันจึงพิมพ์อย่างน้อยสองครั้ง ...
Stefan Reich

0

คุณสามารถโยงคำสั่งด้วยคำสั่ง mkdir จากนั้นอ้างอิงไปยังโฟลเดอร์ที่คุณสร้างขึ้น:

mkdir ~/new-folder/ && scp -P 22 <remote/url>:~/new-folder/

3
(1) คำถามที่ว่า“ โดยอัตโนมัติ” สิ่งนี้ดูเหมือนจะไม่เป็นอัตโนมัติ (2) นี้ดูเหมือนจะเป็นเพียงการเปลี่ยนแปลงเล็กน้อยในคำตอบของ terdon
G-Man

0

เมื่อ จำกัด เฉพาะ scp หรือ sftp ที่ไม่มี ssh (โดย rssh) เป็นไปได้ที่จะสร้างไดเรกทอรีโดยการคัดลอกแผนผังไดเรกทอรีว่างด้วย rsync แล้วคัดลอกไฟล์

นั่นคือวิธีที่ฉันวางกุญแจสาธารณะ ssh ไปยังรีโมทโฮสต์เมื่อ ssh-copy-id ไม่ทำงานและไม่มีไดเรกทอรี. ssh อยู่:

rsync -e 'ssh -p22' -av -f"+ */" -f"- *" ~/.ssh backup@1.2.3.4:~/
scp -P22 ~/.ssh/id_rsa.pub backup@1.2.3.4:~/.ssh/authorized_keys

เป็นไปได้ที่จะรวมคำสั่งนี้เป็นหนึ่ง rsync เพิ่มอีกหนึ่งรวมถึงตัวกรองอยู่ตรงกลางถ้าชื่อไฟล์เป้าหมายเหมือนกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.