I have moved a Leap 15.2 to a VM and upgrade to leap 15.4 for doing it I copied the filesystem with rsync and the booted the VM with opensuse leap 15.4 DVD and did an upgrade. It worked fine and the system boots and works… except I have detected some (but not much) errors, for instance awk oes not work, I look for it and I see it is provided by gawk, and I see in alternatives this
So gawk is there, and awk is a symlink from alternatives to it… but without the initial slash
I have detected more errors like this one … indeed a lot.
I think can get them all with
find / -xtype l
So I could run -exec with find to fix each one of them, adding a / at the begining right?
tutatis:/var/lib/mailman/data # symlinks --help
symlinks: scan/change symbolic links - v1.4 - by Mark Lord
Usage: symlinks -cdorstv] dirlist
Flags: -c == change absolute/messy links to relative
-d == delete dangling links
-o == warn about links across file systems
-r == recurse into subdirs
-s == shorten lengthy links (displayed in output only when -c not specified)
-t == show what would be done by -c
-v == verbose (show all symlinks)
The -c option does just the opposite of what I want
I found a bug report of 2012 asking to include an option to convert relative to absolute symlinks … but it seems it was not included… at least in the symlinks program in opensuse repos.
find /etc -type l -print0|xargs -0 ls -1d |while read i ; do
r=$(realpath "$i")
if ! -e "$r" ]] ; then
echo name: "$i"
echo target "$r" does not exist.
**# insert repair actions here**
fi
done
**erlangen:~ #** ./findlinks.sh
name: /etc/alternatives/rmic
target /usr/lib64/jvm/java-15-openjdk-15/bin/rmic does not exist.
name: /etc/alternatives/rmic.1.gz
target /usr/share/man/man1/rmic-java-15-openjdk.1.gz does not exist.
name: /etc/mtab
target /proc/6457/mounts does not exist.
name: /etc/systemd/system/timers.target.wants/mandb.timer
target /usr/lib/systemd/system/mandb.timer does not exist.
**erlangen:~ #**
but of course, instead ls -l use “repair actions” the problem I have is with the repair actions, I want to change the broken links to just insert a / at the beginning of it… I don’t know how to do it… working on it.
This test works, and I think I will remove the link with the relative path and then recreate the link with the absolute path.
I don’t know if there is a better way to do it.
I cloned it from a physical machine to a virtual machine, I did it creating the filesystems in the clone and copying the files using rsync, with the physical machine running, doing
rsync -aAxXhH --delete -v / 192.168.2.160::root/
where 192.168.2.160 was the virtual machine running a system rescue CD, with the root partition mounted on /target and shared by rsyncd
When this parameter is disabled on a writable module and "use chroot" is off (or the inside-chroot path is not "/"), incoming symlinks will be modified to drop a leading slash and to remove ".." path elements that rsync believes will allow a symlink to escape the module's hierarchy.
#!/bin/bash
find /usr -type l|while read n ; do
t=$(readlink "$n")
if ! -e "$t" ]] ; then
if "$t" == usr/* ]] ; then
echo target "$t" does not exist.
**echo** ln -sf /"$t" "$n"
fi
fi
done
The above prints the missing and the necessary actions. Remove the echo to perform them.
/home/fperal/.local/share/akonadi/socket-tutatis2 which points to tmp/akonadi-fperal.5sdlq4 and should point to /[FONT=monospace]tmp/akonadi-fperal.5sdlq4 will not be corrected with that because you search in [FONT=monospace]/usr and test if the link is pointing to usr/*
Whit the sript I justo posted before I have some errors, for instance:
tutatis:/imagenes/scripts # ls -l /home/fperal/instituto/documentos\ de\ otros\ cursos/micros/18-19/transparencias/2-codificacion.sxi
lrwxrwxrwx 1 fperal 984 108 Feb 25 2021 /home/fperal/instituto/documentos de otros cursos/micros/18-19/transparencias/2-codificacion.sxi -> home/fernando/documentos/instituto/documentos de otros cursos/micros/13-14/transparencias/2-codificacion.sxi
tutatis:/imagenes/scripts # ./repairbrokenlink.sh /home/fperal/instituto/documentos de otros cursos/micros/18-19/transparencias/2-codificacion.sxi
/home/fperal/instituto/documentos
./repairbrokenlink.sh: line 15: : !=: unary operator expected
tutatis:/imagenes/scripts #
I have tried yours and I get similar errors, the problem is the names with spaces.
**tutatis:/imagenes/scripts #** cat repair.sh
#!/bin/sh
echo Link is "$1"
-L "$1" ] || { echo Not a symbolic link ; exit 0 ; }
-e "$1" ] && { echo Target exists; exit 0 ; }
link=$(readlink "$1")
echo Target is "$link"
case "$link" in
/* ) exit 0 ;;
esac
ln -sf /"$link" "$1"
**tutatis:/imagenes/scripts #** ./repair.sh /home/fperal/instituto/documentos de otros cursos/micros/18-19/transparencias/2-codificacion.sxi
Link is /home/fperal/instituto/documentos
Not a symbolic link
**tutatis:/imagenes/scripts #**
It is very unlikely if you tried it with your find command. Show the actual invocation with error.
the problem is the names with spaces.
Yes, you need to quote such name on command line, but it does not apply to find invocation. And your script of course lacks quoting completely, so readlink treats each space separated part as separate filename and returns empty string. This is common mistake in shell programming.
I missed the \ when calling the script, What I did testing your script was
tutatis:/imagenes/scripts # ./repair.sh /home/fperal/instituto/documentos de otros cursos/micros/18-19/transparencias/2-codificacion.sxi
Link is /home/fperal/instituto/documentos
Not a symbolic link
that fails, when I should have done
tutatis:/imagenes/scripts # ./repair.sh /home/fperal/instituto/documentos\ de\ otros\ cursos/micros/18-19/transparencias/2-codificacion.sxi
Link is /home/fperal/instituto/documentos de otros cursos/micros/18-19/transparencias/2-codificacion.sxi
Target is home/fernando/documentos/instituto/documentos de otros cursos/micros/13-14/transparencias/2-codificacion.sxi
tutatis:/imagenes/scripts #