environment-variables - 如果调用它的shell 是交互式 shell,如何从 shell script 中进行判断?

  显示原文与译文双语对照的内容
0 0

我试图设置一个 shell script,只有当它从交互式 shell 调用时才会启动 screen 会话( 或者重新加入现有的) 。 我看到的解决方案是检查 $- 是否包含字母"i":


#!/bin/sh -e

echo"Testing interactivity..."
echo 'Current value of $- = '"$-"
if [ `echo $- | grep -qs i` ]; then
 echo interactive;
else
 echo noninteractive;
fi

但是,这会失败,因为脚本是由一个新的非交互式 shell 运行的,因为它在顶部的#!/bin/sh 。 如果我源代码而不是运行它,它就像期望的那样工作,但这是一个丑陋的黑客。 当我运行它的时候我宁愿让它工作。

那么如何在脚本中测试交互?

时间: 原作者:

0 0

尝试一下,看看它是否符合你的要求:


#!/bin/sh
if [ $_!= $0 ]
then
 echo interactive;
else
 echo noninteractive;
fi

下划线( $_ ) 扩展到用于调用脚本的绝对路径名。 零( $0 ) 扩展到脚本的名称。 如果它们是不同的,那么脚本就从调用interactive交互式的。 在Bash中,随后的$_ 扩展给了前面命令( 将 $_的值保存在另一个变量中可能是一个好主意,以便保存它)的扩展参数。

来自 man bash:


 0 Expands to the name of the shell or shell script. This is set
 at shell initialization. If bash is invoked with a file of com‐
 mands, $0 is set to the name of that file. If bash is started
 with the -c option, then $0 is set to the first argument after
 the string to be executed, if one is present. Otherwise, it is
 set to the file name used to invoke bash, as given by argument
 zero.
 _ At shell startup, set to the absolute pathname used to invoke
 the shell or shell script being executed as passed in the envi‐
 ronment or argument list. Subsequently, expands to the last
 argument to the previous command, after expansion. Also set to
 the full pathname used to invoke each command executed and
 placed in the environment exported to that command. When check‐
 ing mail, this parameter holds the name of the mail file cur‐
 rently being checked.

原作者:
0 0

虽然 $_ 可能在must中工作,但可能不能在每个兼容的sh中工作。

$PS1 将只在 shell 是交互式的情况下设置。 这样就可以了


if [ -z"$PS1" ]; then
 echo noninteractive
else
 echo interactive
fi

原作者:
0 0

尝试 tty

if tty 2>&1 |grep not ; then echo"Not a tty"; else echo"a tty"; fi

tty实用程序将附加到标准输入的终端的名称写入标准输出。 写入的名称是由 ttyname(3) 返回的字符串。 如果标准输入不是终端,则消息``not将写入一个 tty''。

原作者:
0 0

你可以尝试使用类似。


if [[ -t 0 ]]
then
 echo"Interactive...say something!"
 read line
echo $line
else
 echo"Not Interactive"
fi

测试字段中的"-t"switch 检查给定的文件描述符是否与终端( 如果输出将打印到终端,也可以执行这个操作,例如) 匹配。 在这里,它检查程序中的标准是否与终端匹配。

0 0

简单答案:不在` 或者 [ ] 中运行这些命令。

这里不需要任何一个构造。


显然我不能确定你所期望


[ `echo $- | grep -qs i` ]

要测试但我不认为它在测试你认为它在测试的内容。

代码将执行以下操作:

  • 运行 echo $- | grep -qs i 在子shell的内部。
  • 捕获子shell输出的标准。
  • 用包含输出的字符串替换原始的` 表达式。
  • 将该字符串作为参数传递给 [ 命令或者在( 取决于你的shell ) 中生成。
  • 仅当该字符串为非空时,才从 [ 生成成功的返回代码。

一些可能的问题:

  • 无论是哪种类型的-qs 选项,都应该使用选项来生成无输出,因此我希望 [ 测试空字符串,而不管它是。
  • 反斜杠还可能转义美元符号并导致文本'美元减'( 而不是变量的内容) 被发送到 grep

另一方面,如果你移除了 [ 和引号,而是说


if echo"$-" | grep -qs i ; then

然后:

  • 当前 shell 将使用你要测试的值扩展 "$-"
  • echo.. . | 会把它送到 grep的标准输入上
  • 如果输入包含字母 igrep 将返回成功的返回代码,
  • 由于 -qs 标志,grep 将不输出输出,因此
  • if 语句将使用 grep 返回代码来决定要选哪个分支。

同样:

  • 没有反引号将替换任何在运行时产生输出的命令,并且
  • 没有 [ 命令会尝试用一些返回代码替换 grep的返回代码,它已经尝试从 grep 生成的输出。

有关如何使用 if 命令的更多信息,请参见本节 excellent 。

原作者:
0 0

如果要测试 $-的值而不分叉外部进程( 比如 。 grep ) 然后,你可以使用以下技术:


if ["${-%i*}"!="$-" ]
then
 echo Interactive shell
else
 echo Not an interactive shell
fi

这将从 $-的值中删除 i*的任何匹配,然后检查它是否有任何差异。


( ${parameter/from/to} 构造( 比如 。 ["${-//[!i]/}" ="i" ] 可以在Bash脚本中使用 true ,但是在Debian和Ubuntu系统中不存在。

原作者:
...