Is there a way to do a remote "ls" much like "scp" does a remote copy in a standard linux shell?
7 Answers
You could always do this:
ssh user@host ls -l /some/directory
That will SSH to the host, run ls, dump the output back to you and immediately disconnect.

- 2,379
- 1
- 18
- 23
-
9... if you have real shell access. Some systems have a special shell which will only accept certain `scp` and `rsync` calls, maybe `sftp` as well, and that's it. – glglgl Jun 06 '14 at 22:11
-
-
3@WalrustheCat `alias rls="ssh user@host ls -l"` Restart your shell and `rls /some/directory` should work. – chishaku Oct 10 '15 at 09:17
-
The only problem with this is that file not found returns an error code,when my reason for doing it is precisely why I want to call ls. – Steve Cohen Nov 28 '17 at 18:54
-
Not following @SteveCohen. Are you wanting the error code from the remote ls? If so, $? contains it right after you execute the command. (e.g. it returns 2 if I run this [locally or remotely] on a file that is not found) – Corey S. Nov 28 '17 at 23:42
-
No, exactly the opposite. I DON'T want error codes at all from ls.I'm running this as an Exec in a gradle script. Executing ls under via ssh transfers its error code (2) as the error code of the ssh invocation. I DON'T want this to be an error code, as the whole point of doing ls in my case is to see if a file exists on the remote. In my admittedly unusual case, I can workaround this with find instead of ls. If the output of find contains 0 lines, then the file is not present on the remote. If non-zero, then it is present. That is what I want, without all the error-code complications. – Steve Cohen Dec 06 '17 at 23:01
To list all files in a directory:
rsync host.name.com:directory/path/'*'
For something like find directory/path -ls
rsync -r host.name.com:directory/path

- 191
- 1
- 2
-
1If rsync is not installed on the host, then you get something like `bash: rsync: command not found`. I guess this implies it's using SSH in the background? – mwfearnley Sep 25 '15 at 10:23
-
Note the the format is similar to `ls -l`. On my system, it doesn't look like there is an option to just list the files. – Jonathan May 03 '16 at 11:37
-
@mwfearnley: No, although most packaging will define ssh as a recommendation or dependency for rsync, its quite possible to install one without the other. – symcbean Sep 11 '20 at 23:03
For all coming via google to this question because they are looking for a way to list remote files but can not access the remote server via ssh (common case for backup servers) you could use 'sftp'.
Example:
sftp username@hostname.xyz
ls
cd somedir
exit
Start an interactive session in a specific remote directory:
sftp [user@]host[:dir]

- 169
- 1
- 7
Yes. SSH and do an ls
:
ssh host ls /path
You could easily script this to be more flexible, or use the host:path syntax scp
uses.

- 10,982
- 2
- 34
- 29
As mentioned, if you can SSH into the host, you can do whatever you like.
You can use either ssh user@host
or ssh alias
(defined in ~/.ssh/config
)
Examples
Edit: Fixed some examples by single quoting the entire command to be sent. Thanks @dave_thompson_085 for pointing to the problem.
$ ssh user@host 'ls /dir/file'
You mentioned that you don't want to receive the errors from ls
if the file does not exist.
One option is to just discard the error messages
$ ssh user@host 'ls /dir/file 2>/dev/null'
This will preserve the return as well. So $?
will be 0 only if the ls command found /dir/file. This is nice because it works for files, folders, symlinks or anything that can be listed by ls.
Another option is to check if the file exists before listing.
$ ssh user@host '[ -f /dir/file ] && ls /dir/file'
You could also test and list a folder, but the syntax changes
$ ssh user@host '[ -d /dir/sub ] && ls /dir/sub'
You could chain and test for ANY as well
$ ssh user@host '[ -f /dir/file ] || [ -d /dir/file ] && ls /dir/file'
You could also just check if the item exists and nothing else
$ ssh user@host '[ -f /dir/file ] || [ -d /dir/file ]'
$ echo $? # exit code will be 0 ONLY if the file exists
0
You may want to include a test for symlinks with [ -L /my/target ]
as well.
You could run conditional codes remotelly
$ ssh user@host '[ -f /dir/file ] && echo "File EXISTS!" || echo "File NOT FOUND!"'
File EXISTS!
Or locally if you move the commands outside the command string
$ ssh user@host '[ -f /dir/file ]' && echo "File EXISTS!" || echo "File NOT FOUND!"
File EXISTS!
The way quoting and expansion works can be tricky though. If you use double quotes outside the main command (instead of single quotes as above), variables will be expanded BEFORE connecting ssh, unless you escape the $
. It is normally easier to use single quotes to avoid that, but your mileage may vary. Some times you need stuff to expand locally AND remotelly, which can be tricky.

- 121
- 2
-
Your 2nd example is wrong; the `ls` runs locally, or tries to. Similarly in your 5th example the `echo`'s run locally (which is okay for echo) and in your 6th example `{ }` does not change that. Lastly, for shells with history expansion, normally interactive bash and zsh, `echo "FILE EXISTS!"` doesn't work (anywhere, not just with `ssh`). – dave_thompson_085 Sep 13 '20 at 08:08
-
Thanks for pointing it out. I have (hopelly) fixed the answers and also added some more examples and explanations. Cheers! – Gus Neves Sep 14 '20 at 23:32
The above answers do not contemplate when you need to add a password. To include password and username in a single command, install sshpass
.
For mac: $ brew install hudochenkov/sshpass/sshpass
For linux: sudo apt-get install sshpass -y
Then:
$ sshpass -p your_password ssh user@hostname ls /path/to/dir/
You can also save output:
$ sshpass -p your_password ssh user@hostname ls /path/to/dir/ > log.txt
In python3:
import subprocess
cluster_login_email = 'user@hostname'
cluster_login_password = 'your_password'
path_to_files = '/path/to/dir/'
response = subprocess.run([
'sshpass', '-p', cluster_login_password, 'ssh', cluster_login_email, 'ls',
path_to_files], capture_output=True)
response = response.stdout.decode("utf-8").split('\n')

- 21
- 1
I find my most frequent use of this is to get the ls result, a simple list of files without all the permissions and dates and such, and keep it in a local file.
{ ssh me@host.com "cd /dir/of/interest; ls -1f *.txt;" } > /home/me/listoffiles.txt
You can run anything you want within the quotes. All output ends up in your local text file. Or if you want to run a big nasty script on the server and capture all of its output, even errors:
{ ssh me@host.com <script.remote.sh } > /home/me/output.log 2>/home/me/output.err

- 260
- 2
- 6
-
1
-
@glglgl+ in the 1st code line also (it's the quoting, and _only_ the quoting, that controls what gets sent to remote system for execution) – dave_thompson_085 Sep 13 '20 at 08:09