Skip to content

Instantly share code, notes, and snippets.

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:

shift 1
for f in "$@"; do
  printf "progress\nput $f" | sftp -b- "$s" || exit 1

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:

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

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.


This comment has been minimized.

Copy link

Lex-2008 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.


This comment has been minimized.

Copy link

yougg 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.