Aqui está uma solução possível, mas ela interceptará todos os comandos, não apenas aqueles inseridos por meio do prompt (assim, os comandos nos scripts também ficarão presos). Você pode ter que modificá-lo para conseguir o que deseja.
Primeiro, defina a opção shopt extdebug
.
Do manual :
If set, behavior intended for use by debuggers is enabled:
1- The -F option to the declare builtin (see Bash Builtins) displays the source file name and line number corresponding to each function name supplied as an argument.
2- If the command run by the DEBUG trap returns a non-zero value, the next command is skipped and not executed.
3- If the command run by the DEBUG trap returns a value of 2, and the shell is executing in a subroutine (a shell function or a shell script executed by the . or source builtins), a call to return is simulated.
4- BASH_ARGC and BASH_ARGV are updated as described in their descriptions (see Bash Variables).
5- Function tracing is enabled: command substitution, shell functions, and subshells invoked with ( command ) inherit the DEBUG and RETURN traps.
6- Error tracing is enabled: command substitution, shell functions, and subshells invoked with ( command ) inherit the ERR trap.
(ênfase minha)
Você precisa deste comando para cancelar a execução do comando digitado pelo usuário e chamar sua função personalizada. Se isso não estiver definido, o Bash chamará sua função personalizada e executará o comando do usuário.
Em seguida, use aspas simples para escrever sua armadilha para evitar a expansão da variável Bash:
trap 'caller >/dev/null || xxx $BASH_COMMAND' DEBUG
Agora, se a sua função xxx
retornar um valor diferente de zero (por exemplo, 1
), o comando do usuário não será executado.
Aqui está um exemplo completo:
$ shopt -s extdebug
$ xxx() { if [ "$1" = 'sudo' ]; then echo "No sudo, please.";return 1; fi }
$ trap 'caller >/dev/null || xxx $BASH_COMMAND' DEBUG
$ ls
foo bar
$ sudo ls
No sudo, please.
Neste exemplo, xxx
verifica se a primeira palavra do comando é sudo
e, em caso afirmativo, imprime uma mensagem e cancela o comando. Você pode obter o comando do usuário inteiro em xxx
usando "$*"
.