- Check if file is a link on Linux
- 4 Answers 4
- Determining if a file is a hard link or symbolic link?
- 6 Answers 6
- Check if a directory exists in Linux or Unix shell
- How to check if a directory exists in Linux
- A note about symbolic links (symlink)
- Linux check if a directory exists and take some action
- Check if directory exists in bash and if not create it
- Using test command
- Getting help
- Conclusion
- How to list all symbolic links in a directory
- 9 Answers 9
- How can I find broken symlinks
- 11 Answers 11
Check if file is a link on Linux
I am trying to check if a symbolic link exists from a KornShell (ksh) script using -h filename command. This works good on HP boxes.
Not sure what is the correct option for Linux, AIX and Solaris boxes.
Any insight regarding this?
4 Answers 4
-h is part of the POSIX spec; it should work everywhere that is vaguely reasonable.
According to man test on Mac OS X:
-L is also standardized, so if you find anywhere that -h does not work, you should try -L instead.
It is -h on linux systems also, at least (bash is my shell):
Check man test to see the available operators you have available to use on files and strings in your given enviorment.
The best answer is to try whatever the ‘test’ man page says on your system. If that seems to work, look no further. However, if it doesn’t seem to work, or if you have questions about more obscure options to test, then you should also check the man page for your shell to see if ‘expr’ or ‘[‘ are built-ins. In that case, the shell might be using an internal implementation instead of calling the expr utility from /bin. On Solaris I verified that ksh93 treats [ as a builtin (even though the man page doesn’t seem to say so). From the truss output you can see that ksh is not running the expr command for [.
Thw two possible options are
If $? is 0 then file is linked otherwise its not linked, I will prefer the first option instead.
Источник
Determining if a file is a hard link or symbolic link?
I’m creating a shell script that would take a filename/path to a file and determine if the file is a symbolic link or a hard link.
The only thing is, I don’t know how to see if they are a hard link. I created 2 files, one a hard link and one a symbolic link, to use as a test file. But how would I determine if a file is a hard link or symbolic within a shell script?
Also, how would I find the destination partition of a symbolic link? So let’s say I have a file that links to a different partition, how would I find the path to that original file?
6 Answers 6
Jim’s answer explains how to test for a symlink: by using test ‘s -L test.
But testing for a «hard link» is, well, strictly speaking not what you want. Hard links work because of how Unix handles files: each file is represented by a single inode. Then a single inode has zero or more names or directory entries or, technically, hard links (what you’re calling a «file»).
Thankfully, the stat command, where available, can tell you how many names an inode has.
So you’re looking for something like this (here assuming the GNU or busybox implementation of stat ):
The -c ‘%h’ bit tells stat to just output the number of hardlinks to the inode, i.e., the number of names the file has. -gt 1 then checks if that is more than 1.
Note that symlinks, just like any other files, can also be linked to several directories so you can have several hardlinks to one symlink.
The f1 , f2 and f3 directory entries are the same file (same inode: 10802124, you’ll notice the number of links is 3). They are hard links to the same regular file.
s4 and s5 are also the same file (10802384). They are of type symlink, not regular. They point to a path, here s3 . Because s4 and s5 are entries of the same directory, that relative path s3 point to the same file (the one with inod 10802347) for both.
If you do a ls -Ll , that is asking to get file information after resolving symlinks:
You’ll find they all resolve to the same file (10802124).
You can check if a file is a symlink with [ -L file ] . Similarly, you can test if a file is a regular file with [ -f file ] , but in that case, the check is done after resolving symlinks.
hardlinks are not a type of file, they are just different names for a file (of any type).
Using the -h and -L operators of the test command:
According to this SO thread, they have the same behavior, but -L is preferred.
you can use readlink FILE; echo $? . This returns 1 when it’s a hardlink and 0 when it’s a symlink.
From the man page: » When invoked as readlink, only the target of the symbolic link is printed. If the given argu- ment is not a symbolic link, readlink will print nothing and exit with an error.»
There are a lot of quite correct answers here, but I don’t think anybody really tackled the original misperception. The original question is basically «when I make a symbolic link, it’s easy to identify it afterwards. But I can’t figure out how to identify a hard link.» And yes, the answers basically boil down to «you can’t,» and more or less explain why, but nobody seems to have acknowledged that, really, it IS confusing and strange.
If you’re reading all this and you’ve figured out what’s going on, then you’re good; you don’t need to read my little bit. If you’re still confused, then keep going.
The really really short answer is that a hard link isn’t really a link at all, not in the way a symbolic link is. It’s a new entry in the directory structure that points to the same bunch of bytes that the original directory entry did, and once you’ve created it, it is just as ‘real’ and legitimate as the first one. Every ‘normal’ file on your drive has at least one hard link; without that, you wouldn’t see it in any directory, and would be unable to refer to it or use it. So if you have a file Fred.txt, and you hard link Wilma.txt and Barney.txt to it, all three names (and directory entries) refer to the same file, and they are all equally valid. There isn’t any way for the OS to tell that one of the entries was created when you hit «save» in your text editor, and the others were made with the «ln» command.
The OS does have to keep track of how many different entries are pointing to the same file, though. If you delete Wilma.txt, no surprise that you don’t free up any space on your drive. But if you delete Fred.txt (the ‘original’ file), you still won’t free up any space on your drive, because the data on the drive that was known as Fred.txt is still also Barney.txt. Only when you delete all of the directory entries will the OS de-allocate the space that the data itself was occupying.
If Barney.txt had been a symbolic link, then deleting Fred.txt would have de-allocated the space, and Barney.txt would now be a broken link. Also, if you move or rename a file that has a symbolic link pointing at it, you’ll break the link. But you can move or rename a hard-linked file all you want without breaking the other directory entries that point to that file/data, because all of them are directory entries that refer to the same block of data on the drive (by using the inode # of that data).
[It’s two years later, and that last bit confused me for a minute, so I think I’ll clarify. If you type «mv ./Wilma.txt ../elsewhere/Betty.txt» it seems like you’re moving the file, but in fact, you are not. What you’re really doing is removing a line item from the directory list of your current directory, the one that says «the name ‘Wilma.txt’ is associated with the data that can be found by using inode #######,» and adding a new line item to the directory list of directory ../elsewhere that says «the name ‘Betty.txt’ is associated with the data that can be found via inode #######». This is why you can ‘move’ a 2 gigabyte file as quickly as a 2 kilobyte file, as long as you’re moving them to another location on the same drive.]
Because the OS has to keep track of how many different directory entries are pointing to the same chunk of data, you can tell if a particular file has been hard linked to, even though you can’t tell for certain if the directory entry that you’re looking at is the ‘original’ one or not. One way is the «ls» command, specifically «ls -l» (that’s a lower-case L after the dash)
To borrow an earlier example.
The first letter’s a dash, so it’s not a directory or something else exotic, it’s a ‘regular’ ordinary file. But if it were truly ordinary, that number after the rwx-ish part would be «1», as in, «there is one directory entry pointing to this block of data.» But it’s part of a demonstration of hard links, so instead it says «3».
Note that this can possibly lead to weird and mysterious behavior (if you haven’t wrapped your head around hard links, that is). If you open Fred.txt in your text editor and make some changes, will you see the same changes in Wilma.txt and Barney.txt? Maybe. Probably. If your text editor saves the changes by opening the original file and writing the changes to it, then yes, all three names will still be pointing at the same (newly changed) text. But if your text editor creates a new file (Fred-new-temp.txt), writes your changed version to that, then deletes Fred.txt, then renames Fred-new-temp.txt to Fred.txt, Wilma and Barney will still be pointing to the original version, not the new changed version. If you don’t understand hard links, this could drive you slightly mad. 🙂 [Okay, I don’t actually personally know of any text editors that would do the new-file/rename thing, but I do know of lots of other programs that do exactly that, so stay alert.]
A final note: one of the things that ‘fsck’ (file system check) checks for is if there are blocks of data on your drive that somehow are no longer referenced by any directory entries. Sometimes something goes wrong, and the only directory entry that points to an inode gets deleted but the drive space itself doesn’t get marked as «available.» So one of fsck’s jobs is to match up all the allocated space with all the directory entries to make sure that there aren’t any unreferenced files. If it finds some, it creates new directory entries and puts them in «lost+found».
Источник
Check if a directory exists in Linux or Unix shell
How to check if a directory exists in Linux
- One can check if a directory exists in a Linux shell script using the following syntax:
[ -d «/path/dir/» ] && echo «Directory /path/dir/ exists.» - You can use ! to check if a directory does not exists on Unix:
[ ! -d «/dir1/» ] && echo «Directory /dir1/ DOES NOT exists.»
One can check if a directory exists in Linux script as follows:
Always enclose “$DIR” in double-quotes to deal with directories having white/black spaces in their names. For instance:
A note about symbolic links (symlink)
Directories with symbolic links need special consideration as follows using the -L switch:
Linux check if a directory exists and take some action
Here is a sample shell script to see if a folder exists or not in Linux:
Run it as follows:
./test.sh
./test.sh /tmp/
./test.sh /nixCraft
Check if directory exists in bash and if not create it
Here is a sample shell script to check if a directory doesn’t exist and create it as per our needs:
Make sure you always wrap shell variables such as $DIR in double quotes ( «$DIR» to avoid any surprises in your shell scripts:
Using test command
One can use the test command to check file types and compare values. For example, see if FILE exists and is a directory. The syntax is:
test -d «DIRECTORY» && echo «Found/Exists» || echo «Does not exist»
The test command is same as [ conditional expression. Hence, you can use the following syntax too:
[ -d «DIR» ] && echo «yes» || echo «noop»
- No ads and tracking
- In-depth guides for developers and sysadmins at Opensourceflare✨
- Join my Patreon to support independent content creators and start reading latest guides:
- How to set up Redis sentinel cluster on Ubuntu or Debian Linux
- How To Set Up SSH Keys With YubiKey as two-factor authentication (U2F/FIDO2)
- How to set up Mariadb Galera cluster on Ubuntu or Debian Linux
- A podman tutorial for beginners – part I (run Linux containers without Docker and in daemonless mode)
- How to protect Linux against rogue USB devices using USBGuard
Join Patreon ➔
Getting help
Read bash shell man page by typing the following man command or visit online here:
man bash
help [
help [[
man test
Conclusion
This page explained various commands that can be used to check if a directory exists or not, within a shell script running on Linux or Unix-like systems. The -d DIR1 option returns true if DIR1 exists and is a directory. Similarly, the -L DIR1 option returns true if DIR1 found and is a symbolic links.
🐧 Get the latest tutorials on Linux, Open Source & DevOps via
Источник
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?
9 Answers 9
Parsing ls is a Bad Idea®, prefer a simple find in that case:
To only process the current directory:
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.
grep is your friend:
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
This returns all symbolically linked items (both dirs & fns) in a directory:
However, in order to distinguish between actual symbolically linked item types:
Returns symbolically linked filename items only. And,
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:
This shall long list all the files in the directory even if they are hidden.
The files that start with l are your symbolic link files.
Источник
How can I find broken symlinks
Is there a way to find all symbolic links that don’t point anywere?
will give me all symbolic links, but makes no distinction between links that go somewhere and links that don’t.
I’m currently doing:
But I’m wondering what alternate solutions exist.
11 Answers 11
I’d strongly suggest not to use find -L for the task (see below for explanation). Here are some other ways to do this:
If you want to use a «pure find » method, it should rather look like this:
( xtype is a test performed on a dereferenced link) This may not be available in all versions of find , though. But there are other options as well:
You can also exec test -e from within the find command:
Even some grep trick could be better (i.e., safer) than find -L , but not exactly such as presented in the question (which greps in entire output lines, including filenames):
The find -L trick quoted by solo from commandlinefu looks nice and hacky, but it has one very dangerous pitfall: All the symlinks are followed. Consider directory with the contents presented below:
If you run find -L . -type l in that directory, all /usr/share/ would be searched as well (and that can take really long) 1 . For a find command that is «immune to outgoing links», don’t use -L .
1 This may look like a minor inconvenience (the command will «just» take long to traverse all /usr/share ) – but can have more severe consequences. For instance, consider chroot environments: They can exist in some subdirectory of the main filesystem and contain symlinks to absolute locations. Those links could seem to be broken for the «outside» system, because they only point to proper places once you’ve entered the chroot. I also recall that some bootloader used symlinks under /boot that only made sense in an initial boot phase, when the boot partition was mounted as / .
So if you use a find -L command to find and then delete broken symlinks from some harmless-looking directory, you might even break your system.
Источник