self-deleting shell script

BashShell

Bash Problem Overview


I've looked around for an answer to this one but couldn't find one.

I have written a simple script that does initial server settings and I'd like it to remove/unlink itself from the root directory on completion. I've tried a number of solutions i googled ( for example /bin/rm $test.sh) but the script always seems to remain in place. Is this possible? Below is my script so far.

#! /bin/bash
cd /root/
wget -r -nH -np --cut-dirs=1 http://myhost.com/install/scripts/
rm -f index.html* *.gif */index.html* */*.gif robots.txt
ls -al /root/

if [ -d /usr/local/psa ]
	then
        echo plesk > /root/bin/INST_SERVER_TYPE.txt
	chmod 775 /root/bin/*
	/root/bin/setting_server_ve.sh
	rm -rf /root/etc | rm -rf /root/bin | rm -rf /root/log | rm -rf /root/old
	sed -i "75s/false/true/" /etc/permissions/jail.conf
        exit 1;
elif [ -d /var/webmin ]
	then
	echo webmin > /root/bin/INST_SERVER_TYPE.txt
	chmod 775 /root/bin/*
	/root/bin/setting_server_ve.sh
	rm -rf /root/etc | rm -rf /root/bin | rm -rf /root/log | rm -rf /root/old
	sed -i "67s/false/true/" /etc/permissions/jail.conf
        break
	exit 1;
else
	echo no-gui > /root/bin/INST_SERVER_TYPE.txt
	chmod 775 /root/bin/*
	/root/bin/setting_server_ve.sh
	rm -rf /root/etc | rm -rf /root/bin | rm -rf /root/log | rm -rf /root/old
	sed -i "67s/false/true/" /etc/permissions/jail.conf
        break
	exit 1;
fi	

Bash Solutions


Solution 1 - Bash

rm -- "$0"

Ought to do the trick. $0 is a magic variable for the full path of the executed script.

Solution 2 - Bash

This works for me:

#!/bin/sh

rm test.sh

Maybe you didn't really mean to have the '$' in '$test.sh'?

Solution 3 - Bash

The script can delete itself via the shred command (as a secure deletion) when it exits.

#!/bin/bash

currentscript="$0"

# Function that is called when the script exits:
function finish {
    echo "Securely shredding ${currentscript}"; shred -u ${currentscript};
}

# Do your bashing here...

# When your script is finished, exit with a call to the function, "finish":
trap finish EXIT

Solution 4 - Bash

The simplest one:

#!/path/to/rm

Usage: ./path/to/the/script/above

Note: /path/to/rm must not have blank characters at all.

Solution 5 - Bash

$0 may not contain the script's name/path in certain circumstances. Please check the following: <https://stackoverflow.com/a/35006505/5113030> (Choosing between $0 and BASH_SOURCE...)

The following script should work as expected in these cases:

  • source script.sh - the script is sourced;
  • ./script.sh - executed interactively;
  • /bin/bash -- script.sh - passed as an argument to a shell program.
#!/usr/bin/env bash

# ...

rm --  "$( readlink -f -- "${BASH_SOURCE[0]:-$0}" 2> '/dev/null'; )";

Please check the following regarding shell script source reading and execution since it may affect the behavior when a script is deleted while running: <https://unix.stackexchange.com/a/121025/133353> (How Does Linux deal with shell scripts?...)


Related: <https://stackoverflow.com/a/246128/5113030> (How can I get the source directory of a Bash script from...)

Solution 6 - Bash

I wrote a small script that adds a grace period to a self deleting script based on
user742030's answer https://stackoverflow.com/a/34303677/10772577.

function selfShred {
    SHREDDING_GRACE_SECONDS=${SHREDDING_GRACE_SECONDS:-5}
    if (( $SHREDDING_GRACE_SECONDS > 0 )); then
        echo -e "Shreding ${0} in $SHREDDING_GRACE_SECONDS seconds \e[1;31mCTRL-C TO KEEP FILE\e[0m"
        BOMB="●"
        FUZE='~'
        SPARK="\e[1;31m*\e[0m"
        SLEEP_LEFT=$SHREDDING_GRACE_SECONDS
        while (( $SLEEP_LEFT > 0 )); do
            LINE="$BOMB"
            for (( j=0; j < $SLEEP_LEFT - 1; j++ )); do
                LINE+="$FUZE"
            done
            LINE+="$SPARK"
            echo -en $LINE "\r"
            sleep 1
            (( SLEEP_LEFT-- ))
        done
    fi
    shred -u "${0}"
}

trap selfShred EXIT

enter image description here See the repo here: https://github.com/reedHam/self-shred

Solution 7 - Bash

Why remove the script at all? As other have mentioned it means you have to keep a copy elsewhere.

A suggestion is to use a "firstboot" like approach. Simply create an empty file in e.g. /etc/sysconfig that triggers the execution of this script if it is present. Then remove that file at the end of the script.

Modify the script so it has the necessary chkconfig headers and place it in /etc/init.d/ so it is run at every boot.

That way you can rerun the script at a later time simply by recreating the trigger script.

Hope this helps.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRFHView Question on Stackoverflow
Solution 1 - BashrichoView Answer on Stackoverflow
Solution 2 - BashziesemerView Answer on Stackoverflow
Solution 3 - Bashuser742030View Answer on Stackoverflow
Solution 4 - Bashuser15283025View Answer on Stackoverflow
Solution 5 - BashFaitherView Answer on Stackoverflow
Solution 6 - BashReed HambrookView Answer on Stackoverflow
Solution 7 - BashBramView Answer on Stackoverflow