Changing link targets
After erasing or moving a file to which one or more links point, those
links are broken. This may have quite unpleasant effects, like data loss
and crashing programs. To avoid such problems, all links referring to the
corresponding files must be changed. That, of course, requires that one
knows all of them, which frequently isn't the case. The problem is:
While the target a link points to can easily be found (see
getlink), one can't easily tell
which links are pointing to a file - there are no backward
references. So the only way is to search the file system (or a part of it).
The following script chglink serves this purpose. It searches a given
directory for links pointing to a given target, and either prints them or
replaces them by links to a different (preferably existing) target.
Usage:
chglink [option...]directory oldTarget [newTarget]
Options:
-h Help.
-l Compare absolute paths (see below).
-p Partial comparison (see below).
-r Recursive search.
-t Test, only print commands, don't execute them.
-v Verbose.
The first file parameter is the directory to be searched, the second the old target,
the third the new target. If the third parameter is missing, matching links found are
printed, but not changed.
With option -l , first oldTarget and newTarget are made
absolute. Then, for any link, its phsyical target is determind (using the
function getlink, which must be defined), and
compared to oldTarget . If they are equal, the link is replaced
by a link to newTarget .
With option -p all links containing the substring
oldTarget are changed; this substring is replaced by newTarget
The replacement follows the bash rules of parameter expansion
${parameter/pattern/string} : If pattern starts with # ,
only substrings at the beginning match, if it starts with % ,
only substrings at the end match.
If option -r is present, the directory will be searched recursively,
including all subdirectories. Without this option, only the direct
contents of the directory are included.
With option -t , no links are actually changed, but the correspondig
commands are printed. This way a dry run can be performed.
Examples:
- Replace all links in directory
dir1 pointing to /home/dummy/blah
by a link pointing to ../ah/oh .
chglink dir1 /home/dummy/blah ../ah/oh
Note that this only changes links pointing directly to /home/dummy/blah .
-
Find all links in the present directory and all subdirectories whose final (physical)
target is
/usr/share/foo.png , and replace them by the absolute path of
bar/baz.png .
chglink -lr . /usr/share/foo.png bar/baz.png
|