222

I have a symbolic link in my /var/www/ directory that links to WordPress. When I run the command ls -la from the /var/www/ directory the link to WordPress doesn't show up. Is there a way to list all of the symbolic links that are in a directory?

1
119

You can use grep with ls command to list all the symbolic links present in the current directory.

This will list all the links present in the current directory.

ls -la /var/www/ | grep "\->"
6
  • 9
    It will return false positive if you have a file containing "->". Try a simple touch "foo->" Sep 9 '14 at 18:32
  • 6
    why not greping with ^l? Jan 18 '17 at 12:13
  • 4
    As usual, the best answer is the one with highest + Dec 10 '17 at 19:19
  • 1
    Nice! → .bash_alias: alias listlinks='ls -l --color | grep "\->"' 8-) Apr 11 '18 at 3:08
  • Pass -R to ls to get recursive list.
    – Itachi
    Apr 27 '18 at 7:10
399

Parsing ls is a Bad Idea®, prefer a simple find in that case:

find . -type l -ls

To only process the current directory:

find . -maxdepth 1 -type l -ls

Credits: How do I make the shell to recognize the file names returned by a `ls -A` command, and these names contain spaces?

8
  • 17
    @ahnbizcad: It's not 1 (one) but l (link) May 28 '15 at 17:51
  • 3
    Great answer! I adjusted mine to not descend down directory path like this: find /<your_directory> -maxdepth 1 -type l -ls 2>/dev/null Thank you!
    – bgs
    Feb 4 '16 at 18:47
  • 3
    For only the current directory (i.e. not recursive) add -maxdepth 1. Apr 8 '16 at 14:32
  • 1
    @cig0 u do not need to use awk, u probably want just this: find . -maxdepth 1 -type l | sort -n
    – sobi3ch
    Jun 28 '19 at 15:43
  • 2
    @GabrielStaples from man find: -ls True; list current file in ls -dils format on standard output. Useful to see ./os-release -> ../usr/lib/os-release in /etc rather than just ./os-release Feb 13 '20 at 9:11
9

grep is your friend:

ls -lhaF | grep ^l   # list links
ls -lhaF | grep ^d   # list directories
ls -lhaF | grep ^-   # list files

This will list lines starting with "l" which represent Links in the perms column in place of l use d for directories and - for files

1
  • 1
    Just don't do anything with this method programatically since malicious filenames can end up injecting shell code. To be safe, one should use the find command with -exec, and if piping to xargs, use the null-character separator output flag of find combined with the null-character separator input flag of xargs.
    – ErikE
    Dec 19 '19 at 15:24
5

POSIXly:

find ! -name . -prune -type l
2
  • 1
    Can you explain the ! in this context?
    – Mtl Dev
    Jan 14 '20 at 15:42
  • @MtlDev ! negates the condition matching, here ! -name . means matching everything except current directory.
    – cuonglm
    Jan 15 '20 at 4:49
3

This returns all symbolically linked items (both dirs & fns) in a directory:

find . -maxdepth 1 -type l -print | cut -c3- | grep -v "\#"

However, in order to distinguish between actual symbolically linked item types:

ls -lhaF | grep ^l | grep -v "\#" | cut -c42- | grep -v "/" | cut -d' ' -f1

Returns symbolically linked filename items only. And,

ls -lhaF | grep ^l | grep -v "\#" | cut -c42- | grep "/" | cut -d' ' -f1

Returns symbolically linked dirname items only.

1

To view the symbolic links in a directory:

  1. Open a terminal and move to that directory.

  2. Type the command:

    ls -la
    

    This shall long list all the files in the directory even if they are hidden.

  3. The files that start with l are your symbolic link files.

2
  • 1
    -1: KasiyA's answer already covers this.
    – muru
    Sep 10 '14 at 5:45
  • this also lists non-syminks. Far better solutions that answer the Q already posted.
    – RichieHH
    Oct 14 '20 at 5:09
0

Type ls -lai,it will list all the files and subdirectories with corresponding inode numbers.You know files with same inode number are the links(hard or soft) and this solution also works for the symbolic links.

1
  • 1
    ls -lai does not show the same inode number for a file and its symbolic links. Unlike hard links, symbolic links have their own separate inode entries. This is what it looks like. Sep 12 '14 at 6:19
0

Can be done with python as well:

$ python -c "import os,sys; print '\n'.join([os.path.join(sys.argv[1],i) for i in os.listdir(sys.argv[1]) if os.path.islink(os.path.join(sys.argv[1],i))])" /path/to/dir

Sample run:

$ python -c "import os,sys; print '\n'.join([os.path.join(sys.argv[1],i) for i in os.listdir(sys.argv[1]) if os.path.islink(os.path.join(sys.argv[1],i))])" /etc
/etc/vtrgb
/etc/printcap
/etc/resolv.conf
/etc/os-release
/etc/mtab
/etc/localtime

This can be extended to be recursive via os.walk function, but it's sufficient to use simple list generation for listing links in a single directory as I showed above.

1
  • 2
    Way over complicating when basic shell commands can already do this.
    – RichieHH
    Oct 14 '20 at 5:10
0

Kindly find below one liner bash script command to find all broken symbolic links recursively in any linux based OS

b=$(find / -type l); for i in $(echo $b); do file $i ; done |grep -i broken 2> /dev/null

Not the answer you're looking for? Browse other questions tagged or ask your own question.