使用完成的命令创建别名

使用完成的命令创建别名

我讨厌rm -rf /*,所以我想回应一些事情而不是运行rm -rf /*。我怎样才能做到这一点?

答案1

我想,你说的“讨厌”是指你害怕意外运行这个程序?

该命令rm -r /(带或不带-f)将提示您:

rm: it is dangerous to operate recursively on `/'
rm: use --no-preserve-root to override this failsafe

不幸的是,当您指定 时它不会检查这一点/*,因为后者会扩展到每个文件夹中。虽然大多数文件夹及其内容都是安全的(因为您没有使用sudo),但不幸的是,您的主文件夹中的内容将被删除。

这个问题没有简单的答案。你可以编写一个函数来.bashrc检查这个问题,但这会非常复杂:该函数必须:

  • 检查选项是否包含-r-R--recursive,以及是否使用了--no-preserve-root
  • 查看非选项参数以确定是否可能使用了/*

我认为-f或者--force可以被忽略,因为没有这个,命令仍然有能力造成严重破坏。

我编写了一个脚本来执行此操作。它如下所示。只需将其添加到文件末尾即可~/.bashrc关闭所有打开的终端并重新打开终端,它应该可以工作了。

警告,警告, 警告,警告

  1. 彻底测试在现场使用之前。
  2. 我在脚本中将echo实际命令放在前面(就在最后),以便您进行测试。这意味着当您运行它时,它将显示命令而不是实际运行它。当您彻底测试它后,请编辑您的以删除单词。rm~/.bashrcecho
  3. 这适用于你的终端。确实如此不是适用于 root,即 sudo。因此,它将仍然造成破坏如果你运行sudo rm -rf /*。要使它适用于 sudo… 嗯,一定有办法,但抱歉,我不知道怎么做。:(我相信这里有聪明人会想出办法,在这种情况下,我可以将其添加到此回复中。(如果你能保证 sudo 总是使用相同的 ,那么就有办法,${PATH}但我不认为这是真的。)

脚本如下:

#---------------------------------------------------------------------------------------------------
#    Amendment to rm
#
#    Check if it is likely that the user called rm on root with recursion but without the option
#    --no-preserve-root
#    If so, display a warning. Otherwise, allow rm to continue unhindered.
#---------------------------------------------------------------------------------------------------


function rm ()
{
    # Extract all of the options and parameters.
    local -r GETOPT="$( getopt --longoptions=force,interactive::,one-file-system,no-preserve-root,recursive,dir,verbose,help,version    \
                               --options=fiIrRdv -- "${@}"
                      )"

    # Replace the current parameters with the interpreted ones from rm.
    eval set -- "${GETOPT}"

    # Define variables to use in the function.
    local -i FILES_COUNT=0                              # The number of files and folders found.
    local ALL_ROOT=true                                 # Assume true unless found otherwise.
    local RECURSIVE_USED=false                          # Unless found true.
    local NO_PRESERVE_ROOT_USED=false                   # Unless found true.
    local PARAM                                         # To hold the parameter being inspected.
    local INTERACTIVE_STATE=false                       # Whether we are expecting an option to --interactive.

    # Run through the parameters to find if we should catch this command.
    for PARAM
    do
        # Handle the option --interactive first.
        if ${INTERACTIVE_STATE}
        then
            INTERACTIVE_STATE=false                     # Turn off the interactive state.

        elif [[ ${PARAM} == '--interactive' ]]
        then
            INTERACTIVE_STATE=true

        elif [[ ${PARAM} == '-r' || ${PARAM} == '-R' || ${PARAM} == '--recursive' ]]
        then
            RECURSIVE_USED=true

        elif [[ ${PARAM} == '--no-preserve-root' ]]
        then
            NO_PRESERVE_ROOT_USED=true

        elif [[ ${PARAM} =~ ^- ]]
        then
             :                                          # Ignore any option that we don't care about.                          

        else
            : $(( ++FILES_COUNT ))                      # Keep count.
            if ! [[ ${PARAM} =~ ^/ ]]
            then
                 ALL_ROOT=false                         # This isn't a root file or folder.
            fi
        fi
    done

    # Is this likely to be the command that we are searching for?
    if (( FILES_COUNT > 0 )) && ${RECURSIVE_USED} && ${ALL_ROOT} && ! ${NO_PRESERVE_ROOT_USED}
    then
        # Yes! Recursive; all root files and folders; and missing no-preserve-root.
        # Leave a message and exit with an error.
        echo 'You are using rm to remove all root files and folders.'         >&2
        echo 'Please use --no-preserve-root if that is really what you want.' >&2
        return 3
    fi

    # No, this is (supposedly) safe. Run the command.
    echo rm "${@}"

} # rm

相关内容