sftp — quick reference
One-liner transfers
Download or upload a single file without opening the sftp> prompt. Use user@host:remote_path for the remote side.
| When to use | Command |
|---|---|
| Download one remote file to a local path | sftp user@host:/remote/file /local/dir/ |
| Download a remote directory tree | sftp -r user@host:/remote/dir /local/parent/ |
| Upload one local file with a inline command string | sftp user@host:/remote/dir/ <<< $'put /local/file' |
| Upload using a here-document (several commands) | sftp user@host <<EOFput /local/file /remote/pathbyeEOF |
Batch mode (-b)
Run a list of SFTP commands from a file or stdin — best for cron, CI, and repeatable uploads.
| When to use | Command |
|---|---|
| Run commands from a batch file (non-interactive) | sftp -b /path/batch.txt user@host |
Pipe commands on stdin (- means stdin) |
sftp -b - user@host <<'BATCH'get /remote/file /local/filebyeBATCH |
Batch file must end each line with bye or quit |
echo -e 'get /remote/f\\nbye' > batch.txt |
Connection and SSH options
SFTP reuses the SSH client stack. Pass host, port, keys, and ssh_config the same way as ssh.
| When to use | Command |
|---|---|
Custom SSH port (-P is sftp; -p is ssh — do not swap) |
sftp -P 2222 user@host |
| Same port via SSH option syntax | sftp -o Port=2222 user@host |
| Use a specific private key | sftp -i ~/.ssh/id_ed25519 user@host |
| Load client settings from a config file | sftp -F /path/ssh_config user@host |
| Fail instead of prompting for a password (scripts) | sftp -o BatchMode=yes user@host |
| Force password auth when keys are also present | sftp -o PreferredAuthentications=password -o PubkeyAuthentication=no user@host |
Password automation (sshpass)
Only when keys are impossible — requires the sshpass package (apt install sshpass / dnf install sshpass).
| When to use | Command |
|---|---|
| Supply password on the command line (avoid in shared history) | sshpass -p 'PASSWORD' sftp -o BatchMode=no user@host:/remote/ <<< $'put /local/file' |
| Read password from an environment variable | SSHPASS='secret' sshpass -e sftp -b batch.txt user@host |
| Read password from a restricted file | sshpass -f /root/.sftp_pass sftp -b batch.txt user@host |
Package installs and updates in this section use dnf command.
sftp — command syntax
Synopsis from sftp usage on Ubuntu 25.04 (OpenSSH 9.9p1):
sftp [-46AaCfNpqrv] [-B buffer_size] [-b batchfile] [-c cipher]
[-D sftp_server_command] [-F ssh_config] [-i identity_file]
[-J destination] [-l limit] [-o ssh_option] [-P port]
[-R num_requests] [-S program] [-s subsystem | sftp_server]
[-X sftp_option] destinationRemote paths use [[user@]host[:port]][:path] or a URI sftp://[user@]host[:port][/path]. With -b, SFTP runs each batch line and exits — no interactive sftp> session.
sftp — command examples
Essential Download one file without the sftp> prompt
Pull a single remote file into a local directory — useful in scripts when you do not want to open an interactive SFTP shell.
Run the command (localhost used as both client and server in this lab):
sftp localhost:/tmp/sftp-lab/remote/testfile.txt /tmp/sftp-lab/local/oneliner.txtSample output:
Connected to localhost.
Fetching /tmp/sftp-lab/remote/testfile.txt to /tmp/sftp-lab/local/oneliner.txtConfirm the file landed locally:
cat /tmp/sftp-lab/local/oneliner.txtSample output:
remote-file-contentIf you omit the local path, SFTP saves the file under your current working directory using the remote basename.
Essential Upload one file with a here-string (<<<)
Send one put command without a here-document block — handy for short cron lines.
Run the command:
sftp localhost:/tmp/sftp-lab/remote/ <<< $'put /tmp/sftp-lab/local/upload.txt'Sample output:
Connected to localhost.
Changing to: /tmp/sftp-lab/remote/
sftp> put /tmp/sftp-lab/local/upload.txt
Uploading /tmp/sftp-lab/local/upload.txt to /tmp/sftp-lab/remote/upload.txtVerify on the remote side (same host in this lab):
cat /tmp/sftp-lab/remote/upload.txtSample output:
local-uploadThe <<< $'...' form feeds one line to SFTP's stdin after connect; quote remote paths with spaces carefully.
Essential Batch file (-b) for scripted transfers
Put multiple SFTP commands in a text file and let -b run them non-interactively — the usual pattern for automation.
Create a batch file:
cat > /tmp/sftp-lab/batch/get.txt << 'EOF'
get /tmp/sftp-lab/remote/testfile.txt /tmp/sftp-lab/local/downloaded.txt
bye
EOFRun batch mode:
sftp -b /tmp/sftp-lab/batch/get.txt localhostSample output:
sftp> get /tmp/sftp-lab/remote/testfile.txt /tmp/sftp-lab/local/downloaded.txt
sftp> byeCheck the download:
cat /tmp/sftp-lab/local/downloaded.txtSample output:
remote-file-contentBatch mode aborts on the first failing command unless you pass -oBatchMode together with error-handling in your wrapper script.
Common Here-document for several commands
When you need cd, mkdir, put, or get in one shot, a here-document is clearer than chaining <<< lines.
Run the commands:
sftp localhost <<EOF
put /tmp/sftp-lab/local/upload.txt /tmp/sftp-lab/remote/uploaded-via-heredoc.txt
bye
EOFSample output:
Connected to localhost.
sftp> put /tmp/sftp-lab/local/upload.txt /tmp/sftp-lab/remote/uploaded-via-heredoc.txt
Uploading /tmp/sftp-lab/local/upload.txt to /tmp/sftp-lab/remote/uploaded-via-heredoc.txt
sftp> byeConfirm:
cat /tmp/sftp-lab/remote/uploaded-via-heredoc.txtSample output:
local-uploadEnd with bye or quit so the session closes cleanly in scripts.
Common Download a directory with -r
Mirror a remote folder tree in one command line — equivalent to get -r inside an interactive session.
Run the command:
sftp -r localhost:/tmp/sftp-lab/remote/testdir /tmp/sftp-lab/local/Sample output:
Connected to localhost.
Fetching /tmp/sftp-lab/remote/testdir/ to /tmp/sftp-lab/local/testdir
Retrieving /tmp/sftp-lab/remote/testdirList what arrived:
find /tmp/sftp-lab/local/testdir -type fSample output:
/tmp/sftp-lab/local/testdir/inner.txtRecursive uploads often need a here-doc (put -r) because a single URL-style one-liner cannot express every remote layout.
Common Batch commands from stdin (sftp -b -)
Keep commands inside the script without maintaining a separate batch file on disk.
Run the commands:
sftp -b - localhost <<'BATCH'
get /tmp/sftp-lab/remote/testdir/inner.txt /tmp/sftp-lab/local/inner.txt
bye
BATCHSample output:
sftp> get /tmp/sftp-lab/remote/testdir/inner.txt /tmp/sftp-lab/local/inner.txt
sftp> byeVerify:
cat /tmp/sftp-lab/local/inner.txtSample output:
inside dirQuote the delimiter (<<'BATCH') so the shell does not expand variables inside the batch lines.
Common BatchMode=yes for key-only automation
Cron and CI jobs should fail fast when a password would be required — BatchMode=yes tells SSH not to prompt.
Run the command:
sftp -o BatchMode=yes -i ~/.ssh/id_ed25519 [email protected]:/data/file.tar.gz /var/backups/Sample output (success):
Connected to backup.example.com.
Fetching /data/file.tar.gz to /var/backups/file.tar.gzSample output (no usable key — exits non-zero):
[email protected]: Permission denied (publickey,password).
Connection closedPair this with key-based login; see ssh command for ssh-copy-id setup.
Advanced sshpass when keys are not available
Some legacy hosts only allow password auth. sshpass wraps SFTP for one-line uploads — install the package first, and prefer a secrets file over literals in shell history.
Install (once per host):
sudo apt install -y sshpassRun a password-backed batch upload:
sshpass -f /root/.sftp_pass sftp -o StrictHostKeyChecking=accept-new -b /tmp/upload.ba [email protected]Sample batch file /tmp/upload.ba:
cd incoming
put /var/reports/daily.csv
byeSample output:
sftp> cd incoming
sftp> put /var/reports/daily.csv
Uploading /var/reports/daily.csv to /incoming/daily.csv
sftp> byeRestrict permissions on the password file (chmod 600) and migrate to SSH keys when possible — passwords in scripts are a last resort.
Advanced Non-default SSH port (-P)
When sshd listens on something other than port 22, tell SFTP explicitly — -P is the sftp front-end flag (uppercase).
Run the command:
sftp -P 2222 -o User=deploy sftp.example.com:/releases/app.tgz /tmp/Sample output:
Connected to sftp.example.com.
Fetching /releases/app.tgz to /tmp/app.tgzEquivalent using SSH option syntax:
sftp -o Port=2222 [email protected]:/releases/app.tgz /tmp/Do not confuse sftp -P (port) with ssh -p (lowercase) — they are different binaries with different flag letters.
sftp — when to use / when not
| Use non-interactive sftp when | Use something else when |
|---|---|
|
|
sftp vs scp
| sftp (batch / one-liner) | scp | |
|---|---|---|
| Best for | chrooted SFTP-only accounts, multi-step cd + put scripts |
single-file or recursive copy in one command |
| Remote shell | SFTP subsystem only | requires scp/ssh on server |
| Scripting | -b batch files, here-docs |
scp host:path local one-liners |
| Resume / sync | limited | use rsync instead |
See the scp command for direct copy syntax.
Related commands
File transfer and remote access around the same SSH stack.
| Command | One line |
|---|---|
| sftp | SFTP over SSH — batch and one-liner transfers (this page) |
Browse the full index in our Linux commands reference.
sftp — interview corner
What is SFTP in Linux?
SFTP (SSH File Transfer Protocol) moves files over an encrypted SSH connection. It is not classic FTP — there is no separate FTP port or cleartext passwords.
On Linux, the sftp client is part of OpenSSH. It can run interactively (sftp user@host then sftp> prompts) or non-interactively with URL-style paths, -b batch files, and here-documents — which is what this cheat sheet focuses on.
A strong answer is:
"SFTP is file transfer over SSH. I use one-liners or sftp -b batch files in scripts, and scp or rsync when a single copy or sync job is enough."
How do you run SFTP without an interactive prompt?
Three common patterns:
- URL-style one-liner —
sftp user@host:/remote/file /local/dir/ - Batch file —
sftp -b commands.txt user@hostwhere each line is an SFTP command - Here-doc — feed multiple commands to
sftp user@host <<EOF ... EOF
For cron jobs, add -o BatchMode=yes and SSH keys so the job fails instead of hanging on a password prompt.
A strong answer is:
"I use sftp -b for scripts, or a one-liner path for a single get/put. BatchMode=yes plus keys keeps cron jobs non-interactive."
When would you pick sftp over scp?
Pick sftp when:
- The account is chrooted to SFTP only (no scp shell)
- You need several remote steps (
cd,mkdir, thenput) in one scripted session - Policy mandates the SFTP subsystem
Pick scp for a quick one-shot file or recursive copy when both sides allow it.
A strong answer is:
"scp for simple copies; sftp when the server is SFTP-only or my script needs cd/mkdir/put steps in one batch."
How do you automate SFTP with a password?
Preferred order:
- SSH keys (
ssh-copy-id, thensftp -i key user@host) sshpassonly if keys are impossible —sshpass -f /secure/file sftp -b batch user@host
Never hard-code passwords in world-readable scripts. Restrict the password file to root (chmod 600).
A strong answer is:
"Keys first. If I must use a password, sshpass with a restricted file and sftp -b — never plaintext passwords in shell history."
How do you use SFTP on a non-default port?
Use sftp -P PORT (uppercase P on the sftp command) or pass -o Port=PORT through the SSH option stack:
sftp -P 2222 user@host:/path/file /tmp/Do not confuse with ssh -p (lowercase) — different command, different flag.
A strong answer is:
"sftp -P 2222 or sftp -o Port=2222 — uppercase P on sftp, not ssh's lowercase -p."
Troubleshooting
For Connection refused, verify the SFTP/SSH port on the server with ss -tlnp before retrying sftp -P; the ss command documents listener checks.
| Symptom | Likely cause | What to try |
|---|---|---|
Permission denied (publickey,password) with BatchMode=yes |
No key loaded or wrong user | ssh -i key user@host, confirm BatchMode is off for password tests |
Connection refused |
Wrong host or port | sftp -P PORT, verify sshd listens with ss -tlnp | grep ssh on server |
Batch exits immediately with Host key verification failed |
Unknown host key | Pre-seed with ssh-keyscan host >> ~/.ssh/known_hosts or use StrictHostKeyChecking=accept-new once |
Couldn't canonicalize: No such file or directory on put -r |
Remote parent dir missing | mkdir on remote first (here-doc), then put -r |
sshpass: command not found |
Package not installed | sudo apt install sshpass or sudo dnf install sshpass |
| Hangs in cron | Waiting for password | Keys + BatchMode=yes; avoid password auth in unattended jobs |
References
Scope: non-interactive SFTP one-liners, batch files, here-docs, and sshpass patterns only — not a full interactive sftp> command tutorial.

