मैं एक दूरस्थ मशीन पर सीधे कमांड के विशाल (विशाल) आउटपुट को कैसे करूं?


50

ध्यान दें कि मैं पहले फ़ाइल को स्थानीय रूप से संग्रहीत नहीं कर सकता - यह बहुत बड़ी है।

यह (अप्रिय) पृष्ठ (नीचे तक सभी तरह स्क्रॉल करें) एक उत्तर देने के लिए लगता है, लेकिन मुझे उस भाग को नापसंद करने में परेशानी हो रही है जो टेप ड्राइव के लिए विशिष्ट है:

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

इसे और अधिक ठोस बनाने के लिए, यहाँ बताया गया है कि आप यह कैसे काम करेंगे:

स्थानीय मशीन पर:

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

(यह सम्मेलन का उपयोग कर रहा है - जो वास्तव में समर्थन नहीं करता है - स्रोत फ़ाइल के लिए डैश को प्रतिस्थापित करने के लिए इसे स्टड से प्राप्त करने के लिए कहने के लिए।)


क्या आप अपने Google परिणाम का url पोस्ट कर सकते हैं? एक्सपर्ट एक्सचेंज केवल नीचे का जवाब दिखाता है कि आपका रेफ़रर Google है ...
जॉन

जवाबों:


76

आप ssh में पाइप कर सकते हैं और रिमोट कमांड चला सकते हैं। इस स्थिति में, रिमोट कमांड है cat > big.txtजो big.txtफ़ाइल में स्टड की नकल करेगा ।

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

यह आसान और सीधा है, जब तक कि आप ssh का उपयोग दूरस्थ छोर से कनेक्ट करने के लिए कर सकते हैं।

आप ncडेटा को स्थानांतरित करने के लिए (नेटकैट) का उपयोग भी कर सकते हैं । प्राप्त करने वाली मशीन पर (जैसे, host.example.com):

nc -l 1234 > big.txt

यह nc1234 पोर्ट को सुनने के लिए सेट किया जाएगा और big.txtफ़ाइल में उस पोर्ट पर भेजे गए किसी भी चीज़ को कॉपी करेगा । फिर, भेजने की मशीन पर:

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

यह कमांड ncरिसीवर पर पोर्ट 1234 से कनेक्ट करने के लिए भेजने के पक्ष में बताएगा और पूरे नेटवर्क में स्टड से डेटा कॉपी करेगा।

हालाँकि, ncसमाधान में कुछ गिरावट है:

  • कोई प्रमाणीकरण नहीं है; कोई भी 1234 पोर्ट से कनेक्ट हो सकता है और फ़ाइल में डेटा भेज सकता है।
  • डेटा एन्क्रिप्टेड नहीं है, क्योंकि यह साथ होगा ssh
  • यदि कोई मशीन फ़ायरवॉल के पीछे है, तो चुने हुए पोर्ट को कनेक्शन के माध्यम से और ठीक से रूट करने की अनुमति देने के लिए खुला होना चाहिए, विशेष रूप से प्राप्त अंत पर।
  • दोनों सिरों को स्वतंत्र रूप से और एक साथ स्थापित करना होगा। sshसमाधान के साथ , आप केवल एक समापन बिंदु से स्थानांतरण आरंभ कर सकते हैं।

यदि यह किसी भी सांत्वना है, तो मैं आपको स्वीकार करने के लिए इच्छुक हूं क्योंकि यह स्पष्ट रूप से बताता है कि वास्तव में क्या चल रहा है। (यदि आप वास्तव में इसे प्राप्त करना चाहते हैं, तो आप कुछ मार्गदर्शन के साथ फीफो पाइप और नेटकाट समाधान शामिल कर सकते हैं कि आप एक या दूसरे को क्यों पसंद कर सकते हैं! :)
20-30 बजे

किया हुआ। नेटकैट एक उपयोगी उपयोगिता है। :)
बैरी ब्राउन

अन्य टिप्पणी की तरह, यदि आप टार के माध्यम से पाइपिंग कर रहे हैं, तो आप एक प्रक्रिया प्रतिस्थापन का उपयोग कर सकते हैं:tar -cvzf >(ssh destination 'cat > file') huge_directory_tree
तैवे

1
एसएसएच वास्तव में जाने का रास्ता है। इसकी तुलना में ncडिफ़ॉल्ट रूप से और अधिक महत्वपूर्ण रूप से आपके डेटा का एन्क्रिप्शन और संपीड़न प्रदान करता है: त्रुटि का पता लगाने। मेरे पास ऐसी परिस्थितियां थीं जहां मैंने ncएक दोषपूर्ण नेटवर्क ड्राइवर के साथ उपयोग किया और दूषित डेटा को अनिर्धारित रूप से प्रसारित किया गया। SSH उस स्थिति में विफल हो जाएगा, क्योंकि यह दोषपूर्ण डेटा को डिक्रिप्ट / डिकम्प्रेस नहीं कर सकता है।
jlh

15

Ssh का उपयोग करना:

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

आह, सुंदर, धन्यवाद! इस या फीफो पाइप समाधान को प्राथमिकता देने का कोई कारण?
dreeves

मुझे लगता है कि मैक्नॉड दृष्टिकोण नामांकित पाइप को छोड़कर बिल्कुल उसी तरह से कार्य को पूरा करता है।
bpf

4

एनसी (नेट कैट) का उपयोग करें , जिसे फ़ाइल को स्थानीय रूप से सहेजने की आवश्यकता नहीं है।


आह, धन्यवाद! मेरी "प्रतिध्वनि .. | scp .." उदाहरण के समकक्ष शामिल करना चाहते हैं? और किसी भी कारण से आप अन्य उत्तरों के लिए इसे पसंद करना जानते हैं?
dreeves

2
मैं इसके ncलिए उपयोग करने के खिलाफ दृढ़ता से अनुशंसा करता हूं । मैंने एक बार एक मशीन से दूसरी मशीन में एक कच्ची डिस्क की छवि को केवल बहुत बाद में पता लगाया कि मेरा नेटवर्क ड्राइवर दोषपूर्ण था और दोषपूर्ण बिट्स को स्थानांतरित कर दिया था। उपयोग करें scp, sshया कुछ और जो आपको बताएगा कि ट्रांसमिशन त्रुटि है।
jlh

2

एक FIFO पाइप का उपयोग करें:

mknod mypipe p
scp mypipe destination &
ls > mypipe

मुझे यह लिनक्स सिस्टम पर काम करने के लिए नहीं मिला। scpशिकायत की कि mypipe एक नियमित फ़ाइल नहीं थी।
बैरी ब्राउन

1
मैक पर काम नहीं किया, या तो, उसी कारण से। (मुझे mkfifoपाइप बनाने के लिए उपयोग करना था , हालाँकि।)
बैरी ब्राउन

1
यहां भी काम नहीं किया। लेकिन अगर यह आपके लिए काम करता है, और आपके पास बैश या zsh है, तो आप इसे बेहतर तरीके से एक प्रक्रिया प्रतिस्थापन के साथ प्राप्त कर सकते हैं, जैसे इस उदाहरण के लिए:scp <(ls) destination
Taywee

1

थैंक्स डेनिस शेरेबकोव!

जब मैंने हेट्ज़नर क्लाउड पर आपकी स्क्रिप्ट की कोशिश की तो मुझे मिल गया

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

लेकिन बिना किसी सामग्री वाली केवल एक फ़ाइल बनाई गई। के रूप में वास्तविक सामग्री पहले से ही Opensl के साथ एन्क्रिप्टेड है, हमें वास्तव में scp की आवश्यकता नहीं है। Linux buildin ftpमें पाइपिंग की महान क्षमताएं भी हैं। तो यहाँ मेरा (अभी भी काफी मैनुअल) समाधान है:

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

यहाँ एक वैकल्पिक समाधान है:

ऊपर दिए गए सभी उदाहरण ssh + cat का सुझाव देते हैं कि गंतव्य सिस्टम पर "बिल्ली" उपलब्ध है।

मेरे मामले में सिस्टम (Hetzner बैकअप) के पास sftp की पेशकश करने वाले टूल का एक बहुत ही प्रतिबंधात्मक सेट था, लेकिन एक पूर्ण शेल नहीं। इसलिए ssh + cat का उपयोग करना संभव नहीं था। मैं एक ऐसे समाधान के साथ आया था जो अनिर्दिष्ट "scp -t" ध्वज का उपयोग करता है। पूरी स्क्रिप्ट नीचे मिल सकती है।

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

अनुरोध के अनुसार, नीचे एक बहुत सरल और छोटा संस्करण है।

#!/bin/sh

# WORKS ON LARGE FILES ONLY

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

क्या आप सभी अनावश्यक चीजों को हटाकर इसमें सुधार कर सकते हैं और बस इसे कैसे उपयोग करने के नंगे न्यूनतम उदाहरण के लिए नीचे दे सकते हैं scp -t? अभी आपके पास एक पूरी स्क्रिप्ट है जो आपके वातावरण के लिए अत्यधिक कस्टम / स्थानीय है। हेत्ज़नेर विकी के लिए एक अच्छी बात है, लेकिन सुपर उपयोगकर्ता के लिए नहीं जहां ज्यादातर लोग सिर्फ स्कैप के माध्यम से इनपुट कैसे करें, इसके लिए देख रहे हैं।
allquixotic
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.