
私は何かのために、かなりアドホックなインストール スクリプトを書いています。制御構造はあまりなく、基本的にはコマンドのリストだけです。各コマンドが実行される前に、ユーザーに確認してもらいたいです。すべてのコマンドの前にシェル関数名を付けずに、bash でそれを実行させる方法はありますか?
答え1
次のように使用できますextdebug
:
shopt -s extdebug
trap '
IFS= read -rn1 -d '' -p "run \"$BASH_COMMAND\"? " answer <> /dev/tty 1>&0
echo > /dev/tty
[[ $answer = [yY] ]]' DEBUG
cmd1
cmd2
...
参考までに、zsh
同等のものは次のようになります。
TRAPDEBUG() {
read -q "?run \"$ZSH_DEBUG_CMD\"? " || setopt errexit
echo > /dev/tty
}
cmd1
cmd2
...
よりポータブルに:
run() {
printf '%s ' "run $@?" > /dev/tty
IFS= read -r answer < /dev/tty
case $answer in
[yY]*) "$@";;
esac
}
run cmd1
run cmd2
run cmd3 > file
ではrun cmd3 > file
、file
と書いても は切り捨てられることに注意してくださいn
。そのため、次のように記述するといいでしょう。
run eval 'cmd3 > file'
または、次のように関数eval
に移動します。run
run() {
printf '%s ' "run $@?" > /dev/tty
IFS= read -r answer < /dev/tty
case $answer in
[yY]*) eval "$@";;
esac
}
run cmd1
run 'cmd2 "$var"'
run 'cmd3 > file'
もう一つのポータブル版ですが、制限がさらに多くなっています。
xargs -pL1 env << 'EOF'
cmd1 "some arg"
cmd2 'other arg' arg\ 2
ENV_VAR=value cmd3
EOF
これはコマンド ( にあるもの$PATH
) に対してのみ機能し、引数はリテラル文字列のみ (変数やシェル構造は使用できませんが、xargs は独自の引用符の形式を認識します) であり、リダイレクトやパイプは使用できません。