APLawrence.com -  Resources for Unix and Linux Systems, Bloggers and the self-employed

Finding symbolic links

Sure, finding symlinks has always been easy: "find . -type l".

The script below is tailored for SCO Unix upgrades where the installer intended to over write the root filesystem. Having a list of root file links pointing to other file systems is very useful for restores.

You might want to run a customized version of this every now and then anyway just for record keeping. It could help at some future date.

See Upgrades vs. Fresh installs also.

Newsgroups: comp.unix.sco.misc
From: rac@tenzing.org (Roger Cornelius)
Subject: Re: Recommendations on upgrading from 504 to 505
Date: Sun, 23 May 1999 21:02:12 GMT
Message-ID: <199905232102.RAA27768@tenzing.org> 
References: <4.1.19990523140233.0234b520@scogr1.dmg-grsd.com>
<19990523144131.C22323@jpradley.jpr.com> Jean-Pierre Radley <jpr@jpr.com> wrote: > >Ken Wolff averred (on Sun, May 23, 1999 at 06:20:28PM +0000): >| >| I also have JP's 'savefiles' script (been using >| this for quite a few upgrades - thanks JP). > >You're welcome. But please get the latest version of savefiles from >ftp.jpr.com. > >The script makes us of BackupEDGE's h flag: > > h Restore the data in addition to the symbolic link. If this flag is set > and symbolic link is restored, AND if the symbolic link point to a real > file which is stored later on the archive, the real file is also > restored. > >It literally means what it says; but in earlier versions of "savefiles", >I had included a few directories; the contents of those directories >didn't get saved if the directory itself was a symlink. /usr/spool/cron, >for example. Here's a script I've been meaning to post for a long time. I use it along with your savefiles script to help restore the state of my system after an upgrade or restore. Depending on the options used, it produces a list of symlinks on the root fs which point to objects on non-root filesystems, a list of symlinks on non-root filesystems which point to the root fs, or both. It will optionally produce the list in a form suitable for execution by the shell.

Any comments or suggestions are welcome.

---- cut here ----
# @(#) findln: print list of symlinks pointing to/from root filesystem
# @(#) Assumes all filesystems are currently mounted
# @(#) Requires Gnu find
# @(#) 08/25/97 rac@tenzing.org

# The following can be useful in building a script to reconnect symlinks
# after an OS upgrade, etc..
# findln -nr | sed 's/^\(.*\) -> \(.*\)/ln -s \2 \1/'
#  or
# findln -lnr

arg0=`basename $0`

# location of gnu find

if expr "`id`" : ".*(root) *" >/dev/null
    : ok
    echo "Must be root" >&2
    exit 2

usage() {
    echo "Usage: $arg0 [-l] [-n] [-r]
-n  print symlinks on non-root filesystems pointing to root filesystem
-r  print symlinks on root filesystem pointing to non-root filesystems
-l  print in format suitable for execution by /bin/sh" >&2
    exit 1

# find symlinks on root filesystem which point to non-root filesystems
do_root_fs() {

    echo "\n#\n# symlinks on root filesystem\n#"

    # create -lname command list for gnu find
    for fs in $mountlist
        case $fs in
        /|/stand)   # skip root and stand filesystems
        *)  pat="$pat ${pat:+-o} -lname '${fs}/*'";;

    sh -c "$FIND / -mount \( $pat \) -printf '$printf_fmt'"

# find symlinks on non-root filesystems which point to / or /stand filesystems
do_nonroot_fs() {

    echo "\n#\n# symlinks on non-root filesystems\n#"

    # create -lname command list for gnu find
    # don't match any symlink whose contents don't begin with '/'
    pat="! -lname '[!/]*'"
    for fs in $mountlist
        case $fs in
        *)  pat="$pat ${pat:+-a} ! -lname '${fs}/*'";;

    # for each fs, search for symlinks to / or /stand
    for fs in $mountlist
        # skip root and stand filesystems
        case $fs in /|/stand) continue ;; esac

        sh -c "$FIND $fs -mount -type l \( $pat \) -printf '$printf_fmt'"

# default printf format
printf_fmt="%p -> %l\n"

do_root=false do_nonroot=false
while getopts lnr opt 
    case $opt in
    l)  printf_fmt="ln -s %l %p\n";;
    n)  do_nonroot=:;;
    r)  do_root=:;;
    *)  usage;;

# skip /dev/cd* and /dev/hd[0-9]d (cdrom drives and dos partitions)
mountlist="`/etc/mount | sed '/\/dev\/cd/d; /\dev\/hd[0-9]d/d; s/ .*//'`"

$do_root && do_root_fs
$do_nonroot && do_nonroot_fs
---- cut here ----

Roger Cornelius        rac@tenzing.org

Got something to add? Send me email.

(OLDER)    <- More Stuff -> (NEWER)    (NEWEST)   

Printer Friendly Version

-> -> Finding symbolic links ––>Re: Recommendations on upgrading from 504 to 505

Increase ad revenue 50-250% with Ezoic

More Articles by

Find me on Google+

© Tony Lawrence

Kerio Samepage

Have you tried Searching this site?

Unix/Linux/Mac OS X support by phone, email or on-site: Support Rates

This is a Unix/Linux resource website. It contains technical articles about Unix, Linux and general computing related subjects, opinion, news, help files, how-to's, tutorials and more.

Contact us

Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it? (Brian Kernighan)

This post tagged: