Look for, backup and delete symlinks

Hi,

My first post here:
Was looking if someone can help enhancing my code.
I am limited to sh or ash shell (android / busybox)

I made a script to look for busybox symlinks, backup them and delete them

I have these questions about the below code:

  • busybox tar do not has the options to append to an archive, any workaround for my script to avoid backing up separate files?

  • I want to avoid grep to search for busybox string in the readlink output results. if [[ str1 == *busybox ]] option is not recognized in my case

  • any other advises about that script are welcome

Thanks a lot

#!/system/xbin/busybox sh
# or android shell /bin/sh

bkdir="/sdcard/bb-uninstall" ; 
if [ -d "$bkdir" ] ; 
	then 
		busybox echo "Backup folder $bkdir already exists. Please remove it to proceed...">>$bkdir/__Error_Backup_Folder_Already_Exists__.txt ; 
		busybox echo "Backup folder \"$bkdir\" already exists. Please remove it to proceed..." ; 
		exit 1 ; 
	else 
		busybox mkdir $bkdir ; 
		if [ ! -d "$bkdir" ] ; 	 
			then 
				busybox echo "Backup folder \"$bkdir\" could not be created" ; 
				busybox echo "Check if sdcard is present, mounted, has free space or you have permissions!!" ; 
				exit 1 ; 
		fi ; 
fi ; 

bbdir="/system/xbin /system/bin" ; 
ndeletes=0 ; 
for bbpath in $bbdir ; 
	do 
		for f in $(busybox find $bbpath -type l) ; 
			do 
				gnr=$(busybox readlink $f) ; 
				if echo "$gnr" |busybox grep -q busybox ; 
					then 
						busybox echo -e "$f \t is linked to \t $gnr ---> backup up in sdcard then deleted">>$bkdir/bb-uninstall.log ; 
						bkfile=`busybox echo "$f" | busybox tr '/' '.'` ; 
						bkfile=bak$bkfile ; 
						busybox tar zcf $bkdir/$bkfile.tar.gz -C / ${f:1} ; 
						if [ ! -f "$bkdir/$bkfile.tar.gz" ] ; 
							then 
								busybox echo "Error while creating backup file \"$bkdir/$bkfile.tar.gz\"" ; 
								busybox echo "File \"$f\" was not deleted" ; 
								busybox echo "Check free space on \"$bkdir\" or if you have needed permissions" ; 
								busybox echo "Uninstall will stop. Launch it again after fixing write issue to \"$bkdir\"" ; 
								exit 1 ; 
						fi ; 
						busybox echo "$f linking to $gnr backed-up. Now deleting" ; 
						busybox rm $f ; 
						ndeletes=`busybox expr $ndeletes + 1` ; 
					else busybox echo "$f is not linked to busybox, but to $gnr ---> file not deleted">>$bkdir/bb-uninstall.log ; 
				fi ; 
		done 
done 


echo >>$bkdir/bb-uninstall.log ; 
echo "=========================================">>$bkdir/bb-uninstall.log ; 
echo "  Busybox Uninstaller v1.0 Completed !!  ">>$bkdir/bb-uninstall.log ; 
echo "=========================================">>$bkdir/bb-uninstall.log ; 
echo "               - Details -               ">>$bkdir/bb-uninstall.log ; 
echo "Number of deleted files: $ndeletes">>$bkdir/bb-uninstall.log ; 
echo "Busybox cleaned folders: \"$bbdir\"">>$bkdir/bb-uninstall.log ; 
echo "Backup folder: \"$bkdir\"">>$bkdir/bb-uninstall.log ; 
echo "Log file: \"$bkdir/bb-uninstall.log\"">>$bkdir/bb-uninstall.log ; 
echo >>$bkdir/bb-uninstall.log ; 

echo ; 
echo "=========================================" ; 
echo "  Busybox Uninstaller v1.0 Completed !!  " ; 
echo "=========================================" ; 
echo "               - Details -               " ; 
echo "Number of deleted files: $ndeletes" ; 
echo "Busybox cleaned folders: \"$bbdir\"" ; 
echo "Backup folder: \"$bkdir\"" ; 
echo "Log file: \"$bkdir/bb-uninstall.log\"" ; 
echo ; 

You could use a case statement to match the "busybox" string:

case "$gnr" in
    *busybox*)
                ....
    ;;
    *)
               ....
    ;;
esac

---------- Post updated at 09:48 AM ---------- Previous update was at 09:35 AM ----------

Think you are going to have to resort to rebuilding the tar with your new/replaced files:

  • Extract existing tar archive into a temp area
  • copy additional/replacement files into same structure
  • retar the whole thing
  • delete the temp area.

---------- Post updated at 09:54 AM ---------- Previous update was at 09:48 AM ----------

Don't think ${f:1} is supported under ash you man need to use ${f#?} instead.

Thank you a lot for the support

Using case in: again, no advantage over grep, as both are external commands to the shell. Using Grep permits me to continue with the if/else structure
Any other way to replace this part of code:

if [[ $gnr == *busybox ]] 

By the way, I tried also this one:

if [ $gnr = "$bbpath/busybox" ]; 

But it ends detecting all symlinks as related to busybox, even those that are not related to it. Any reason you see for that?

Should I try

if [[ $gnr = "$bbpath/busybox" ]]; 

?

Did not think at it that way, good idea :slight_smile:

Edit:
${f:1} worked fine under /bin/sh (android) and also with the busybox ash I use actually. But thank you for the other alternative