スクリプトの出力がevalに渡されることを確認する方法はありますか?

スクリプトの出力がevalに渡されることを確認する方法はありますか?

プログラム/スクリプトの出力が特にbashスクリプトからevalに渡されることを確認したいと思います。

たとえば、次のものを区別できます。

$ ./program.sh

~から

$ eval "$(./program.sh)"

program.sh内で?後者は評価する環境変数を印刷しますが、最初のものはそうではありません。

./program.sh print-envこれにより、試用版に配信するためのプログラムを開発する必要がなくなります。

一方、この可能性があれば、evalIdea?に渡された出力を作成することが可能であることがわかります。

答え1

存在する:

eval "$(./program.sh)"

シェルは./program.shパイプにリダイレクトされた標準出力として実行され、パイプのもう一方の端にあるメモリの出力を読み取ります。その後、./program/sh消えたら(そのパイプにeofが表示され、その後wait()プロセスを完了するためにほとんどのシェルから返されます)、保存された内容から末尾の改行文字を引いたものがeval

したがって、このような状況を検出するには、./program.sh次のものが必要です。

  1. 標準出力がパイプであることを検出します。それは簡単です。 Linuxでは使用できます[ -p /dev/stdout ]
  2. これはパイプの反対側の端からデータを読み取るシェルプロセスです。これはさらに複雑になります。最近のLinuxでは、10より大きいfdを読むためにパイプを開いた名前で終わるプロセスlsofの出力を見ることができます。lsof +E -Fca -ap "$$" -d 1sh
  3. eval something次に、シェルプロセスが現在のコマンドラインを解釈していることを確認する必要があります。これを行うには、デバッガをシェルに接続し、特定のシェルの内部データ構造を理解して、実際にどのコマンドが実行されたかを確認する必要があります。

簡単に言えば、あなたはできません。しかし、出力がttyに行くときとそうでないときに異なる出力を提供することに満足することができ、これは問題になる可能性があります。

if [ -t 1 ]; then
  echo output for tty
else
  echo output for something else
fi

関連情報