Bir komutun (çok) çıkışını doğrudan uzaktaki bir makineye nasıl geçiririm?


50

Dosyayı önce yerel olarak depolayamadığımı unutmayın - çok büyük.

Bu (iğrenç) sayfa (aşağıya doğru kaydırın) bir cevap veriyor gibi görünüyor, ancak teyp sürücülerine özgü kısmı sökmekte zorlanıyorum:

http://webcache.googleusercontent.com/search?q=cache:lhmh960w2KQJ:www.experts-exchange.com/OS/Unix/SCO_Unix/Q_24249634.html+scp+redirect&cd=3&hl=en&ct=clnk&gl=us

Bunu daha somut hale getirmek için, işte işe yarayabileceğini nasıl düşünürsünüz :

Yerel makinede:

% echo "pretend this string is a huge amt of data" | scp - remote.com:big.txt

(Bu, scp'yi aslında desteklemeyen - kaynak dosyası yerine stdin'den almasını söyleyen bir çizgi koymak yerine kullanılan sözleşmeyi kullanmaktır.)


Google sonucunuzun URL'sini gönderebilir misiniz? Uzmanlar Değişim, sadece yönlendirici google ise altta cevabını gösterir ...
Jon

Yanıtlar:


76

Ssh içine yönlendirebilir ve uzak bir komut çalıştırabilirsiniz. Bu durumda, uzak komut cat > big.txtstdin'i big.txtdosyaya kopyalayacaktır .

echo "Lots of data" | ssh user@example.com 'cat > big.txt'

Uzak uca bağlanmak için ssh kullanabildiğiniz sürece, kolay ve kolaydır.

ncVerileri aktarmak için (NetCat) de kullanabilirsiniz . Alıcı makinede (örneğin, host.example.com):

nc -l 1234 > big.txt

Bu, nc1234 numaralı bağlantı noktasını dinlemek ve bu bağlantı noktasına gönderilen her şeyi big.txtdosyaya kopyalamak için ayarlanır . Ardından, gönderen makinede:

echo "Lots of data" | nc host.example.com 1234

Bu komut nc, gönderen tarafta alıcıdaki 1234 numaralı bağlantı noktasına bağlanmasını ve verileri ağ üzerinden stdin'den kopyalamasını söyleyecektir .

Bununla birlikte, ncçözümün birkaç dezavantajı vardır:

  • Kimlik doğrulama yok; herhangi biri 1234 numaralı bağlantı noktasına bağlanabilir ve dosyaya veri gönderebilir.
  • Veriler, olduğu gibi şifrelenmedi ssh.
  • Her iki makine de bir güvenlik duvarının arkasındaysa, seçilen bağlantı noktasının, özellikle alıcı tarafta, bağlantının düzgün bir şekilde gerçekleşmesini ve yönlendirilmesini sağlamak için açık olması gerekir.
  • Her iki ucun bağımsız ve aynı anda kurulması gerekir. İle sshçözümü, sen uç noktalarının sadece birinden havale başlatabilirsiniz.

Teselli olacaksa, gerçekte neler olup bittiğini güzel bir şekilde açıkladığından, sizinkileri kabul ediyorum olarak işaretlemeye meyilliyim. (Gerçekten araştırmak istiyorsanız, neden birini veya diğerini tercih edebileceğinize dair bazı rehberlik içeren FIFO boru ve netcat çözümlerini dahil edebilirsiniz! :)
dreeves

Bitti. Netcat kullanışlı bir yardımcı programdır. :)
Barry Brown

Diğer yorumda olduğu gibi, eğer tar ile boru kullanıyorsanız, bir işlem ikame kullanabilirsiniz:tar -cvzf >(ssh destination 'cat > file') huge_directory_tree
Taywee

1
SSH gerçekten gitmenin yolu. Karşılaştırıldığında nchata algılama: o da daha da önemlisi varsayılan ve verilerinizin şifreleme ve sıkıştırma sunmaktadır. ncHatalı bir ağ sürücüsü ile kullandığım ve bozulmamış verilerin algılanamadığı durumlar vardı. SSH bu durumda başarısız olur, çünkü hatalı verilerin şifresini çözemez / kodunu çözemez.
jlh

15

Ssh kullanarak:

echo "pretend this is a huge amt of data" | ssh user@remote.com 'cat > big.txt'

Ah, güzel, teşekkür ederim! Bunu tercih etmek için herhangi bir sebep veya FIFO boru çözümü?
dreeves

Bence mknod yaklaşımı, ismi belirtilen boru dışında tamamen aynı şekilde yapıyor.
bpf

4

Dosyayı yerel olarak kaydetmeniz gerekmeyen nc (Net Cat) kullanın .


Ah teşekkürler! "Echo .. | scp .." örneğimin eşdeğerini dahil etmek ister misiniz? Ve bunu diğer cevaplara tercih etmek için bildiğiniz herhangi bir sebep var mı?
dreeves

2
Bunun nciçin kullanmamaya şiddetle tavsiye ederim . Bir keresinde, ağ sürücümün hatalı olduğunu ve hatalı bitleri aktardığını çok daha sonra bulmak için bir makineden diğerine bir ham disk görüntüsü atmıştım. Kullanım scp, sshbir iletim hatası olduğunda söyleyecektir başka ya da bir şey.
JLH

2

Bir FIFO borusu kullanın:

mknod mypipe p
scp mypipe destination &
ls > mypipe

Bunun Linux sisteminde çalışmasını sağlayamadım. scpmypipe'ın normal bir dosya olmadığından şikayet etti.
Barry Brown

1
Aynı sebepten dolayı Mac de çalışmadı. ( mkfifoYine de, boruyu oluşturmak için kullanmak zorunda kaldım .)
Barry Brown

1
Burada da işe yaramadı. Fakat eğer sizin için işe scp <(ls) destination
yararsa

1

Thanx Denis Scherbakov!

Senaryonuzu Hetzner bulutunda denediğimde anladım.

debug1: Sending command: scp -v -t backup-20180420120524.tar.xz.enc
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: channel 0: free: client-session, nchannels 1
debug1: fd 0 clearing O_NONBLOCK
Transferred: sent 4168, received 2968 bytes, in 0.0 seconds
Bytes per second: sent 346786.6, received 246944.0

Ancak yalnızca içeriği olmayan bir dosya oluşturuldu. Gerçek içerik openssl ile şifrelenmiş olduğundan, aslında scp'ye ihtiyacımız yoktur. Linux yerleşik ftpaynı zamanda mükemmel borulama yeteneklerine sahiptir. İşte benim (hala oldukça manuel) çözümüm:

#!/bin/bash

function join_e
{
  for word in $*; do
    echo -n "--exclude=$word "
  done
}


# Directory and file inclusion list
ILIST=(
  /home
)

# Directory and file exclusion list
ELIST=(
  var/lib/postgresql
)



export OPASS=fileencryptionpassword

nice -n 19 bash -c \
   "\
   tar $(join_e ${ELIST[@]}) -cpvf - -C / ${ILIST[*]} \
   | xz -c9e -T8 \
   | openssl enc -aes-256-cbc -pass env:OPASS \
   "

# decrypt with:
# cat backup.tar.xz.enc | openssl  aes-256-cbc -d  -pass env:OPASS | xz -dc | tar xv

# invocation procedure for ftp:
# $ ftp -np
# ftp> open storage.com
# ftp> user  storageuser storagepass
# ftp> put "| bash ~/backup.sh" backup.tar.xz.enc

1

İşte alternatif bir çözüm:

Yukarıdaki örneklerin tümü, ssh + kedisini gösteren, hedef sistemde "kedinin" mevcut olduğunu varsayar.

Benim durumumda sistem (Hetzner yedekleme) sftp sunan çok kısıtlayıcı bir araç setine sahipti, ancak tam bir kabuk yoktu. Bu yüzden ssh + cat kullanmak mümkün değildi. Belgelenmemiş "scp -t" bayrağını kullanan bir çözüm buldum. Komut dosyasının tamamı aşağıda bulunabilir.

#!/bin/bash

function join_e
{
  for word in $*; do
    echo -n "--exclude=$word "
  done
}

CDATE=`date +%Y%m%d%H%M%S`

# Make password available to all programs that are started by this shell.
export OPASS=YourSecretPasswrodForOpenSslEncryption

#-----------------------------------------------

# Directory and file inclusion list
ILIST=(
  var/lib
)

# Directory and file exclusion list
ELIST=(
  var/lib/postgresql
)

# 1. tar: combine all files into a single tar archive
#      a. Store files and directories in ILIST only.
#      b. Exclude files and directories from ELIST.
# 2. xz: compress as much as you can utilizing 8 threads (-T8)
# 3. openssl: encrypt contents using a password stored in OPASS local environment variable
# 4. cat: concatenate stream with SCP control message, which has to be sent before data
#      a. C0600 - create a file with 600 permissions
#      b. 107374182400 - maximum file size
#         Must be higher or equal to the actual file size.
#         Since we are dealing with STDIN, we have to make an educated guess.
#         I've set this value to 100x times my backups are.
#      c. stdin - dummy filename (unused)
# 5. ssh: connect to the server
#      a. call SCP in stdin (-t) mode.
#      b. specify destination filename

nice -n 19 bash -c \
   "\
   tar $(join_e ${ELIST[@]}) -cpf - -C / ${ILIST[*]} \
   | xz -c9e -T8 \
   | openssl enc -aes-256-cbc -pass env:OPASS \
   | cat <(echo 'C0600 107374182400 stdin') - \
   | ssh username@server.your-backup.de "\'"scp -t backup-${CDATE}.tar.xz.enc"\'"\
   "

2019.05.08 Güncellemesi:

İsteğe göre, aşağıdaki çok daha basit ve daha kısa versiyon

#!/bin/sh

# WORKS ON LARGE FILES ONLY

cat filename.ext \
| cat <(echo 'C0600 107374182400 stdin') - \
| ssh user@host.dom 'scp -t filename.ext'

Eğer tüm gereksiz şeyler kaldırarak bu iyileştirmek ve sadece nasıl kullanılacağına ilişkin minimum örneğine bu aşağı pare Can scp -t? Şu anda ortamınıza göre çok özel / yerelleştirilmiş eksiksiz bir komut dosyanız var. Hetzner wiki için iyi bir şey, ancak çoğu insanın sadece scp ile giriş yapmayı düşündüğü Süper Kullanıcı için değil.
allquixotic
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.