ワニの首に近づいたら、沼地を空にすることが目標だったことを忘れがちです。
—人気のあることわざ
問題はについてですがecho
、これまでの回答の大部分はset +x
コマンドをこっそり入れる方法に焦点を当ててきました。はるかに単純で直接的なソリューションがあります。
{ echo "Message"; } 2> /dev/null
({ …; } 2> /dev/null
以前の回答で見なかった場合は考えなかったかもしれないことを認めます。)
これはやや面倒ですが、連続したecho
コマンドのブロックがある場合、各コマンドで個別に行う必要はありません。
{
echo "The quick brown fox"
echo "jumps over the lazy dog."
} 2> /dev/null
改行がある場合、セミコロンは必要ないことに注意してください。
非標準のファイル記述子(例:3)で永続的に
開き、常に発言する代わりに発言するというkenorbのアイデアを使用することで、入力の負担を軽減でき/dev/null
ます。2>&3
2> /dev/null
この記事の執筆時点で、最初の4つの答えは、特別な(そして、ほとんどの場合、面倒な)何かやって必要と
すべてのあなたが時間をecho
。すべての echo
コマンドで実行トレースを抑制したい場合(そしてなぜそうしないのですか?)、大量のコードを変更せずにグローバルに行うことができます。まず、エイリアスがトレースされないことに気付きました。
$ myfunc()
> {
> date
> }
$ alias myalias="date"
$ set -x
$ date
+ date
Mon, Oct 31, 2016 0:00:00 AM # Happy Halloween!
$ myfunc
+ myfunc # Note that function call is traced.
+ date
Mon, Oct 31, 2016 0:00:01 AM
$ myalias
+ date # Note that it doesn’t say + myalias
Mon, Oct 31, 2016 0:00:02 AM
(次のスクリプトスニペットは#!/bin/sh
、/bin/sh
bashへのリンクであっても、shebangがの場合に機能することに注意してください。しかし、shebangがの場合、#!/bin/bash
追加する必要がありますshopt -s expand_aliases
スクリプトでエイリアスを取得コマンドをます。
だから、私の最初のトリック:
alias echo='{ set +x; } 2> /dev/null; builtin echo'
さて、私たちが言うときecho "Message"
、私たちはトレースされないエイリアスを呼び出しています。エイリアスはトレースオプションをオフにし、set
コマンドからのトレースメッセージを抑制し(user5071535の回答で最初に提示された手法を使用)、実際のecho
コマンドを実行します。これにより、 echo
コマンドごとにコードを編集する必要なく、user5071535の回答と同様の効果を得ることができます。ただし、これによりトレースモードはオフのままになります。set -x
エイリアスでは単語を文字列に置き換えることしかできないため、エイリアスにa を入れることはできません(少なくとも簡単にはできません)。引数の後にコマンドにエイリアス文字列の一部を挿入することはできません
(例:)"Message"
。したがって、たとえば、スクリプトに
date
echo "The quick brown fox"
echo "jumps over the lazy dog."
date
出力は
+ date
Mon, Oct 31, 2016 0:00:03 AM
The quick brown fox
jumps over the lazy dog.
Mon, Oct 31, 2016 0:00:04 AM # Note that it doesn’t say + date
したがって、メッセージを表示した後でも、トレースオプションをオンに戻す必要があります。ただし、連続したコマンドのブロックごとに1回だけecho
です。
date
echo "The quick brown fox"
echo "jumps over the lazy dog."
set -x
date
あとでset -x
自動化を行うことができればいいのですecho
が、もう少し巧妙にできます。しかし、それを提示する前に、これを考慮してください。OPは、#!/bin/sh -ex
シバンを使用するスクリプトから始まります。暗黙的にユーザーx
はシェバンからを削除し、実行トレースなしで正常に動作するスクリプトを使用できます。その特性を保持するソリューションを開発できたらいいと思います。ここでの最初のいくつかの答えは、そのプロパティが失敗します。なぜなら、echo
それが既にオンになっているかどうかに関係なく、無条件でafter ステートメントでトレースを「戻す」からです。
この回答は、この問題を置き換えるので、その問題を顕著に認識できません echo
トレース出力付きの出力。したがって、トレースをオフにすると、すべてのメッセージが消えます。echo
ステートメントの後に条件付きでトレースをオンに戻すソリューションを紹介します-既にオンになっている場合のみ。これを無条件でトレースを「元に戻す」ソリューションにダウングレードするのは簡単であり、演習として残しておきます。
alias echo='{ save_flags="$-"; set +x;} 2> /dev/null; echo_and_restore'
echo_and_restore() {
builtin echo "$*"
case "$save_flags" in
(*x*) set -x
esac
}
$-
オプションリストです。設定されているすべてのオプションに対応する文字の連結。たとえば、e
とx
オプションが設定されている場合、と$-
を含む文字の寄せ集めにe
なりx
ます。新しいエイリアス(上記)は、$-
トレースをオフにする前の値を保存します。次に、トレースをオフにして、制御をシェル関数にスローします。その関数は実際に実行し、エイリアスが呼び出されたときにオプションがオンになっているecho
かどうかを確認しx
ます。オプションがオンの場合、関数はそれをオンに戻します。オフの場合、関数はオフのままにします。
上記の7行(を含める場合は8行shopt
)をスクリプトの先頭に挿入し、残りはそのままにしておくことができます。
これにより、
- 次のシバン行のいずれかを使用するには:
#!/ bin / sh -ex
#!/ bin / sh -e
#!/ bin / sh –x
または単なるプレーン#!/ bin / sh
期待どおりに動作するはずです。
- のようなコードを持っている
(シバン)
コマンド1
コマンド2
コマンド3
-xを設定
コマンド4
コマンド5
コマンド6
+ xを設定
コマンド7
コマンド8
コマンド9
そして
- コマンド4、5、および6はトレースされます—それらの1つが
echo
である場合を除き、その場合、コマンドは実行されますがトレースされません。(ただし、コマンド5がの場合echo
でも、コマンド6は引き続きトレースされます。)
- コマンド7、8、および9はトレースされません。コマンド8がであっても
echo
、コマンド9はまだトレースされません。
- コマンド1、2、および3は、シバンにが含まれているかどうかに応じて(4、5、6など)またはトレースされません(7、8、9など)
x
。
PS私は、私のシステムでbuiltin
は、中間回答(キーワードの単なるエイリアスecho
)のキーワードを省略できることを発見しました。これは驚くことではありません。bash(1)は、エイリアスの展開中、…
…展開されているエイリアスと同一の単語は、再度展開されません。これは、たとえばにエイリアスls
する可能性がls -F
あり、bashは置換テキストを再帰的に展開しようとしないことを意味します。
当然のことながら、キーワードが省略されたecho_and_restore
場合、最後の答え(を持つもの)は失敗します1。しかし、奇妙なことに、それを削除して順序を切り替えると機能します:builtin
builtin
echo_and_restore() {
echo "$*"
case "$save_flags" in
(*x*) set -x
esac
}
alias echo='{ save_flags="$-"; set +x;} 2> /dev/null; echo_and_restore'
__________
1 未定義の動作を引き起こすようです。私は見た
- 無限ループ(おそらく無制限の再帰のため)
/dev/null: Bad address
エラーメッセージ、および
- コアダンプ。
echo +x; echo "$*"; echo -x
エイリアスで同等のことをする方法を提示できるなら、私はそれを見たいです。