我正在尝试自动为 shell 设置 verbose 和 xtrace 选项,这些选项从未连接到终端的标准输入读取命令(该测试是由 at(1) 和 batch(1) 执行的代理)命令,如果有更好的也可以接受)。
我本来想
if [[ -o SHIN_STDIN ]] && ! test -t 0 ; then
PS4="> "
setopt verbose xtrace
fi
在我的 .zshenv 中可以解决这个问题,但事实并非如此,尽管我已经检查过 .zshenv 确实正确执行,并且在[[ -o SHIN_STDIN ]] && !test -t 0 && echo OK
批量启动时收到了预期的电子邮件。
我缺少什么?
注意 tcsh 认为此类 shell 是交互式的(它将提示设置为非空值)。 zsh 不会(使用 -o Interactive 进行测试,不读取 .zprofile、.zshrc)。我觉得奇怪的是 -o SHIN_STDIN .zshenv 和批处理注册的命令执行之间的值发生变化。
答案1
sh_in_stdin
不是on
在解释时~/.zshenv
或解释任何源文件时(在这些情况下,shell 代码不是来自 stdin)。您可以通过添加echo $options[shinstdin]
到您的~/.zshenv
或运行来验证它:
$ echo 'echo $options[shinstdin]; source =(<<<"echo \$options[shinstdin]")' | zsh
on
off
您可以检查是否$PPID
正在运行atd
:
if [[ $(ps -o comm= -p $PPID) = atd ]]; then...
zsh
就我个人而言,我不喜欢对从 atd 运行的每个调用无条件执行此操作的想法。
您始终可以定义一个debug-at
命令来执行以下操作:
debug-at() {
{
echo 'PS4="> "; set -o verbose -o xtrace'
cat
} | at "$@"
}
并使用它,而不是at
当您确实希望at
/batch
作业在调试状态下运行时。
请注意,并非所有系统都使用$SHELL
解释提供的代码。 Debianat
没有。POSIX 让它由实现定义。无论使用什么 shell(只要它是类似 Korn/POSIX 的),上述方法都可以工作。