67 votes

Comment puis-je scpter la sortie (énorme) d'une commande directement sur une machine distante ?

Notez que je ne peux pas d'abord stocker le fichier localement - il est trop gros.

Cette page (odieuse) (faites défiler jusqu'en bas) semble donner une réponse mais j'ai du mal à démêler la partie qui est spécifique aux lecteurs de bandes :

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

Pour rendre cela plus concret, voici comment vous pourriez le penser pourrait travail :

Sur la machine locale :

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

(C'est en utilisant la convention -- que scp ne supporte pas en fait -- de substituer un tiret au fichier source pour lui dire de le récupérer à partir de stdin à la place).

2voto

Johannes Winter Points 11

Merci à Denis Scherbakov !

Quand j'ai essayé votre script sur le nuage Hetzner, j'ai obtenu

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

Mais seul un fichier sans contenu a été créé. Comme le contenu réel est déjà crypté avec openssl, nous n'avons pas besoin de scp. L'utilitaire linux ftp a également de grandes capacités de tuyauterie. Voici donc ma solution (encore assez manuelle) :

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

1voto

tom Points 101

1) Créer fifo pipe et cat sur la machine distante :

Remote# mknod /tmp/mypipe p # mkfifo /tmp/mypipe
Remote$ cat /tmp/mypipe > big.txt& exit

2) Envoyer des données au tube fifo distant depuis la machine locale avec scp :

Local$ echo "the huge amt of data string" | scp /dev/stdin user@Remote:/tmp/mypipe

1voto

JS. Points 111

J'ai eu un problème similaire avec MacOS/Zsh. D'après Ray Butterworth La réponse de l'auteur ici et celle de Adaephon ailleurs sur SuperUser cela a fonctionné pour moi :

scp =(echo "Hi There!") remote_server:/Users/me/new_file.txt

Assurez-vous simplement de donner un nom de fichier dans le second argument à scp sinon vous obtiendrez un nom inattendu sur le serveur distant.

0voto

Vous pouvez utiliser curl pour cette tâche si vous ne pouvez pas utiliser cat sur le serveur distant par exemple. En utilisant le protocole sftp, vous pouvez copier tout ce que vous envoyez à son stdin via ssh. Vous pouvez utiliser la clé ssh au lieu du mot de passe pour vous authentifier. Je n'ai pas essayé la limitation de taille, mais il devrait fonctionner comme les autres solutions, il est authentifié et la syntaxe est propre.

N'essayez pas de passer du protocole curl au protocole scp, car cela ne fonctionnera pas. scp-not-working

echo "pretend this string is a huge amt of data" | curl -k -T - -u user:password sftp://remote.host/big.txt

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X