FTP, the File Transfer Protocol, was a popular and unencrypted method of transferring files between two remote systems. As of 2022, it has been rendered obsolete by most modern software due to a lack of security, and can mostly only be used in legacy applications.
SFTP, which stands for Secure File Transfer Protocol, is a separate packaged protocol built into SSH that can implement FTP commands over a secure connection. It can usually act as a direct replacement in any context where an FTP server is still needed.
In almost all cases, SFTP is preferable to FTP because of its underlying security features and its ability to leverage an SSH connection. FTP is an insecure protocol that should only be used in limited cases or on networks you trust.
Although SFTP is built into many graphical tools, this guide will demonstrate how to use it through its interactive command-line interface.
How to connect with
By default, SFTP uses the SSH protocol to authenticate and establish a secure connection. Because of this, the same authentication methods are available that are present in SSH.
Although you can authenticate with passwords by default, we recommend that you create SSH keys and transfer your public key to any system you need to access. This is much safer and can save you time in the long run.
See this guide to setting up SSH keys to access your server if you haven’t already.
If you can connect to the machine using SSH, then you have completed all the necessary requirements to use SFTP to manage files. Test SSH access with the
following command: ssh sammy@your_server_ip_or_remote_hostname
If that works, exit again by typing
Now we can establish an SFTP session by issuing the following command:
It will connect the remote system and its message will change to an SFTP prompt.
If you are working on a custom SSH port (not the default port 22), you can open an SFTP session as follows:
- sftp -oPort=custom_port sammy@your_server_ip_or_remote_hostname
This will connect you to the remote system through the specified port
Get help in SFTP
The most useful command to learn first is the help command. This gives you access to a summary of the other SFTP commands. You can call him by typing any of these in the message
This will display a list of available commands
: OutputAvailable commands: bye Exit the sftp cd path Change the remote directory to ‘path’ chgrp path Change file group ‘path’ to ‘grp’ chmod mode path Change the permissions of the ‘path’ file to ‘mode’ chown path Change the owner of the ‘path’ file to ‘own’ df [-hi] [path] Show Statistics for the current directory
file system containing ‘path’ exit Exit sftp get [-Ppr] remote [local] Download help file help Display this help text lcd path Change local directory to ‘path’ . . .
We’ll explore some of the commands you’ll see in the following sections.
Navigation with SFTP
We can navigate through the file hierarchy of the remote system using a series of commands that work similarly to their shell counterparts
First, let’s get our bearings by figuring out which directory we are currently in on the remote system. As in a typical shell session, we can type the following to get
the current directory:
OutputRemote working directory: /home/demouser
We can view the contents of the current directory of the remote system with another familiar command:
OutputSummary.txt info.html temp.txt testDirectory
Note that the commands available within the SFTP interface are not a 1:1 match to typical shell syntax and are not as feature-rich. However, they implement some of the most important optional flags, such as adding -la to ls to see more metadata and file permissions: ls -la
Outputdrwxr-xr-x 5 demouser demouser 4096 Aug 13 15:11.
drwxr-xr-x 3 root root 4096 Aug 13 15:02 .. -rw- 1 demouser demouser 5 Aug 13 15:04 .bash_history -rw-r-r- 1 demouser demouser 220 Aug 13 15:02 .bash_logout -rw-r-r- 1 demouser demouser 3486 Aug 13 15:02 .bashrc drwx- 2 demouser demouser 4096 Aug 13 15:04 .cache -rw-r-r- 1 demouser demouser 675 Aug 13 15:02 .profile . . .
To get to another directory, we can issue this command:
- cd testDirectory
Now we can traverse the remote file system, but what if we need to access our local file system? We can direct commands to the local file system preceding them with an l for local.
All commands discussed so far have local equivalents.
We can print the local working directory:
Working directory OutputLocal: /Users/demouser We can list the contents of the current directory on the local machine:
Local OutputDesktop.txt test.html Document analysis.rtf zebra.html
We can also change the directory with which we want to interact in the local system:
- lcd Desktop
File transfer with SFTP
If we want to download files from our remote host, we can do it using
the command get: get remoteFile OutputFetching /home/demouser/remoteFile to remoteFile /home/demouser/
100% 37KB 36.8KB/s 00:01
As you can see, by default, the get command downloads
a remote file to a file with the same name on the local file system.
We can copy the remote file with a different name by specifying the name after:
- remoteFile localFile
The get command also accepts some option flags. For example, we can copy a directory and all its contents by specifying the recursive option
: get -r someDirectory
We can tell SFTP to maintain the appropriate permissions and access times using the -P flag or -p:
- get -Pr someDirectory
Transferring local files to the remote system File transfer to the remote
works the same way, but with a put command
: put localFile OutputUploading localFile to /home/demouser/localFile
100% 7607 7.4KB/s 00:00
The same flags they work with apply to put. So, to copy an entire local directory, you can run
- put -r localDirectory
A familiar tool that is useful when downloading and uploading files is the df command, which works similarly to the command-line version. With this, you can verify that you have enough space to complete the transfers you are interested in:
- df -h Output size
used Available (root) %Capacity 19.9GB 1016MB 17.9GB 18.9GB 4%
Note that there is no local variation of this command, but we can avoid it by issuing the !
The ! command places us in a local shell, where we can execute any command available on our local system. We can check the disk usage by typing:
- df -h
OutputFilesystem Size used Availability capability Mounted on /dev/disk0s2 595Gi 52Gi 544Gi 9% / devfs 181Ki 181Ki 0Bi 100% /dev map -hosts 0Bi 0Bi 0Bi 100% /net map auto_home 0Bi 0Bi 0Bi 100% /home
Any other local command will work as expected. To return to the SFTP session, type:
You should now see the return of the
Simple file manipulations with SFTP SFTP
allows you to perform some types of file system maintenance. For example, you can change the owner of a file on the remote system with:
- chown userID file
Notice how, unlike the system chmod command, the SFTP command does not accept user names, but uses UID. Unfortunately, there is no built-in way to know the appropriate UID from the SFTP interface.
As a workaround, you can read the /etc/passwd file, which associates usernames with UIDs in most Linux environments
: get /etc/passwd
- !less passwd Outputroot
:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync: x:4:65534: sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh . . .
Notice how instead of giving the ! command itself, we have used it as a prefix for a local shell command. This works to execute any command available on our local machine and could have been used with the local df command previously.
The UID will be in the third column of the file, delineated by a colon.
Similarly, we can change the group owner of a file with:
- chgrp groupID file
Again, there is no built-in way to get a list of remote system groups. We can solve it with the following command
- get /etc/
- !less group
Outputroot:x:0: daemon:x:1: bin:x:2: sys:x:3: adm:x:4: tty:x:5: disk:x:6: lp:x:7: . . .
The third column contains the ID of the group associated with the name in the first column. This is what we are looking for.
SFTP command works normally
on the remote file system:
- chmod 777
publicFile OutputMode switching in /home/demouser/publicFile There is no equivalent command to manipulate local file permissions,
but you can set the local mask, so that any file copied to the local system has its corresponding permissions. That
can be done with the lumask command:
lumask 022 OutputLocal mask:
Now all normal downloaded files
(as long as the -p flag is not used) will have 644 permissions
SFTP also allows you to create directories on local and remote systems with lmkdir and mkdir respectively.
All other file commands
target only the remote file system:
These commands replicate the core behavior of their shell counterparts. If you need to perform these actions on the local file system, remember that you can place it in a shell by issuing this command
run a single command on the local system by prepending the command with ! like this:
- !chmod 644 somefile
When you are finished with your SFTP session, use exit or bye to close the connection.
Although SFTP syntax is much less comprehensive than modern shell tools, it can be useful for providing support for legacy FTP syntax or for carefully limiting functionality Available to remote users in some environments.
For example, you can use SFTP to allow home users to transfer files without SSH access. For more information on this process, see our tutorial on How to enable SFTP without shell access.
If you’re used to using FTP or SCP to make your transfers, SFTP is a good way to leverage the strengths of both. While not appropriate for every situation, it is a flexible tool to have in your repertoire.