Bash

Implementing a Prompt to Warn Before Executing rm -rf Command in Bash

This article introduces how to implement a prompt that warns before executing the "rm -rf *" command on the command line in the Bash programming language (scripting language) for Linux PCs and servers.

Shou Arisaka
4 min read
Nov 10, 2025

This article introduces how to implement a prompt that warns before executing the “rm -rf *” command on the command line in the Bash programming language (scripting language) for Linux PCs and servers.

<>

The Linux command rm -rf is famous as one of the most dangerous commands. In recent years, I’ve heard stories of server administrators unintentionally executing this command and deleting all data.

</>

This time, I’ll introduce code I wrote with the idea of reducing the danger of the rm -rf command even a little.

Usage Example

Image

$ tmpdird # Move to new directory

$ ls
total 0
166351711236005864 drwxrwxrwx 1 yuis yuis 4096 Jul 10 21:59 ..
 23080948093026057 drwxrwxrwx 1 yuis yuis 4096 Jul 10 21:59 .

$ genfiles 3 # Generate files

$ ls
total 0
166351711236005864 drwxrwxrwx 1 yuis yuis 4096 Jul 10 21:59 ..
  8444249304069546 -rwxrwxrwx 1 yuis yuis    2 Jul 10 21:59 3.txt
 23080948093026057 drwxrwxrwx 1 yuis yuis 4096 Jul 10 21:59 .
 51509920740553578 -rwxrwxrwx 1 yuis yuis    2 Jul 10 21:59 2.txt
 36310271996515302 -rwxrwxrwx 1 yuis yuis    2 Jul 10 21:59 1.txt

$ rm -rf * # Delete all files > confirmation prompt > n
W: It seems You are attempting to run kind of dangerous command. Continue? [y/n]
n

$ ls # Confirm files are not deleted
total 0
166351711236005864 drwxrwxrwx 1 yuis yuis 4096 Jul 10 21:59 ..
  8444249304069546 -rwxrwxrwx 1 yuis yuis    2 Jul 10 21:59 3.txt
 23080948093026057 drwxrwxrwx 1 yuis yuis 4096 Jul 10 21:59 .
 51509920740553578 -rwxrwxrwx 1 yuis yuis    2 Jul 10 21:59 2.txt
 36310271996515302 -rwxrwxrwx 1 yuis yuis    2 Jul 10 21:59 1.txt

$ rm -rf * # Delete all files > confirmation prompt > y
W: It seems You are attempting to run kind of dangerous command. Continue? [y/n]
y

$ ls # Confirm files are deleted
total 0
166351711236005864 drwxrwxrwx 1 yuis yuis 4096 Jul 10 21:59 ..
 23080948093026057 drwxrwxrwx 1 yuis yuis 4096 Jul 10 21:59 .

As shown above, when you try to execute rm -rf *, a warning prompt appears before execution. y executes it, and n cancels execution.

Code


ok(){

  : <<< '
  yes or no prompt
  e.g. printf "The file alredy exist here. Override it? " ; ok && echo y || echo n
  '

  read -n 1 -r ; [[ $REPLY =~ ^[Yy]$ ]] && { echo ; return 0 ; } || { echo ; return 1 ; }

}

red='\e[1;31m'
grn='\e[1;32m'
yel='\e[1;33m'
blu='\e[1;34m'
mag='\e[1;35m'
cyn='\e[1;36m'
end='\e[0m'

warn(){
  printf "${yel}W: ${*}\n${end}" >&2
}

##

shopt -s extdebug

preexec_invoke_exec () {
    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    [ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # don't cause a preexec for $PROMPT_COMMAND
    local this_command=`HISTTIMEFORMAT= history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//"`;

    # So that you don't get locked accidentally
    if [ "shopt -u extdebug" == "$this_command" ]; then
        return 0
    fi

        # // filtering

    # Modify $this_command and then execute it
    # eval "${this_command}"

    # echo "${this_command}"

    if [[ "${this_command}" =~ ^(somethingdangercommand$|somethingdangercommand[[:space:]]) ]]; then warn "It seems You are attempting to run kind of dangerous command. Continue? [y/n]" ; ok && eval "${this_command}" || return
  elif [[ "${this_command}" =~ ^(anotherSomethingdangercommand$|anotherSomethingdangercommand[[:space:]]) ]]; then warn "It seems You are attempting to run kind of dangerous command. Continue? [y/n]" ; ok && eval "${this_command}" || return
elif [[ "${this_command}" =~ ^(rm[[:space:]][-rf]{3}$|rm[[:space:]][-rf]{3}[[:space:]]) ]]; then warn "It seems You are attempting to run kind of dangerous command. Continue? [y/n]" ; ok && eval "${this_command}" || return
  else eval "${this_command}"
    fi

        # // filtering

    return 1 # This prevent executing of original command
}

trap 'preexec_invoke_exec' DEBUG

Add the above code to ${HOME}/.bashrc, and try executing an undefined command, somethingdangercommand. Since it’s an undefined command, normally you would get an error saying it’s undefined, but by entering n at the prompt, the command itself is not executed, so it exits without an error.

trap ‘preexec_invoke_exec’ DEBUG … Execute preexec_invoke_exec() before each command execution

elif [[ ”${this_command}” =~ ^(rm[[:space:]][-rf]{3}$|rm[[:space:]][-rf]{3}[[:space:]]) ]]; then warn “It seems You are attempting to run kind of dangerous command. Continue? [y/n]” ; ok && eval ”${this_command}” || return … Warn when the executed command is rm -rf or rm -fr

Before executing a command, it filters whether the command matches a regular expression, etc., and if caught by the filter, it warns; otherwise, it evals the passed command as usual.

References

Conclusion

It seems that rm -rf accidents often happen due to exclamation expansion. If you’re not using it, it’s good to disable it.

# disable/turn off history expansion `!` altogether
set +H

Share this article

Shou Arisaka Nov 10, 2025

🔗 Copy Links