Hard Links Help


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Hard Links Help
# 1  
Old 10-04-2010
Hard Links Help

Ksh newbie here, so please bear with me.

I'm currently writing a script that searches through a directory and displays files with multiple hard links. The way I have it set up, is that it displays the i-node number and then each of the link names. In addition to this, I need to know if there are any hard links outside of the searched directory and if so, how many. Which I'm not completely sure how to do.

Code:
find /etc ! -type d -links +1 -ls
718093    8 -rw-r--r--   2 root     root          223 Aug 22  2009 /etc/hosts
718091    8 -rw-r--r--   3 root     root          204 Aug 22  2009 /etc/sysconfig/network-scripts/ifcfg-eth0
718093    8 -rw-r--r--   2 root     root          223 Aug 22  2009 /etc/sysconfig/networking/profiles/default/hosts
718094    8 -rw-r--r--   2 root     root           68 Aug 22  2009 /etc/sysconfig/networking/profiles/default/resolv.conf
718091    8 -rw-r--r--   3 root     root          204 Aug 22  2009 /etc/sysconfig/networking/profiles/default/ifcfg-eth0
718091    8 -rw-r--r--   3 root     root          204 Aug 22  2009 /etc/sysconfig/networking/devices/ifcfg-eth0
718094    8 -rw-r--r--   2 root     root           68 Aug 22  2009 /etc/resolv.conf

I understand the $4 is the number of hard links, however does that include any links that are found outside of the current directory? If not, then what exactly do I need to do to get a total number of hard links in and out of the current directory?

Also, on a side note what is $2?
# 2  
Old 10-04-2010
The second column is the number of disk blocks required to house the file. Generally the value is 512 byte blocks, though some versions of find might default to 1024 byte blocks.

The fourth column is the number of links, but only if the file is a regular file. If it is a directory it is the number of files contained/referenced in the directory.

Because links (old timers call them links as symbolic links were introduced later) cannot span filesystems, I'd approach the problem by executing a find on the whole file system and matching inodes for files that are listed within the target directory. The following is a way to do this and assumes that the target directory is the current working directory.

Code:

#!/usr/bin/env ksh

p=$(df -h . )
find ${p##* } -type file -ls 2>/dev/null | awk -v cwd="$(pwd)/" '
        {
                if( $4 > 1  )                           # only care about files with multiple hardlinks
                {
                        dir = $NF;
                        sub( "[^/]+$", "", dir );       # lop off the filename
                        if( dir == cwd )                # collect for printing only files in the target directory
                                listit[$1]++;

                        paths[$1] = paths[$1] $NF " ";  # collect paths associated with the inode (regardless of directory)
                }
        }

        END {
                for( f in listit )
                {
                        x = split( paths[f], a, " " );  # split paths for a "vertical" listing
                        printf( "%s\n", f );            # print the inode number
                        for( i = 1; i <= x; i++ )       # list each path
                                printf( "\t%s\n", a[i] );
                        printf( "\n" );
                }
        }
'



Hope this gets you started.
# 3  
Old 10-04-2010
Nice work agama,

Can I suggest 1 slight change: add a -mount flag on the find, to keep it to the 1 filesystem.
This User Gave Thanks to Chubler_XL For This Post:
# 4  
Old 10-04-2010
Thanks for the replies. Just one last question though. In the fourth column above, is that the total number of hard links for that file or just the number of links in that directory?
# 5  
Old 10-04-2010
Quote:
Originally Posted by Unknown50862
Thanks for the replies. Just one last question though. In the fourth column above, is that the total number of hard links for that file or just the number of links in that directory?
Total number of links to the real file.

@Chubler_XL -- yes, good call. Thanks.
# 6  
Old 10-05-2010
can you please tell wot does ##* mean in the below piece of your code.

Code:
find ${p##* } -type file -ls 2>/dev/null | awk -v cwd="$(pwd)/" '

# 7  
Old 10-05-2010
Quote:
Originally Posted by michaelrozar17
can you please tell wot does ##* mean in the below piece of your code.

Code:
find ${p##* } -type file -ls 2>/dev/null | awk -v cwd="$(pwd)/" '

An excerpt from here

Quote:
Chopping strings like a pro

While basename and dirname are great tools, there are times where we may need to perform more advanced string "chopping" operations than just standard pathname manipulations. When we need more punch, we can take advantage of bash's advanced built-in variable expansion functionality. We've already used the standard kind of variable expansion, which looks like this: ${MYVAR}. But bash can also perform some handy string chopping on its own. Take a look at these examples:

$ MYVAR=foodforthought.jpg
$ echo ${MYVAR##*fo}
rthought.jpg
$ echo ${MYVAR#*fo}
odforthought.jpg


In the first example, we typed ${MYVAR##*fo}. What exactly does this mean? Basically, inside the ${ }, we typed the name of the environment variable, two ##s, and a wildcard ("*fo"). Then, bash took MYVAR, found the longest substring from the beginning of the string "foodforthought.jpg" that matched the wildcard "*fo", and chopped it off the beginning of the string. That's a bit hard to grasp at first, so to get a feel for how this special "##" option works, let's step through how bash completed this expansion. First, it began searching for substrings at the beginning of "foodforthought.jpg" that matched the "*fo" wildcard. Here are the substrings that it checked:

f
fo MATCHES *fo
foo
food
foodf
foodfo MATCHES *fo
foodfor
foodfort
foodforth
foodfortho
foodforthou
foodforthoug
foodforthought
foodforthought.j
foodforthought.jp
foodforthought.jpg


After searching the string for matches, you can see that bash found two. It selects the longest match, removes it from the beginning of the original string, and returns the result.

The second form of variable expansion shown above appears identical to the first, except it uses only one "#" -- and bash performs an almost identical process. It checks the same set of substrings as our first example did, except that bash removes the shortest match from our original string, and returns the result. So, as soon as it checks the "fo" substring, it removes "fo" from our string and returns "odforthought.jpg".
After reading that put it to the test.
bash code:
  1. p=$(df -h .)   # free hard disk space in the current directory in a human readable format
  2. echo ${p##* } # there's a space after the *

Last edited by Aia; 10-05-2010 at 04:25 AM..
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Timestamp change for hard and soft links

Hi team, i am writing a purge script to delete softlinks and hardlinks on linux system which are 3/10/30 days old. To test the script i need to create links with old timestamp, i am able to cange timestamp for files but not for links. i tried touch -h option but this option is not available on... (1 Reply)
Discussion started by: Satyak
1 Replies

2. UNIX for Dummies Questions & Answers

Simple example for soft and hard links

Hai, give me a simple example for soft and hard links. this will work for soft link ?? ln -s (2 Replies)
Discussion started by: Ramesh M
2 Replies

3. AIX

List all the soft links and hard links

Hi I'm logged in as root in an aix box Which command will list all the soft links and hard links present in the server ? (2 Replies)
Discussion started by: newtoaixos
2 Replies

4. Solaris

Hard Links and Soft or Sym links

When loooking at files in a directory using ls, how can I tell if I have a hard link or soft link? (11 Replies)
Discussion started by: Harleyrci
11 Replies

5. Shell Programming and Scripting

Unable to preserve hard links. Why?

Hi, I'm trying to create a Makefile that would automate remastering Knoppix distribution. As a part of the process I am mounting using linux cloop device a compressed filesystem and copy the content out of it to separate dir. However during that process I need to preserve hard links and it... (9 Replies)
Discussion started by: dpc.ucore.info
9 Replies

6. UNIX for Advanced & Expert Users

Hard links for directories.

Hard links for directories are not permitted by default. But in some flavor of Unix, super user can create hard links for directories by some other way? Is that true? Is it possible in latest version of BSD or other unix? (2 Replies)
Discussion started by: bbala
2 Replies

7. UNIX for Dummies Questions & Answers

Deleting Symbolic and/or Hard links

From what I understand a symbolic link is alot like a shortcut where it points to another file. if the original file is deleted the symbolic link is rendered useless but a symbolic link can be deleted without any problem. A hard link is like a copy of the file itself but pointing to the same... (3 Replies)
Discussion started by: cue
3 Replies

8. UNIX for Dummies Questions & Answers

hard links in unix

hi i have a hardlink how can i find the source of it (2 Replies)
Discussion started by: jpriyank
2 Replies

9. UNIX for Dummies Questions & Answers

links.... soft or hard.. not sure?

hi, i am in a directory, have 2 files as below then do a ls -l gives the below lrwxrwxrwx 1 root system 23 Mar 08 2001 filea -> /adir/filea lrwxrwxrwx 1 root system 23 Mar 08 2001 filea -> /adir/fileb now, when i do a cd /adir, the system said, adir not... (5 Replies)
Discussion started by: yls177
5 Replies

10. UNIX for Dummies Questions & Answers

links: (soft, hard? symbolic??) inode

Hi, what is link? and soft link? how about hard one and symbolic link. and inode. i get confuse about this links. could anyone help me with full explainsion? thks Gusla (5 Replies)
Discussion started by: gusla
5 Replies
Login or Register to Ask a Question