ftp supports the put "|..." "remote-file.name"
command to pipe data to an ftp connection. Is there something similar available for sftp?
In sftp i get the following error:
sftp 'jmw@backupsrv:/uploads'
sftp> put "| tar -cx /storage" "backup-2012-06-19--17-51.tgz"
stat | tar -cv /storage: No such file or directory
as above the sftp client doesn't obviously execute the command.
i want to use the pipe command to directly redirect the file stream to sftp. (because there is not enough space left to create a backup file on the same disk before uploading it to sftp server.)
As this is the first result you find by googling for this question and it hasn't been mentioned already I'll add the solution I found here as well:
you can use curls sftp implementation for this. As curl is probably already installed on a lot of systems this might be preferred to the solution using custom clients.
example usage:
curl
uses your.ssh/known_hosts
file for key verification. This might fail in case your ssh client does use newer encryption standards not supported by the library used in curlto fix this you can add the other key types to the known hosts file using the following command:
or you can disable key verification using the
-k
flag (I wouldn't recommend that though)I had a lot of fun figuring out a solution to this problem. It requires the tool nc (netcat) on both machines, and SSH (SFTP isn't needed).
In this example, I shall call the machine that has the data that needs to backed up linux-a, and the machine that needs to receive the backup linux-b.
On linux-a, have netcat listen on a port (I took 2000) and redirect it to a file. This will just sit there and wait until something comes through on that port.
On linux-b, open up an ssh tunnel to linux-a, I used port 2000 again. This will redirect anything you throw at TCP port 2000 on localhost to TCP port 2000 on linux-a, where netcat is listening.
Now create the tar archive, but send the output to stdout (using -) and pipe it to gzip for some compression. Now pipe that to another netcat that sends it to localhost on TCP on port 2000.
We're done! On linux-b the netcat is no longer listening, and a new file is created. The best part is that the tar archive was never placed on the hard disk of linux-a.
I know it's not exactly what you asked for in the question, but if you have netcat available, its a viable solution to your type of problem.
Edit: I forgot about one thing: if you follow these instructions, you'll still have an SSH tunnel floating around on linux-a. Find out what the process ID is and kill it.
output-stream-generating-command | ssh user@remotehost 'input-stream-accepting-command'
is an option, if your remote user has a valid shell.voretaq7 pointed out, that the sftp client doesn't support piped data transfer for users, that are allowed to use sftp only to connect to the server.
fortunately, there is libssh2, that supports sftp. so we just need 2 other clients using libssh2, that i've called:
the source code can be found under the following URL: http://www.qxs.ch/2012/07/05/sftp-upload-tool/
since i'm not that experienced in libssh2 programming, i'm happy for any feedback to the source code.