有没有办法查明脚本的输出是否正在传递给 eval?

有没有办法查明脚本的输出是否正在传递给 eval?

我试图找出程序/脚本的输出是否被传递给 eval,尤其是在 bash 脚本中。

例如,我可以区分:

$ ./program.sh

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

在program.sh内?后者将打印要评估的环境变量,而第一个则不会。

这将使我免于开发./program.sh print-env用于传递到 eval 的程序。

另一方面,我可以看到,有了这种可能,就有可能编写出在输出传递到eval.想法?

答案1

在:

eval "$(./program.sh)"

shell 将./program.sh在其标准输出重定向到管道的情况下运行,并在管道的另一端读取内存中的输出。然后,一旦./program/sh消失(导致在该管道上看到 eof,并且随后wait()由进程上的大多数 shell 完成返回),保存的内容减去尾随换行符将被传递到eval.

因此,为了./program.sh检测这种情况,需要:

  1. 检测到它的标准输出是一个管道。这很容易。在 Linux 上,可以使用[ -p /dev/stdout ].
  2. 这是一个在管道另一端读取数据的 shell 进程。这变得更加复杂。在使用最近的 Linux 上lsof,您可以在 的输出中查找lsof +E -Fca -ap "$$" -d 1名称以sh该结尾的进程,该进程打开了管道以读取大于 10 的 fd。
  3. 然后您需要确定该 shell 进程当前正在解释eval something命令行。为此,您可能需要将调试器附加到该 shell 并了解该特定 shell 的内部数据结构,以查看它实际运行的命令。

简而言之,你不能。但也许您可以满足于在输出进入 tty 时和不进入 tty 时提供不同的输出,这应该只是一个问题:

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

相关内容