Home / Alt manpages / sftp(1)

  • sftp(1)
  • User command
  • linux

Transfer Files Safely with OpenSSH sftp

Get remote and local paths backwards in sftp and you overwrite the wrong file instead of downloading one. This guide keeps the two straight: connect to an SSH server, poke around the remote directory, upload, download and resume a transfer with confidence. The examples use OpenSSH sftp from Ubuntu's openssh-client package, version 1:9.6p1-3ubuntu13.19 on the machine used for this guide.

Allow about fifteen minutes. You need the client package, a remote account with SSH and SFTP access, and a local file or directory you are allowed to move around. You do not need root for normal transfers; remote ownership, permissions and server configuration are separate matters that this guide does not touch.

1. Check the installed client

Confirm the command resolves to the binary you expect and note the package version. Both are ordinary, read-only checks:

$ command -v sftp
/usr/bin/sftp
$ dpkg-query -W -f='${Package} ${Version}\n' openssh-client
openssh-client 1:9.6p1-3ubuntu13.19

The client runs over an encrypted SSH transport and can reuse the same keys and SSH configuration as ssh. SFTP is not FTP with a password prompt bolted on, and it gives you no anonymous access by itself.

Checkpoint

If command -v sftp prints nothing, stop here and install the client through your normal system package process. Do not copy a binary in from an untrusted location.

2. Connect and inspect the remote side

Start an interactive session with a real account and host name, replacing both placeholders below, including the account if it differs from your local user:

$ sftp [email protected]
Connected to HOST.example.
sftp> pwd
Remote working directory: /home/USER
sftp> ls -la
sftp> lpwd
Local working directory: /home/USER
sftp> bye

A host key prompt may appear on the first connection. Read the fingerprint and verify it through a trusted channel before accepting it. A password prompt is expected when password authentication is enabled; it is not proof you have reached the server you intended.

This is the one habit worth building early: pwd reports the remote working directory, lpwd reports the local one. Commands such as ls, get and put take remote and local paths in different positions, and mixing them up is the classic sftp mistake.

3. Download one remote file

Connect again, list the remote path, then use get. Giving an explicit second path makes the local destination unambiguous:

$ mkdir -p "$HOME/sftp-downloads"
$ sftp [email protected]
sftp> cd /remote/path
sftp> ls -l report.csv
sftp> get report.csv /home/LOCAL_USER/sftp-downloads/report.csv
Fetching /remote/path/report.csv to /home/LOCAL_USER/sftp-downloads/report.csv
sftp> bye
$ test -s "$HOME/sftp-downloads/report.csv" && echo 'download exists and is non-empty'
download exists and is non-empty

Use your actual local home path instead of /home/LOCAL_USER. Omit the local destination and get report.csv writes a same-named file into your current local directory, so check lpwd first if that default would surprise you.

Safety warning

Downloading to an existing path can replace its contents. Choose a new name, or back up first, when the destination matters. There is no shell redirection involved here, so do not add one to an SFTP command.

4. Upload a file without changing the original

Use lcd to pick the local directory, then put to send a file to a known remote name:

$ sftp [email protected]
sftp> lcd /home/LOCAL_USER/outgoing
sftp> lpwd
Local working directory: /home/LOCAL_USER/outgoing
sftp> put package.tar.gz /remote/path/package.tar.gz
Uploading package.tar.gz to /remote/path/package.tar.gz
sftp> ls -l /remote/path/package.tar.gz
sftp> bye

put reads the local file and writes the remote destination; it never deletes or moves the local original. If the remote name already exists, treat overwriting it as a destructive action: pick a new name, or ask the remote administrator how that destination is managed.

To upload a whole directory tree, add -r to the client command or -R to the interactive put. SFTP does not follow symbolic links during recursive transfers. Check the target directory first, since a broad recursive upload can create more remote state than you meant to.

5. Resume an interrupted transfer carefully

Only resume when you actually know the partial file belongs to this transfer. The client has no way to prove an existing partial file has the right contents:

$ sftp [email protected]
sftp> reget large.iso /home/LOCAL_USER/sftp-downloads/large.iso
Fetching /remote/path/large.iso to /home/LOCAL_USER/sftp-downloads/large.iso
sftp> bye

reget is equivalent to get -a; for an upload, use reput, equivalent to put -a. If the partial local and remote contents actually differ, the result can be a corrupt file. Remove or rename an untrusted partial file and do a fresh transfer instead.

A transfer can also run in batch mode, useful for a small, reviewed job. Put the commands in a file and use non-interactive authentication:

$ sftp -b ./download.sftp [email protected]
$ cat ./download.sftp
cd /remote/path
get report.csv /home/LOCAL_USER/sftp-downloads/report.csv
bye

Batch mode aborts when a command such as get, put, rm, mkdir or ls fails, so review the file before running it. Never put a password in the batch file, and remove a temporary batch file once you've checked its contents if it contains sensitive paths or host details.

6. Handle paths and options deliberately

Quote remote paths containing spaces, and escape glob characters when you mean a literal character rather than a pattern:

sftp> get "Quarterly report.csv" ./reports/
sftp> ls 'archive[2026].tar'
sftp> get archive\[2026\].tar ./reports/

For a non-standard SSH port, use the SFTP option -P with a capital letter, or pass the SSH configuration option explicitly:

$ sftp -P 2222 [email protected]
$ sftp -oPort=2222 [email protected]
  • -p preserves modification times, access times and modes for transferred files. Use it only when keeping those attributes is actually part of the job.
  • -q suppresses progress and diagnostic messages, so leave it off while you are troubleshooting.
  • -v raises logging detail, handy when authentication or connection setup fails.

7. Diagnose failures without escalating blindly

A permission error on a remote path is normally fixed by choosing a permitted path or asking the remote administrator, not by running local sftp with sudo. Elevation changes the local process and can change which SSH keys and configuration files it uses.

For connection diagnostics, retry with verbose logging:

$ sftp -v [email protected]

For a missing file, use pwd, lpwd and ls -l to pin down which side and directory you actually meant. For a failed batch transfer, run the same commands interactively first. For a rejected host key, stop and verify the host identity rather than deleting known-hosts entries out of reflex.

Done means

  • You checked the installed sftp binary and OpenSSH client version.
  • You verified the host key before accepting a first connection.
  • You can tell apart pwd from lpwd, and remote paths from local paths.
  • You downloaded and uploaded using explicit destinations, leaving the local source intact.
  • You only resumed a transfer once the partial file was trustworthy.
  • You know ordinary transfers need no sudo, and you have not used it to bypass remote permissions.