A bash script is used to find out the final regular source file or directory of a multi-level symbolic on Linux and Unix (AIX, Solaris) platform.
-rw-r--r-- 1 user01 group01 12 Feb 26 14:08 /dir1/file1.txt lrwxrwxrwx 1 user01 group01 17 Feb 26 14:13 /dir2/file2.lnk -> ../dir1/file1.txt lrwxrwxrwx 1 user01 group01 30 Feb 26 14:14 /dir3/file3.lnk -> /dir2/file2.lnk lrwxrwxrwx 2 user01 group01 17 Feb 26 14:18 /dir4/file4_1.lnk -> ../dir3/file3.lnk lrwxrwxrwx 1 user01 group01 11 Feb 26 14:21 /dir4/file4_2.lnk -> file4_1.lnk
And run the script getSrc.sh against symbolic link 'file4_2.lnk', the script should return regular file 'file1.txt' with proper path,
$ findSrc.sh /dir4/file4_2.lnk /dir1/file1.txt
The script code as following
#!/bin/bash srcFile="$1" while [ -h "$srcFile" ] do tmpStr=`ls -ld "$srcFile"` tmpSrc=`expr "$tmpStr" : '.*-> \(.*\)$'` if expr "$tmpSrc" : '/.*' > /dev/null; then srcFile="$tmpSrc" else srcFile=`dirname "$srcFile"`"/$tmpSrc" fi done if [[ $srcFile == *".."* ]] || [[ $srcFile == *"."* ]] ; then workDir=`pwd` tmpDir=`dirname "$srcFile"` tmpFile=`basename "$srcFile"` tmpDir=`cd "$tmpDir" > /dev/null && pwd` if [ x"$tmpDir" != x ]; then srcFile="$tmpDir""/$tmpFile" fi cd "$workDir" fi echo $srcFile
Line 4. The logical operator '-h' return TRUE if the following file "$srcFile" is a symbolic link.
Line 5. Gets the output of command 'ls -ld' against the symbolic link given by the first parameter of the script run and assign the output as string to variable 'tmpStr'. For example, running the command as following
$ ls -ld /dir4/file4 lrwxrwxrwx 1 oracle oinstall 1 Feb 26 08:16 /dir4/file4 -> file3
The value of the variable tmpStr will be the string printed in red including the SPACE characters inside the string.
Line 6. The command 'expr' is run with string matching operator ':', it is doing anchored pattern match of regular expression in the string value of variable 'tmpStr', the match starts from beginning of the string. The regular expression '.*-> \(.*\)$' including following parts
'.*' represents any number of any character, it occurs twice in the expression. The first occurrence is followed by three characters '-> ' (hyphen, greater-than and space), they are together to match the string value from the beginning letter 'l' until the SPACE character before string 'file3' in the previous example output of command 'ls -ld'.
'\(' and '\)' the back slash '\' is escape character and telles command 'expr' that the following characters '(' and ')' are parenthesis asking to return the string matching the expression inside the parenthesis. Here, the expression in the parenthesis is second occurrence of '.*', which will match all the characters after the three-character-group '-> ', it is 'file3' in the previous output example of command 'ls -ld'.
Eventually, the output of command 'expr' will be assigned to variable 'tmpSrc'.
Line 7. Test if the path of file saved in variable 'tmpSrc' is absolute path (start with '/').
Line 10. If the test is FALSE in line 7, it means the path of linked (source) file is relative path related to symbolic link file. Therefore, the full path of the source file has to be prefixed with the path of symbolic link.
Line 13-22. It is optional block, it makes the path of source file friendly. It will change path like following
/dir1/dir2/../../dir3/file.txt
/dir1/dir2/./../dir3/file.txt
to following more friendly format
/dir3/file.txt
/dir1/dir3/file.txt
No comments:
Post a Comment