この種の機能が必要なプログラムを作成しようとしています。プロセスは次のとおりです。
- ユーザーはbashコマンドを入力します。
- ユーザーはEnterキーを押します。
- 私のスクリプトはコマンド、現在のディレクトリを変数として取得します。プログラムはオプションでコマンドを変更できます。
- 変更されたコマンドは正常に実行されます。
これを行う方法はありますか?
注:このプログラムは個人的な目的に必要なので、このプログラムを配布しないでください。
ベストアンサー1
私はこれについていくつかの研究をしました。 bashTRAP
とオプションを使用してshopt
これを達成できます。
.bash_profileに追加してください。
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
# Modify $this_command and then execute it
return 1 # This prevent executing of original command
}
trap 'preexec_invoke_exec' DEBUG
仕組みは次のとおりです。
trap 'function_name' DEBUG
function_name
bashコマンドが実行される前に実行されます。ただし、デフォルトreturn
は元のコマンドには影響しません。
shopt -s extdebug
いくつかのデバッグ機能を有効にします。そのうちの1つは、元のコマンドを実行する前に戻り値を確認します。
注:shopt -u extdebug
元のコマンドが常に実行されるように、この機能を無効にします。
ドキュメントextdebug
(2番目の機能を参照):
If set, behavior intended for use by debuggers is enabled:
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.
If the command run by the DEBUG trap returns a non-zero value, the next command is skipped and not executed.
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.
BASH_ARGC and BASH_ARGV are updated as described in their descriptions (see Bash Variables).
Function tracing is enabled: command substitution, shell functions, and subshells invoked with ( command ) inherit the DEBUG and RETURN traps.
Error tracing is enabled: command substitution, shell functions, and subshells invoked with ( command ) inherit the ERR trap.