How to list all symbolic links in a directory
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?
10 Answers 10
Parsing ls is a Bad Idea®, prefer a simple find in that case:
To only process the current directory:
find . -maxdepth 1 -type l -ls
Great answer! I adjusted mine to not descend down directory path like this: find /
@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
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.
Please, do not use ls for scripting. Also mentioned in other answers. More: mywiki.wooledge.org/ParsingLs
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
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 .
@MtlDev ! negates the condition matching, here ! -name . means matching everything except current directory.
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.
To view the symbolic links in a directory:
- Open a terminal and move to that directory.
- Type the command:
ls -l *(@) lrwxrwxrwx 1 david david 15 Nov 18 22:35 gvimrc -> /etc/vim/gvimrc lrwxrwxrwx 1 david david 13 Nov 18 22:19 mydomains.php -> mydomains.php
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.
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.
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
$ 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.
How to find and list all the symbolic links created for a particular file?
I had created many symbolic links on various paths for a particular file or a directory. I want the whole list of created symbolic links paths (location).
Example:
I created symbolic links for ~/Pictures directory on many directories. How do I list all the symlinks to that ~/Pictures directory? Is that possible? If yes, then how?
You need to search exhaustive, there is no count stored like there is for hard-links. See one of the answers using find.
4 Answers 4
find -L /dir/to/start -xtype l -samefile ~/Pictures
find -L /dir/to/start -xtype l -samefile ~/Pictures 2>/dev/null
to get rid of some errors like Permission denied , Too many levels of symbolic links , or File system loop detected which find throws them when doesn’t have the right permissions or other situations.
- -L — Follow symbolic links.
- -xtype l — File is symbolic link
- -samefile name — File refers to the same inode as name . When -L is in effect, this can include symbolic links.
Could the command be modified to find symbolic link that contains a path? e.g. files across the system that may link to ~/Pictures/A, ~/Pictures/A/B/C, or any files in the subdirectories of ~/Pictures>
Very simple, use option -lname :
find / -lname /path/to/original/dir
-lname pattern File is a symbolic link whose contents match shell pattern pattern. The metacharacters do not treat `/' or `.' specially. If the -L option or the -follow option is in effect, this test returns false unless the symbolic link is broken.
Note: Remember that symbolic links could be anywhere, which includes a remote system (if you’re sharing files), so you may not be able to locate them all.
How to see full absolute path of a symlink
When I’m using ls -la symlinkName or stat symlinkName not all the path is displayed (e.g ../../../one/two/file.txt ) What is the linux command that reveals the full path?
One should be careful here: when ls or stat display no absolute path — the link has no absolute path! This is esp. important when the device is mounted e.g. in a different context (e.g. if you have something on a cd or usb-stick or try to recover some broken hdd). All the mentioned solutions (realpath, readlink. ) show only the absolute path in the mounted context.
10 Answers 10
realpath isn’t available on all linux flavors, but readlink should be.
The above should do the trick.
Alternatively, if you don’t have either of the above installed, you can do the following if you have python 2.6 (or later) installed
python -c 'import os.path; print(os.path.realpath("symlinkName"))'
realpath should do the trick.
man realpath shows at the bottom that it it part of «GNU coreutils», which I’m pretty sure always comes on Ubuntu, so even though @IanStapletonCordasco says » realpath isn’t available on all linux flavors», it should at least be available on all Ubuntu and Ubuntu derivative flavors I believe.
unix flavors -> ll symLinkName
OSX -> readlink symLinkName
Difference is 1st way would display the sym link path in a blinking way and 2nd way would just echo it out on the console.
The question was asking specifically for the full/absolute path, not relative path (../../file.txt). Both of these answers will give the relative path.
I will give short review and analysis here, but for those TL;DR here is one-liner for bash, useful to anchor the working directory:
script_home=$( dirname $(realpath "$0") )
Or you can use any other filename instead of $0 to determine it’s real location.
There is not only problem of detemination of real path of some file, but especially some script is called via symlink from another location and needs to reference other resources relative to it’s real work directory.
Details follow. Lets assume we have real script or file and symbolic link to it:
$ ls -la -rwxr-xr-x 1 root root 0 Mar 20 07:05 realscript.sh lrwxrwxrwx 1 root root 10 Mar 20 07:05 symlink -> realscript.sh
And the part of GNU coreutils are few very useful commands:
$ realpath symlink /home/test/realscript.sh
realpath realscript.sh /home/test/realscript.sh
Also very good combination in scripting is to use dirname on script
$ dirname /home/test/realscript.sh /home/test
so to wrap it up, you can use in script
echo $( dirname $(realpath "symlink") )
or to get and store in variable real script home dir and save code to get real path script realscript.sh:
script_home=$( dirname $(realpath "$0") ) echo Original script home: $script_home
Where «$0» is defined as «self» in shell script.
To test everything, we put symlink into /home/test2/, amend some additional things and run/call it from root directory:
$ /home/test2/symlink /home/test Original script home: /home/test Original script is: /home/test/realscript.sh Called script is: /home/test2/symlink
Please try to write your self the amended outputs 🙂
Update 2021, there is also command:
readlink — print resolved symbolic links or canonical file names
DESCRIPTION Note realpath(1) is the preferred command to use for canonicalization functionality.
Bash: how to get real path of a symlink? [duplicate]
Is it possible, executing a file symlinked in /usr/local/bin folder, to get the absolute path of original script? Well, .. I know where original file is, and I know it because I am linkging it. But, . I want this script working, even if I move original source code (and symlink).
coreutils isn’t installed by default on every system that includes bash. stat is more consistently available, but it too has different usage depending on your operating system.
3 Answers 3
readlink is not a standard command, but it’s common on Linux and BSD, including OS X, and it’s the most straightforward answer to your question. BSD and GNU readlink implementations are different, so read the documentation for the one you have.
If readlink is not available, or you need to write a cross-platform script that isn’t bound to a specific implementation:
If the symlink is also a directory, then
will get you into the dereferenced directory, so
echo "I am in $(cd -P "$symlinkdir" && pwd)"
will echo the fully dereferenced directory. That said, cd -P dereferences the entire path, so if you have more than one symlink in the same path you can have unexpected results.
If the symlink is to a file, not a directory, you may not need to dereference the link. Most commands follow symlinks harmlessly. If you simply want to check if a file is a link, use test -L .