Bash 选项和交互式 shell

Bash 选项和交互式 shell

bash 的 -s 选项似乎没有真正做任何事情

当我执行带有或不带有它的命令时,没有任何变化。真正让我困惑的是,当我执行 shell 脚本时,我似乎总是得到一个交互式 shell。我假设它是交互式的,因为当我在脚本中使用 read 内置函数时,它总是提示我输入。这使它具有互动性吗?

shell 脚本在 fedora 中是否以交互方式运行,是否有 -s 可以产生差异的示例?我已经阅读了手册页,但似乎无法自己生成任何具有任何效果的示例。我合并了两个问题,因为我试图使用 s 来更改脚本接收输入的方式,并且在一些教程中他们说它有效果。我意识到它可以设置参数,我不明白的是它如何将其更改为从标准输入读取它似乎总是这样做

这是我用来测试的

if [ -v $PS1 ]
then
  echo non-interactive
else
  echo interactive
fi
read ; echo $REPLY

read 始终能够在非交互式 shell 中工作

即使当我在非交互式 shell 中测试 fd/0 和 fd/1 是否存在时,它们仍然存在

提前致谢

答案1

Bash 还将通过检查其输入/输出是否连接到终端来确定它是否是交互式的。

-s交互式开关允许 bash 脚本在从文件读取命令时处理位置参数。例如:

$ cat demo.sh
echo '$0 = ' $0
echo '$1 = ' $1
echo '$2 = ' $2

$ bash < demo.sh foo bar
bash: foo: No such file or directory

$ bash -s < demo.sh foo bar
$0 =  bash
$1 =  foo
$2 =  bar

答案2

-s选项使 bash 从其标准输入读取命令。如果没有此选项,bash 会将其第一个参数视为要执行的脚本的名称。使用此选项,bash 将其所有参数视为它在标准输入上读取的脚本的参数。该-s选项仅决定 bash 如何解释其命令行参数,而不决定 shell 实例是否是交互式的。

如果 bash 实例使用该-i选项启动,则它始终是交互式的。如果没有-i,则仅当未传递脚本名称(-s影响此)并且标准输入和标准错误都连接到终端时,它才是交互式的。

测试PS1不会告诉您 shell 实例是否是交互式的。您可以PS1在交互式 shell 中取消设置。相反,非交互式 shell 通常继承PS1其环境。测试 shell 是否以交互方式运行的可靠方法是测试是否$-contains i

read内置函数可在任何 shell 中运行,无论是否交互式。它从连接到 shell 标准输入的任何内容中读取(除非重定向)。如果您尝试从 bash 正在读取其正在执行的脚本的同一文件描述符中进行读取,您最终会在脚本中跳过一行(不一定是在您想要的位置);例如,如果您在 bash 的标准输入上传递脚本,并且想要从终端读取一行,则需要重定向调用readread line </dev/tty

文件描述符 0、1 和 2 始终存在(除非它们已被关闭);它们分别是标准输入、标准输出和标准错误。 shell 是否是交互式的与标准描述符指向的内容无关,除了 fd 0 和 2 是否是终端会影响 shell 的交互状态之外。

1是的,我知道有些网页声明了这一点。他们错了。

答案3

有关交互式 shell 的更多信息:

您可以通过检查来了解 shell 是否是交互式的$-。如果$-包含i,则 shell 是交互式的。

当 shell 直接读取用户的输入时,它是交互式的。非交互式 shell 从文件中逐行读取命令并执行它们。当从脚本内的 stdin 读取任何内容时,它不会使 shell 交互,因为“脚本读取输入,而不是 shell”(不知道如何更好地解释这一点)。

    labdebian# cat ./test
    #!/bin/bash
    echo Hello World
    echo $-
    read; echo $REPLY
    echo $-

    labdebian# bash test
    Hello World
    hB
    I'm typing this
    I'm typing this
    hB

    labdebian# bash -i test
    Hello World
    himB
    I'm typing this
    I'm typing this
    himB

答案4

-s不会使您的 shell 具有交互性。代替使用-i

相关内容