SFTP One-Line Commands in Linux: Batch, Here-Docs, and Non-Interactive Transfers

SFTP transfers files over SSH. This page covers non-interactive one-liners — URL-style paths, batch files (-b), here-documents, and sshpass patterns — for scripts and cron jobs, not an interactive SFTP shell tutorial.

Published

Updated

Read time 10 min read

Reviewed byDeepak Prasad

SFTP One-Line Commands in Linux: Batch, Here-Docs, and Non-Interactive Transfers
About SFTP transfers files over SSH. This page covers non-interactive one-liners — URL-style paths, batch files (-b), here-documents, and sshpass patterns — for scripts and cron jobs, not an interactive SFTP shell tutorial.
Tested on Ubuntu 25.04 (Plucky Puffin); OpenSSH_9.9p1 Ubuntu-3ubuntu3.2; kernel 7.0.0-27-generic
Package openssh-client (apt/deb) · openssh-clients (dnf/rpm)
Man page sftp(1)
Privilege user (remote account permissions apply)
Distros

Ubuntu, Debian, RHEL, Fedora, and other systems with OpenSSH client.

For passwordless automation, prefer SSH keys. For large sync jobs, see rsync or scp.

Related guide

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 <<EOF
put /local/file /remote/path
bye
EOF

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/file
bye
BATCH
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):

text
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] destination

Remote 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):

bash
sftp localhost:/tmp/sftp-lab/remote/testfile.txt /tmp/sftp-lab/local/oneliner.txt

Sample output:

text
Connected to localhost.
Fetching /tmp/sftp-lab/remote/testfile.txt to /tmp/sftp-lab/local/oneliner.txt

Confirm the file landed locally:

bash
cat /tmp/sftp-lab/local/oneliner.txt

Sample output:

text
remote-file-content

If 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:

bash
sftp localhost:/tmp/sftp-lab/remote/ <<< $'put /tmp/sftp-lab/local/upload.txt'

Sample output:

text
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.txt

Verify on the remote side (same host in this lab):

bash
cat /tmp/sftp-lab/remote/upload.txt

Sample output:

text
local-upload

The <<< $'...' 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:

bash
cat > /tmp/sftp-lab/batch/get.txt << 'EOF'
get /tmp/sftp-lab/remote/testfile.txt /tmp/sftp-lab/local/downloaded.txt
bye
EOF

Run batch mode:

bash
sftp -b /tmp/sftp-lab/batch/get.txt localhost

Sample output:

text
sftp> get /tmp/sftp-lab/remote/testfile.txt /tmp/sftp-lab/local/downloaded.txt
sftp> bye

Check the download:

bash
cat /tmp/sftp-lab/local/downloaded.txt

Sample output:

text
remote-file-content

Batch 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:

bash
sftp localhost <<EOF
put /tmp/sftp-lab/local/upload.txt /tmp/sftp-lab/remote/uploaded-via-heredoc.txt
bye
EOF

Sample output:

text
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> bye

Confirm:

bash
cat /tmp/sftp-lab/remote/uploaded-via-heredoc.txt

Sample output:

text
local-upload

End 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:

bash
sftp -r localhost:/tmp/sftp-lab/remote/testdir /tmp/sftp-lab/local/

Sample output:

text
Connected to localhost.
Fetching /tmp/sftp-lab/remote/testdir/ to /tmp/sftp-lab/local/testdir
Retrieving /tmp/sftp-lab/remote/testdir

List what arrived:

bash
find /tmp/sftp-lab/local/testdir -type f

Sample output:

text
/tmp/sftp-lab/local/testdir/inner.txt

Recursive 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:

bash
sftp -b - localhost <<'BATCH'
get /tmp/sftp-lab/remote/testdir/inner.txt /tmp/sftp-lab/local/inner.txt
bye
BATCH

Sample output:

text
sftp> get /tmp/sftp-lab/remote/testdir/inner.txt /tmp/sftp-lab/local/inner.txt
sftp> bye

Verify:

bash
cat /tmp/sftp-lab/local/inner.txt

Sample output:

text
inside dir

Quote 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:

bash
sftp -o BatchMode=yes -i ~/.ssh/id_ed25519 [email protected]:/data/file.tar.gz /var/backups/

Sample output (success):

text
Connected to backup.example.com.
Fetching /data/file.tar.gz to /var/backups/file.tar.gz

Sample output (no usable key — exits non-zero):

text
[email protected]: Permission denied (publickey,password).
Connection closed

Pair 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):

bash
sudo apt install -y sshpass

Run a password-backed batch upload:

bash
sshpass -f /root/.sftp_pass sftp -o StrictHostKeyChecking=accept-new -b /tmp/upload.ba [email protected]

Sample batch file /tmp/upload.ba:

text
cd incoming
put /var/reports/daily.csv
bye

Sample output:

text
sftp> cd incoming
sftp> put /var/reports/daily.csv
Uploading /var/reports/daily.csv to /incoming/daily.csv
sftp> bye

Restrict 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:

bash
sftp -P 2222 -o User=deploy sftp.example.com:/releases/app.tgz /tmp/

Sample output:

text
Connected to sftp.example.com.
Fetching /releases/app.tgz to /tmp/app.tgz

Equivalent using SSH option syntax:

bash
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
  • You need a scripted get/put from cron, CI, or a deploy hook
  • A batch file or here-doc can express the whole transfer
  • The remote side only exposes the SFTP subsystem (common for chrooted upload accounts)
  • You want OpenSSH's native client on any Unix host without extra packages
  • You are browsing files interactively at the sftp> prompt → use an SFTP client GUI or an interactive session (out of scope here)
  • You need fast incremental sync or resumes → rsync over SSH
  • One-shot copy with simpler syntax → scp
  • Large tree mirroring with checksumming → rsync
  • Windows desktop drag-and-drop → WinSCP or FileZilla (not command-line sftp)

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.


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:

  1. URL-style one-linersftp user@host:/remote/file /local/dir/
  2. Batch filesftp -b commands.txt user@host where each line is an SFTP command
  3. 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, then put) 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:

  1. SSH keys (ssh-copy-id, then sftp -i key user@host)
  2. sshpass only 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:

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

Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive …