Files, tunnels, and jumps
Transfer files with scp and sftp
Choose batch copy or interactive file transfer and verify direction, destination, permissions, and integrity.
File transfer over SSH reuses everything you set up so far. Same host key, same user key, same notes-server alias. What it adds is a new way to make mistakes: paths.
scp copies files in one shot, like cp with a remote side. sftp opens an interactive session where you ls, cd, put, and get. I use scp in scripts and sftp when I want to look around before I touch anything.
Upload to a staging name
Say we have a release archive to ship. Do not copy it straight onto the path the app reads from. Copy it next to that path, under a name nothing uses yet:
scp release.tar.gz notes-server:/var/www/notes/release.tar.gz.part
release.tar.gz 100% 12MB 4.1MB/s 00:02
The source is first, the destination second. Swap them and scp tries to download a file that does not exist, or worse, overwrites your local copy with an old remote one. Say the direction out loud before you press Enter.
Verify before you use it
A transfer can finish and still be wrong: truncated, the wrong file, an old build. Compare checksums on both sides:
shasum -a 256 release.tar.gz
ssh notes-server 'sha256sum /var/www/notes/release.tar.gz.part'
3f7a1c...e29b release.tar.gz
3f7a1c...e29b /var/www/notes/release.tar.gz.part
Same hash, same bytes. Now move it into place, which on the same filesystem is atomic:
ssh notes-server 'mv /var/www/notes/release.tar.gz.part /var/www/notes/release.tar.gz'
Check what you left behind
scp creates files with your local mode filtered by the remote umask, owned by the user you connected as. Look:
ssh notes-server 'ls -l /var/www/notes/release.tar.gz'
-rw-r--r-- 1 deploy deploy 12582912 Sep 8 11:02 /var/www/notes/release.tar.gz
If the web server runs as a different user, or the file must not be world-readable, fix that now with chmod and chown, on purpose, rather than discovering it in an error log later.
The same thing interactively
sftp is useful when you are not sure where things live:
sftp notes-server
sftp> cd /var/www/notes
sftp> ls -l
sftp> put release.tar.gz release.tar.gz.part
sftp> get /var/log/nginx/error.log
sftp> bye
put uploads, get downloads. lls and lcd act on your local side. Everything else acts on the server.
Break it once
Try scp release.tar.gz notes-server:/var/www/notes/ from a shell where release.tar.gz does not exist. You get No such file or directory locally and nothing changes on the server. Now try uploading to a directory deploy cannot write to, like /etc/. The transfer fails with Permission denied and again nothing changes. Both are cheap failures. The expensive one is a successful copy to the wrong place, and only checksums and ls -l catch that.
For syncing whole directories, rsync over SSH is the better tool. The SSH for developers post covers it.
Lesson completed