Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
How to upload a file(s), to a remote location in one go with sftp. Useful for automation.

Normally if you want to quickly send a file to a remote directory on an ssh server as a one liner or within a script, the following would suffice:

scp file server:path

Occasionally, you may come across a server that only has sftp enabled and not scp. For example if the OpenSSH server you were connecting to was configured as follows:

Subsystem sftp internal-sftp

Match User yourusername
  ChrootDirectory /home/%u
  ForceCommand internal-sftp

Then attempting to connect via scp, would result in the error message: "This service allows sftp connections only."

In such a case, you can simulate basic scp behaviour as follows:

echo put file | sftp -b- server:path

Alternatively, if you need to display the progress of the file as it uploads:

printf "progress\nput file" | sftp -b- server:path

If you need to upload multiple files, you could use a for loop:

for f in file1 file2 file3; do echo put "$f" | sftp -b- server:path; done

(If this example file* would also have worked as a wildcard in place of file1 file2 file3).

You can combine all of the above to make a very simple upload script like so:

#!/bin/sh
s="$1"
shift 1
for f in "$@"; do
  printf "progress\nput $f" | sftp -b- "$s" || exit 1
done

Give this a suitable name (e.g. upload-sftp) and use it as follows:

upload-sftp server:path file*

Using Bash instead of Bourne Shell would allow you to specify server:path as the last option (like scp), i.e.:

upload-sftp file* server:path 

To do that, use the following:

#!/bin/bash
eval s=\$$#
for f in "${@:1:$(($#-1))}"; do
  printf "progress\nput $f" | sftp -b- "$s" || exit 1
done

Note: Using sftp in this way requires non-interactive authentication using keys to be configured. You can set -oBatchMode=no to use password authentication but this would be cumbersome when uploading multiple files using the above example, as you would be prompted for a password before each file is uploaded.

P.S. Yes I know the man page specifically mentions the -b switch but some basic examples help.

@Lex-2008

This comment has been minimized.

Copy link

commented Dec 4, 2014

i would actually think (but i've never tried) that you can upload multiple files in one sftp session, like this:

for f in file1 file2 file3; do echo put "$f"; done | sftp -b- server:path

That would help if you have to use password authentication and want to avoid entering your password for every file.

@yougg

This comment has been minimized.

Copy link

commented Dec 12, 2016

upload multiple files by one line:

sftp {user}@{server}:{remote_path} <<< "put {localfiles}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.