Search code examples
bashshellaliasrm

Aliasing the rm command to avoid evaluating separate asterisks


I would like to use the rm command such that it returns an error when there is a separate asterisk in its argument. For example, if I type rm -f * .txt , then this command should not be executed (this way I have already removed several files unintentionally). Could you please help me what the simplest way is to do this?


Solution

  • As discussed in comments, there is normally no way for an rm alias or function to detect if it was run with a * that was expanded by the shell to a list of arguments. This Bash function demonstrates a possible alternative way to help with your problem:

    function rm
    {
        local arg
        for arg in "$@"; do
            if [[ $arg != -* && ! -L $arg && ! -e $arg ]]; then
                printf 'rm: ERROR: argument does not exist: %q\n' "$arg" >&2
                printf '    Nothing is being removed\n' >&2
                return 1
            fi
        done
    
        command rm "$@"
    }
    
    • The function checks all of its arguments. It prints an error message and returns immediately with non-zero status if any of them isn't an option, isn't a symlink, and isn't an ordinary file, directory, or special file. The explicit check for a symlink is necessary because a symlink to a non-existing path fails the -e test. For instance, if run with rm * .txt it will delete nothing because it will detect a non-existing .txt file.
    • If none of the arguments fails the checks, it runs the real rm on the full list of arguments.