在ksh环境脚本中检测交互式shell

5

如何确定给定的ksh调用是否运行交互式shell?

我在一个ENV文件中有一些命令,我希望在非交互式ksh调用(例如执行shell脚本时)中跳过它们。

我看到了一些建议,范围从开始:

if [[ $- = *i* ]]; then
    # do interactive stuff
fi

除非确定该 shell 是交互式的并使用这个神秘的咒语,否则不要甚至引用.kshrc

ENVIRON=$HOME/.kshrc                                    export ENVIRON
ENV='${ENVIRON[(_$-=1)+(_=0)-(_$-!=_${-%%*i*})]}'       export ENV
4个回答

5

我发现在ksh中,检查$-变量中是否有‘i’标志是最好的方法。

if [[ $- = *i* ]]; then
    #do interactive stuff     
fi

3
在bash中,通常在~/.bashrc的内部使用这两种方法:
  • Check if stdin is a tty:

    [ -t 0 ] || return
    

    or

    if [ -t 0 ]; then
        # do interactive stuff
    fi
    
  • Check if the prompt ($PS1) is set:

    [ -z "$PS1" ] || return
    

但我不知道如何在ksh中实现。


1
“-t N” 是确定的吗?有没有与 “$- = i” 不同的情况? - David Citron
test -t 0 是用于测试 stdin 是否为终端的命令。这与shell是否交互不同。例如,您可以运行一个从tty读取的shell脚本。 - Mikhail T.
@MikhailT Shell脚本通常不会源化~/.bashrc,对吗? - user1686
你的意思是 ~/.kshrc,@grawity。当ksh和bash作为交互式shell时,它们只读取各自的 ~/.foorc 文件。在那里检查它是没有必要的。但如果你确实要检查,最好检查得正确... - Mikhail T.
@MikhailT 你可能想要通知Debian,因为他们的bash副本编译方式不同,并且也会读取.bashrc文件进行批量SSH登录。 - user1686
更加理由去正确地检查交互性。 - Mikhail T.

0
一个合适的KSH shell在运行脚本时不应调用$ENV。然而,这是Sun的ksh88方言中存在已久的错误,并且实际上在Solaris 10中被修补了。(令人惊讶的是,Sun传统上非常不愿意改变现有的行为,因为这样的修复可能会破坏解决方法。在这种情况下,标准占了上风。)
为了防止sun的ksh88在运行脚本时读取$ENV,通常使用#!/bin/ksh -p解决方法,如果您没有/etc/suid_profile挂起,则是安全的。
然而,$-是交互式shell的可靠指示器,除非你伪造它。
$ cat interactive.sh
echo \$- = $-
[[ $- == *i* ]] && echo interactive || echo not interactive

当作为脚本运行时,会得到以下结果:

$ ksh  interactive.sh
$- = hB
not interactive

当我们伪造-i标志时,您将得到您所要求的内容:

$ ksh  -i interactive.sh
$- = imBE
interactive

当从交互式 shell 中获取时,它会执行正确的操作:

$ . ./interactive.sh
$- = imsBEl
interactive

0

也可以使用'tty -s':

The following exit values are returned:

  0        Standard input is a terminal.

  1        Standard input is not a terminal.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接