Làm cách nào để quét trực tiếp đầu ra (rất lớn) của lệnh tới máy từ xa?


50

Lưu ý rằng trước tiên tôi không thể lưu trữ tệp cục bộ - quá lớn.

Trang này (đáng ghét) (cuộn từ dưới lên) dường như đưa ra câu trả lời nhưng tôi gặp khó khăn khi gỡ bỏ phần dành riêng cho ổ đĩa băng:

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

Để làm cho điều này cụ thể hơn, đây là cách bạn nghĩ nó có thể hoạt động:

Trên máy cục bộ:

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

(Đó là sử dụng quy ước - mà trên thực tế scp không hỗ trợ - thay thế một dấu gạch ngang cho tệp nguồn để nói với nó để lấy nó từ stdin thay thế.)


Bạn có thể đăng url của kết quả google của bạn? Trao đổi chuyên gia chỉ hiển thị câu trả lời ở phía dưới nếu người giới thiệu của bạn là google ...
Jon

Câu trả lời:


76

Bạn có thể dẫn vào ssh và chạy một lệnh từ xa. Trong trường hợp này, lệnh từ xa cat > big.txtsẽ sao chép stdin vào big.txttệp.

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

Thật dễ dàng và đơn giản, miễn là bạn có thể sử dụng ssh để kết nối với đầu xa.

Bạn cũng có thể sử dụng nc(NetCat) để chuyển dữ liệu. Trên máy nhận (ví dụ: host.example.com):

nc -l 1234 > big.txt

Điều này sẽ được thiết lập ncđể nghe cổng 1234 và sao chép mọi thứ được gửi đến cổng đó vào big.txttệp. Sau đó, trên máy gửi:

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

Lệnh này sẽ thông báo ncở phía gửi để kết nối với cổng 1234 trên máy thu và sao chép dữ liệu từ stdin trên mạng.

Tuy nhiên, ncgiải pháp có một vài nhược điểm:

  • Không có xác thực; bất cứ ai cũng có thể kết nối với cổng 1234 và gửi dữ liệu vào tệp.
  • Dữ liệu không được mã hóa, như nó sẽ có ssh.
  • Nếu một trong hai máy nằm phía sau tường lửa, cổng được chọn sẽ phải được mở để cho phép kết nối thông qua và được định tuyến đúng cách, đặc biệt là ở đầu nhận.
  • Cả hai đầu phải được thiết lập độc lập và đồng thời. Với sshgiải pháp, bạn có thể bắt đầu chuyển từ chỉ một trong các điểm cuối.

Nếu đó là bất kỳ sự an ủi nào, tôi có xu hướng đánh dấu sự chấp nhận của bạn vì nó giải thích độc đáo những gì đang diễn ra. (Nếu bạn muốn thực sự dành nó, bạn có thể bao gồm các giải pháp ống và netcat FIFO với một số hướng dẫn về lý do tại sao bạn có thể thích cái này hay cái khác :)!
dreeves

Làm xong. Netcat là một tiện ích tiện dụng. :)
Barry Brown

Như trong nhận xét khác, nếu bạn đang chuyển qua tar, bạn có thể sử dụng thay thế quy trình:tar -cvzf >(ssh destination 'cat > file') huge_directory_tree
Taywee

1
SSH thực sự là con đường để đi. So với ncnó cũng cung cấp mã hóa và nén dữ liệu của bạn theo mặc định và quan trọng hơn: phát hiện lỗi. Tôi đã gặp tình huống sử dụng nctrình điều khiển mạng bị lỗi và dữ liệu bị hỏng được truyền đi mà không bị phát hiện. SSH sẽ thất bại trong tình huống đó, vì nó không thể giải mã / giải nén dữ liệu bị lỗi.
jlh

15

Sử dụng ssh:

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

Ah, đẹp, cảm ơn bạn! Bất kỳ lý do để thích giải pháp đường ống này hoặc FIFO?
dreeves

Tôi nghĩ rằng cách tiếp cận mknod hoàn thành nhiệm vụ theo cách chính xác giống như ngoại trừ đường ống được đặt tên.
bpf

4

Sử dụng nc (Net Cat), không cần lưu tệp cục bộ.


À, cảm ơn! Bạn muốn bao gồm tương đương với ví dụ "echo .. | scp .." của tôi? Và bất kỳ lý do bạn biết để thích điều này hơn các câu trả lời khác?
dreeves

2
Tôi thực sự khuyên bạn không nên sử dụng nccho việc này. Tôi đã từng đổ một hình ảnh đĩa thô từ máy này sang máy khác chỉ để biết sau đó trình điều khiển mạng của tôi bị lỗi và chuyển các bit bị lỗi. Sử dụng scp, sshhoặc bất cứ điều gì khác mà sẽ cho bạn biết khi có một lỗi truyền dẫn.
jlh

2

Sử dụng một ống FIFO:

mknod mypipe p
scp mypipe destination &
ls > mypipe

Tôi không thể làm điều này để làm việc trên một hệ thống Linux. scpphàn nàn rằng mypipe không phải là một tập tin thông thường.
Barry Brown

1
Không làm việc trên máy Mac, vì lý do tương tự. (Tuy nhiên, tôi phải sử dụng mkfifođể tạo đường ống.)
Barry Brown

1
Tôi cũng không làm việc ở đây. Nhưng nếu nó phù hợp với bạn và bạn có bash hoặc zsh, bạn có thể đạt được điều này tốt hơn bằng cách thay thế quy trình, như ví dụ này:scp <(ls) destination
Taywee

1

Thanx Denis Scherbakov!

Khi tôi thử kịch bản của bạn trên đám mây Hetzner, tôi đã nhận được

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

Nhưng chỉ có một tập tin không có nội dung được tạo ra. Vì nội dung thực tế đã được mã hóa bằng openssl, chúng tôi thực sự không cần scp. Bản dựng sẵn linux ftpcũng có khả năng đường ống tuyệt vời. Vì vậy, đây là giải pháp (vẫn khá thủ công) của tôi:

#!/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

Đây là một giải pháp thay thế:

Tất cả các ví dụ trên gợi ý ssh + cat cho rằng "cat" có sẵn trên hệ thống đích.

Trong trường hợp của tôi, hệ thống (sao lưu Hetzner) có một bộ công cụ rất hạn chế cung cấp sftp, nhưng không phải là một vỏ hoàn chỉnh. Vì vậy, sử dụng ssh + cat là không thể. Tôi đã đưa ra một giải pháp sử dụng cờ "scp -t" không có giấy tờ. Kịch bản hoàn chỉnh có thể được tìm thấy dưới đây.

#!/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"\'"\
   "

Cập nhật 2019.05,08:

Theo yêu cầu, dưới đây là một phiên bản đơn giản và ngắn hơn nhiều.

#!/bin/sh

# WORKS ON LARGE FILES ONLY

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

Bạn có thể cải thiện điều này bằng cách loại bỏ tất cả những thứ không cần thiết và chỉ giảm bớt điều này xuống ví dụ tối thiểu về cách sử dụng scp -t? Ngay bây giờ bạn có một tập lệnh hoàn chỉnh có tính tùy chỉnh / cục bộ cao đối với môi trường của bạn. Một điều tốt cho wiki Hetzner, nhưng không dành cho Super User, nơi hầu hết mọi người chỉ tìm cách làm thế nào để nhập liệu thông qua scp.
allquixotic
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.