Bashが入力行全体を読み込んだ後、その行でコマンドを実行する前に結果を表示するにはどうすればよいですか?

Bashが入力行全体を読み込んだ後、その行でコマンドを実行する前に結果を表示するにはどうすればよいですか?

~からBash マニュアル、セクション 6.6 エイリアス

  …常にスラム読む前に行全体を少なくとも1つ入力してください。 実装するその行のすべてのコマンド。コマンドが実行されると、エイリアスが拡張されます。読む、そんなときはしないで 処刑された。したがって、他のコマンドと同じ行に表示されるエイリアス定義は、次の入力行を読むまで適用されません。

ここで私は理解する方法を見つけようとしています。 次のうち、「入力の行全体を読んで」「該当行からコマンドを実行する」ときにシェルが何をするのですか?

結果を表示するためのコマンドと例はありますか?

  • 後ろに 吹く 読む 1行全体を入力してください。
  • しかし、今後 実装するこの行にコマンドがありますか?

例えば、

  • 「入力の行全体を入力してください」は、複数のコマンドで構成される複合コマンドです。
  • 「完全な入力ライン」は、複数の複合コマンドのパイプライン、パイプラインのリストなどでもあります。

答え1

これを理解する良い方法は、次の例を見ることです。https://stackoverflow.com/questions/38526612/bash-unable-to-set-and-use-alias-in-the-same-line

たとえば、次のコマンドを実行しようとします。

$ alias foo="echo bac" ; foo;
-bash: foo: command not found
$ foo
bac

bashは行全体を読み込み、fooエイリアスがないため拡張されません(エイリアスは読み取ると拡張されます)。この行が実行されると、エイリアスが設定され、エラーが発生します。

答え2

あなたが引用したBashマニュアルのセクションは次のとおりです。

エイリアスは、コマンドの実行時ではなく、コマンドの読み込み時に拡張されます。したがって、他のコマンドと同じ行に表示されるエイリアス定義は、次の入力行を読むまで適用されません。

したがって、エイリアシングは、実際に行を読むことと実行することの違いを示す例の1つです!

これを明確にするために複合コマンドがあります。まずエイリアスを定義してから、それを試してみます。

alias echo=uname; echo

Bashに慣れていない人は、このコマンドの出力がLinux(または実行しているオペレーティングシステムが何であるか)期待することができますが、実際には何も出力しません。 Bashが最初だからです。読む行をクリックしてエイリアス定義を適用します。 Bashが見るものは次のとおりです。

alias echo=uname; echo

2番目のものechoには変換されませんuname。これは、Bashalias echo=unameがまだコマンドを実行していないためです。読むそれ。 Bash はその行を読んだ後、読んだ内容を実行します。したがって、以下が実行されます。

alias echo=uname; echo(上記の通り正確に読み取られています)

と入力して、Bashがコマンドを実行したことを確認することもできますecho。以前にエイリアスを定義したので、読み込みechoフェーズでエイリアスを変換して Bash を実行します。unameuname

簡単に言うと:

$ alias echo=uname; echo

$ echo
Linux

編集する:

編集、Bashが入力行を読んだ後、実際に実行する前に結果を表示する方法があるかどうか尋ねました。答えは「はい」です。しかし、日常的な使用にはあまり便利ではありません(ただし、シェルの中で何が起こっているのかを理解するのは間違いなく便利です)。

次の内容でファイルを作成します。

#!/bin/bash
shopt -s expand_aliases
trapped() {
    echo "On line ${1}, Bash sees: $BASH_COMMAND"
}
trap 'trapped ${LINENO}' DEBUG
alias echo=uname; echo
echo

次にファイルを実行します。

以下は、スクリプトの仕組みの説明です。

  • shopt -s expand_aliases非対話モードでも、別名を拡張するように Bash に指示します (この例のように)。
  • 次に関数を定義しますtrapped()。呼び出されると、この関数は現在実行中のコマンドを(引数として渡された行番号とともに)印刷します。
  • 私たちはそれと呼びますtrap 'trapped ${LINENO}' DEBUG。これはBashに「という信号を見るたびに最初にDEBUG実行trapped ${LINENO}します。DEBUGこれはBashが自動的に生成した信号です。簡単なコマンドを実行する前に。つまり、trapped()コマンドが実行される前に関数が呼び出されます。
  • 最後に、デモのためにいくつかのコマンドを実行します。しかし、他の何かが起こる前に実行されるトラップがあるので、trapped()Bashはすぐに実行される内容を印刷します。このLINENO変数は、現在行番号を提供する Bash 組み込み変数です。

コマンドを実行せずに「実行」し、Bashが読んでいる内容を続けるには、extdebugBashのマニュアルのオプションを見てください。

答え3

あなたの質問はあまり明確ではありませんが、あなたの文の並置は

注文するとき読む、そんなときはしないで処刑された

そして

いつもクソ閉じて読む前に行全体を少なくとも1つ入力してください。 実装するその行のすべてのコマンド。

質問の焦点がエイリアス拡張であることを示します。 (Bashマニュアルの抜粋を除いて、あなたの質問にエイリアスがまったく記載されていないので、「提案」と言います。)

質問の元のバージョン

Bashがその行でコマンドを実行する前に、常に入力の行全体を読み取ることをどのように証明できますか?

これを行う唯一の実際の方法は、デバッグ/監視/追跡ツールの種類を使用してシェルの内部状態を確認することです。これは少し非現実的です。  小さなペンギンの答え手動引数で手動コンテンツをサポートする方法を示します。以下は(IMO)より明確な答えのバリエーションです。

$エイリアスmyalias =日付

$エイリアスmyalias = "ls -ld";
2017年8月4日金曜日午前3時33分33分

シェルが実行を開始する前に(2番目)、行全体を完全に読み取る必要があると言えます。なぜなら、シェルが実行されると、次のようにmyalias実行されるからです。エイリアスが実行されるdateとに上書きされるため、シェルは次に拡張する必要があります。myaliasls -ldmyaliasdate

alias myalias="ls -ld"

コマンドなので、その行からコマンドを実行する前に、入力行全体を読み取る必要があります。


あなたの修正された質問、

Bashが入力行全体を読み込んだ後、その行でコマンドを実行する前に結果を表示するにはどうすればよいですか?

この場合、より意味があります。コマンドラインを見たいと思います。エイリアス拡張  その行でコマンドを実行する前、つまりエイリアス拡張の結果を確認してください。私の考えでは、あなたは次のようなものを見たいと思います。

alias myalias="ls -ld"; date

私が知る限り、その出力を得る方法はありません。エイリアスが拡張された完全な行です。ただし、xtrace-x)オプションは近いです。

$セット-x

$エイリアスmyalias =日付
+エイリアスmyalias =日付

$エイリアスmyalias = "ls -ld";
+ エイリアス 'myalias=ls -ld'
+日付                                                         ←エイリアス拡張
2017年8月4日金曜日午前3時33分42分

もちろん、これは拡張された各コマンドが実行される前にのみ出力されるため、エイリアス拡張の結果はコマンドの出力と混在します。さらに、これは次のように表示されます。みんな拡張:

$animal=猫
+動物=猫

$echo こんにちは、myalias "$animal" R*
+エコこんにちは
こんにちは
+世界に反響を起こす
世界
+ls -ld cat 追加情報ファイル                                            ←エイリアス拡張
ls:アクセスできません。 cat:そのファイルまたはディレクトリはありません。
-rw-r--r--2マイユーザー名マイグループ名  489 2015年2月22日読む

私たちはそれを見ることができませんls -ld "$animal" R*。変数拡張とパス名(glob)拡張後にのみ表示できます。また、パイプでは「うまく動作」しません。

$エイリアスmyalias =日付
+エイリアスmyalias =日付

$エイリアス|
+日付                                                         ←エイリアス拡張
+od-cb
0000000 8月04、2 0 1金曜日
        106162151054040101165147040060064054040062060061
0000020 7 9:4 2:1午後7時\ n
        067040040071072064062072061067040120115012
0000036

トレース出力は、date2 つの別々の行に合計を表示します。 (出力に不明な場合は、od -cb元のコマンドラインを見て、それが実行している操作を把握する必要があります。)date | od -cb

関連情報