Bash 脚本如何知道它是如何运行的?

Aes*_*ula 12 scripting bash terminal nautilus

我有一个 Bash 脚本,我试图帮助我运行一个相当复杂的命令,它有一些小的更改,它会通过 echo 和 read 询问我。

我找到了强制它运行终端来执行命令的解决方案,但我对此不感兴趣。我希望它做的是,如果我腾出空间并在 Nautilus 中按 Enter 键(使其与 Run Software 一起运行),它会轻轻弹出一个通知,说“请从终端运行它”。

我可以让弹出窗口发生——就像我知道命令一样——但我无法让 Bash 脚本判断它是否在终端内运行,它似乎总是这么认为。甚至有可能吗?

gol*_*cks 10

man bash条件表达式

-t fd  
    True if file descriptor fd is open and refers to a terminal.
Run Code Online (Sandbox Code Playgroud)

假设 fd 1 是标准的,if [ -t 1 ]; then应该适合你。该高级Shell脚本指南的索赔-t用这样的方式将故障转移ssh,并且测试(使用标准输入,标准输出不)因此应为:

if [[ -t 0 || -p /dev/stdin ]]
Run Code Online (Sandbox Code Playgroud)

-p测试文件是否存在并且是命名管道。 但是,从经验上我会注意到这对我来说不是真的:-p /dev/stdin正常终端和 ssh 会话都失败,而if [ -t 0 ](或-t 1) 在这两种情况下都有效(另请参阅下面关于高级 Shell 脚本指南该部分问题的 Gilles 评论)。


如果主要问题是一个专门的上下文,您希望从中调用脚本以适合该上下文的方式运行,您可以避开所有这些技术细节,并通过使用包装器和自定义变量来为自己省去一些麻烦:

!#/bin/bash

export SPECIAL_CONTEXT=1
/path/to/real/script.sh
Run Code Online (Sandbox Code Playgroud)

调用这个live_script.sh或其他什么,然后双击那个。您当然可以使用命令行参数完成同样的事情,但是仍然需要一个包装器来在 GUI 文件浏览器中进行指向和单击工作。

  • 这是正确的答案 - 这也是 POSIX 所说的 shell 应该检测它是否是交互式的。 (5认同)
  • Advanced Bash-Scripting Guide 中的那部分有几个错误。`PS1` 不是判断 shell 是否交互的可靠测试。“如果一个脚本需要测试它是否在交互式 shell 中运行”也令人困惑:它应该是如果*某些代码*需要测试——脚本通常不在交互式 shell 中运行(但它可以,如果它是来源)。在 `$-` 中测试 `i` 是测试 shell 是否具有交互性的正确方法。测试 `-t 0` 或 `-t 2` 是判断脚本是否在终端中运行的正确方法,这与交互式不同。 (3认同)
  • @DanielAmaya - 如果您重定向输入,则脚本不会在终端上运行。问题是如何检测脚本是否正在终端上运行。 (2认同)
  • 你确定在 `[ ... ]` 中使用 `||` 吗?如果你使用 `[[ … ]]` 那么它会很好,但通常 `||` 用于分隔命令,并且 `[ -t 0` 是对 `[` 的错误调用,因为它的最后一个 `]`不见了。通常也没有命令`-p`。我同意对终端进行测试;这可能就是这样做的方法。这只是我关心的语法。 (2认同)