I got myself into a situation where I had to copy some files from my computer to a server that presented sftp but not scp. Since I’ve never needed to use the sftp protocol from a cli-only machine, I haven’t really thought about how it works in non-interactive mode. Batch mode allows you to create a batch file of sftp commands to execute on the server, but what if you just want to do a single operation?
Pipes to the rescue:
$ echo put filename.tgz | sftp -i private.key -b - email@example.com
Putting a dash after the -b option causes the command to take batch input from stdin. Piping text to the command, then, means that text is swallowed by the sftp client. Nice and simple.