【问题标题】:AIX Interactive ShellAIX 交互式外壳
【发布时间】:2018-07-11 02:18:17
【问题描述】:

我希望我能区分脚本何时以交互方式运行与“at”或“cron”运行。如果用户在命令行上运行脚本,我想将输出放到他们的屏幕上,但如果它通过 'at' 或 'cron' 运行,那么输出将转到日志文件。

我在网上搜索并看到了很多关于使用“$-”的建议(尽管不是针对 AIX 的)。这听起来很有希望,但当我尝试时,它并没有那么有用。

如果我在提示符下键入“echo "$-"',我会返回 "ims"。如果我使用 echo 命令创建一个脚本,它会返回“h”。如果我通过“at”提交脚本,我得到“h”,如果我让 cron 运行它,我得到“h”。

我还研究了使用 TERM 和 PS1,但它们再次不允许我区分由“cron”或“at”运行的脚本与在命令行调用的脚本。

还有什么我可以在 AIX 上尝试的吗?

谢谢。

如果我运行这个脚本

格伦。这是我正在运行的脚本。我使用“tty -s”而不是“$-”得到了想要的结果。难道我做错了什么?你看到“$-”的结果总是说我不在交互式 shell 中。

   #!/bin/ksh93
   echo "tty -s"
   if tty -s 
   then 
      echo "   - I'm an interactive shell"
   else 
      echo "   - I'm not interactive"
   fi
   echo "\$-"
   case $- in
   *i*) echo "   - I'm an interactive shell";;
   *)   echo "   - I'm not interactive";;
   esac

当脚本通过 1) 命令行、2) “at”和 3) cron 运行时,我得到了这三个结果集。

command line result

tty -s
   - I'm an interactive shell
$-
   - I'm not interactive

at result

tty -s
   - I'm not interactive
$-
   - I'm not interactive

Cron result

tty -s
   - I'm not interactive
$-
   - I'm not interactive

通过在命令行运行我的意思是我正在运行“script.ksh >> script.log”。如果我从命令行运行“echo $-”,它会返回“ims”,但是当脚本中引用 $- 时,它总是返回“h”。

【问题讨论】:

    标签: unix ksh aix


    【解决方案1】:

    您想检查$- 是否包含 字母i。如果是这样,您就有了一个交互式外壳:

    case $- in
    *i*) echo "I'm an interactive shell";;
    *)   echo "I'm not interactive";;
    esac
    

    测试

    $ ksh
    $ case $- in
    > *i*) echo "I'm an interactive shell";;
    > *)   echo "I'm not interactive";;
    > esac
    I'm an interactive shell
    
    $ ksh <<'END'
    > case $- in
    > *i*) echo "I'm an interactive shell";;
    > *)   echo "I'm not interactive";;
    > esac
    > END
    I'm not interactive
    

    鉴于下面的 cmets,您可能想要使用这个内置测试:

    if [ -t 0 ]; then
        : # script running interactively
    else
        # running non-interactively (cron or at)
        # redirect output to a log file
        exec 1>/path/to/logfile 2>&1
    fi
    # and now, your script can just output to stdout/stderr
    # and the output will go to the screen or to the logfile
    echo "hello"
    date
    print -u2 "bye"
    

    【讨论】:

    • 我确实尝试过使用“$-”(参见原始帖子)。当我在命令行中键入“echo '$-'”时,它会返回“ims”,但如果我将该行放入脚本并运行脚本,则值将更改为“h”。当我通过“at”或作为 cron 作业运行脚本时,它也是“h”。我希望能够区分何时从命令行运行脚本与何时通过“at”或“cron”运行。
    • 我知道。我读了那个。您不想查看$- 的全部内容。正如我上面写的,你需要检查$-是否包含字母i
    • 格伦。我编辑了原始问题,向您展示了使用“$-”和“tty -s”得到的结果。 "$-" 总是表示非交互式。
    • 接下来的 15 天我将不在办公室,所以我会在 21 日之前回复任何问题。谢谢。
    • tty 命令只是让您知道标准输入是否来自终端。比较 sh -c 'tty -s &amp;&amp; echo interactive || echo not'sh -c 'tty -s &amp;&amp; echo interactive || echo not' &lt;/dev/null
    【解决方案2】:

    如果用户在命令行上运行脚本,我想将输出放到他们的屏幕上,但如果它通过 'at' 或 'cron' 运行,那么输出将转到日志文件。

    这就是标准输出和重定向的好处。您也可以使用命令tty -s 来确定您的标准输入是否是终端。 (如果您想检查您的标准输出tty -s &lt;&amp;1

    示例(~projects/tmp/tty_test.sh):

    #!/bin/sh
    
    exec >>~projects/tmp/tty_test.log 2>&1
    
    tty
    
    if tty -s; then echo terminal
    else            echo otherwise
    fi
    

    【讨论】:

    • tty -s 不允许我区分何时从命令行运行脚本与何时通过“at”或“cron”运行。不管我如何运行脚本,'tty -s' 返回 0,表示交互式。我错过了什么吗?我想要这样,当脚本在命令行运行时,输出会出现在屏幕上,但如果它是通过“at”或“cron”运行的,它应该转到一个文件。
    • 现在可以使用了。我错误地使用了 "if [[ $(tty -s) -eq 0 ]] 这显然(嗯,现在至少)不正确。谢谢。
    猜你喜欢
    • 2016-04-16
    • 1970-01-01
    • 2015-09-26
    • 2014-01-11
    • 2021-09-28
    • 2013-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多