我只想从我的 POSIX shell 脚本确定它是否以交互方式运行,但由于某种原因,以下函数:
running_interactively()
{
printf '%s' ${-} | grep -F i > /dev/null 2>&1
}
即使我在终端中运行脚本也会返回 false。我是否做错了,或者交互式脚本的定义是否与我在终端中由用户运行脚本的简单想法有所不同?
代码片段:
#!/bin/sh
set -u
running_interactively()
{
# echo $- returns only u
printf '%s' ${-} | grep i > /dev/null 2>&1
}
print_error_and_exit()
{
# redirect all output from this function to standard error stream
if running_interactively
then
exec >&2
else
echo wrong again, smart ass
fi
...
}
print_error_and_exit someArgs
答案1
shell 脚本除非源自交互式 shell,否则很少在交互式 shell 环境中运行。这意味着$-
不会包含i
.
你什么可以检查的目的是查看标准输入是否连接到终端。这是使用-t
带有参数0
(标准输入流的文件描述符)的测试来完成的:
running_interactively () { [ -t 0 ]; }
这假设“正在交互运行”意味着“能够直接从终端读取输入”。
还可以对文件描述符 2(标准错误)进行额外测试,作为能否在脚本中与用户进行全面交互的测试。用户交互主要发生在标准输入(用户输入)和标准错误(提示、诊断消息等)上:
running_interactively () { [ -t 0 ] && [ -t 2 ]; }
但是,如果脚本的输出被重定向或通过管道传输,则对文件描述符 1(标准输出)进行测试将会失败。