我想实现一个zsh脚本,其行为取决于是否直接在 shell 的 CLI 上调用。
我一开始以为脚本可以通过查找 的i值来做到这一点$-,但我错了。
事实上,当我从命令行运行下面的脚本时
#!/bin/zsh
printf -- '%s\n' "$-"
Run Code Online (Sandbox Code Playgroud)
...我得到的输出不包括i1。
我的 shell 脚本还有其他方法可以找出这些信息吗?
注意:zsh虽然我现在正在写剧本,但我也想知道bash剧本的答案是什么。如果答案取决于OS,我主要对 Linux 和 Darwin 感兴趣。
1569X如果有人想知道的话,脚本的输出是。
$-包含i何时 shell 本身是交互式 shell、何时发出提示、允许您在终端上输入和编辑命令行、执行作业控制等。
脚本通常由非交互式 shell 解释。如果您将脚本调用为./the-script或zsh ./the-script,则该zsh实例不是交互式的。交互式 shell 解释脚本的唯一时间是当您告诉交互式 shell 使用source ./the-script或 之类的内容解释其中的代码时eval "$(<the-script)"。
在这里,在我看来,您似乎更想知道脚本是否是从终端内调用的,就像您想知道用户是否可以通过终端与其进行交互一样。
\n[/命令test(内置于 zsh 和 bash 以及大多数其他类似 Bourne 的 shell 中,但也应该作为 POSIX 系统上的独立命令存在)可以通过其-t运算符告诉您。该-t运算符采用 one\xc2\xb9 数字参数,它是一个文件描述符。
[ -t 0 ]或者test -t 0如果文件描述符 0 在终端设备上打开,则返回 true。文件描述符0是标准输入,1是标准输出,2是标准错误,所有其他fd没有任何保留的特殊含义。
所以在你的脚本中,你可以这样做:
\nif [ -t 0 ]; then\n echo "I (this script) am taking input from a terminal, so likely from a user"\nfi\n\nif [ -t 1 ]; then\n echo "My output goes to a terminal device, so will likely be seen by a user"\n [ -t 2 ] && echo errors also go there.\nfi\nRun Code Online (Sandbox Code Playgroud)\n如果您想检查脚本是否从终端会话中运行,即使其输入和/或输出可能被重定向到终端设备之外的其他文件,您可以检查是否有“终端附加到脚本” s 会话类似于:
\nif { true <> /dev/tty; } 2> /dev/null; then\n echo "there\'s a terminal device attached to my session"\nfi\nRun Code Online (Sandbox Code Playgroud)\n如果你想知道它是什么终端设备:
\ntty_on_stdin=$(tty)\nRun Code Online (Sandbox Code Playgroud)\ntty_on_stderr=$(tty <&2)\nRun Code Online (Sandbox Code Playgroud)\n{ tty_on_stdout=$(tty <&3); } 3>&1\nRun Code Online (Sandbox Code Playgroud)\n(请参阅此后续问答,了解与 fd 3 的小舞蹈背后的原因)。
\ncontrolling_tty=$(LC_ALL=C ps -o tty= -p "$$")\n[ "$controlling_tty" = \'?\' ] || controlling_tty=/dev/$controlling_tty\nRun Code Online (Sandbox Code Playgroud)\n\xc2\xb9 在早期的test/[实现中,该参数是可选的并且[ -t ]是[ -t 1 ]. POSIX 不再允许这样做,因为[ "$var" ]这与[ -n "$var" ]. 尽管如此,你会发现ksh93仍然检查 stdout 是否转到 tty,[ -t ]尽管只有当-t是字面量时;var=-t; [ "$var" ]即使 stdout 不在终端上也返回 true。
| 归档时间: |
|
| 查看次数: |
640 次 |
| 最近记录: |