Home / Alt manpages / sftp(1)

  • sftp(1)
  • User command
  • linux

Transfer Files Safely with OpenSSH sftp

You will finish with a repeatable way to connect to an SSH server, inspect the remote directory, upload and download files, and resume a transfer without guessing which side of the connection a path belongs to. 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 transfer. You do not need root for normal file transfers. Remote ownership, permissions and server configuration are separate matters.

1. Check the installed client

Confirm that the command resolves to the expected binary and record the package version. These 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 uses an encrypted SSH transport. It can use the same key authentication and SSH configuration as ssh. SFTP is not FTP with a password prompt added, and it does not provide 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 from an untrusted location.

2. Connect and inspect the remote side

Start an interactive session with a real account and host name. Replace both placeholders, 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

The 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 evidence that the server is the one you intended to reach.

pwd reports the remote working directory. lpwd reports the local one. This distinction prevents a common error: commands such as ls, get and put operate on remote and local paths in different positions.

3. Download one remote file

Connect again, list the remote path, then use get. Here the 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. If you omit the local destination, get report.csv writes a file with the same name in the current local directory. Check lpwd first if that default would be surprising.

Safety warning

Downloading to an existing path may replace its contents. Choose a new name, or make a backup before using a destination that matters. The shell redirection operator is not involved here, so do not add one to an SFTP command.

4. Upload a file without changing the original

Use lcd to choose 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 does not delete or move the local original. If the remote name already exists, treat replacement as a destructive action: use a new name or ask the remote administrator how the destination is managed.

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

5. Resume an interrupted transfer carefully

Resume only when the partial file is known to be the same transfer. The client cannot prove that 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 differ, the resulting file can be corrupt. Remove or rename an untrusted partial file and perform a fresh transfer instead.

A transfer can also be started in batch mode, which is useful for a small reviewed job. Put 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 commands such as get, put, rm, mkdir or ls fail. Review the file before running it. Do not put a password in the batch file. Remove a temporary batch file after checking its contents if it contains sensitive paths or host details.

6. Handle paths and options deliberately

Quote remote paths containing spaces. 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 preserving those attributes is part of the job. -q suppresses progress and diagnostic messages, so leave it off while troubleshooting. -v raises logging detail and is useful 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. It is not fixed by running local sftp with sudo. Elevation changes the local process and may also 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 establish which side and directory you 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 as a 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 distinguish 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 when the partial file was trustworthy.
  • You know that ordinary transfers do not require sudo, and you have not used it to bypass remote permissions.