Bash

Implementierung einer Eingabeaufforderung zur Warnung vor Ausführung des rm -rf Befehls in Bash

Dieser Artikel stellt vor, wie man eine Eingabeaufforderung implementiert, die warnt, bevor der "rm -rf *"-Befehl auf der Befehlszeile in der Bash-Programmiersprache (Skriptsprache) für Linux-PCs und Server ausgeführt wird.

Shou Arisaka
5 Min. Lesezeit
31. Okt. 2025

Dieser Artikel stellt vor, wie man eine Eingabeaufforderung implementiert, die warnt, bevor der “rm -rf *“-Befehl auf der Befehlszeile in der Bash-Programmiersprache (Skriptsprache) für Linux-PCs und Server ausgeführt wird.

<>

Der Linux-Befehl rm -rf ist berühmt als einer der gefährlichsten Befehle. In den letzten Jahren habe ich Geschichten gehört, dass Serveradministratoren diesen Befehl unbeabsichtigt ausführen und alle Daten löschen.

</>

Diesmal werde ich Code vorstellen, den ich mit der Idee geschrieben habe, die Gefahr des rm -rf-Befehls auch nur ein wenig zu reduzieren.

Verwendungsbeispiel

Image

$ tmpdird # In neues Verzeichnis wechseln

$ 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 # Dateien generieren

$ 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 * # Alle Dateien löschen > Bestätigungsaufforderung > n
W: It seems You are attempting to run kind of dangerous command. Continue? [y/n]
n

$ ls # Bestätigen, dass Dateien nicht gelöscht wurden
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 * # Alle Dateien löschen > Bestätigungsaufforderung > y
W: It seems You are attempting to run kind of dangerous command. Continue? [y/n]
y

$ ls # Bestätigen, dass Dateien gelöscht wurden
total 0
166351711236005864 drwxrwxrwx 1 yuis yuis 4096 Jul 10 21:59 ..
 23080948093026057 drwxrwxrwx 1 yuis yuis 4096 Jul 10 21:59 .

Wie oben gezeigt, erscheint eine Warnmeldung vor der Ausführung, wenn Sie versuchen, rm -rf * auszuführen. y führt es aus, und n bricht die Ausführung ab.

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

Fügen Sie den obigen Code zu ${HOME}/.bashrc hinzu und versuchen Sie, einen undefinierten Befehl, somethingdangercommand, auszuführen. Da es sich um einen undefinierten Befehl handelt, würden Sie normalerweise einen Fehler erhalten, dass er undefiniert ist, aber durch Eingabe von n an der Eingabeaufforderung wird der Befehl selbst nicht ausgeführt, sodass er ohne Fehler beendet wird.

trap ‘preexec_invoke_exec’ DEBUG … Führe preexec_invoke_exec() vor jeder Befehlsausführung aus

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 … Warnen, wenn der ausgeführte Befehl rm -rf oder rm -fr ist

Bevor ein Befehl ausgeführt wird, wird gefiltert, ob der Befehl mit einem regulären Ausdruck übereinstimmt usw., und wenn er vom Filter erfasst wird, warnt es; andernfalls wird der übergebene Befehl wie üblich mit eval ausgeführt.

Referenzen

Fazit

Es scheint, dass rm -rf-Unfälle oft aufgrund von Ausrufezeichen-Expansion passieren. Wenn Sie es nicht verwenden, ist es gut, es zu deaktivieren.

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

Diesen Artikel teilen

Shou Arisaka 31. Okt. 2025

🔗 Links kopieren