如何检测输入是来自参数、文件还是终端

Mar*_*ker 8 shell io-redirection

在 bash 中,有没有办法知道给定的脚本是否已被调用:

$ myscript.sh myfile
Run Code Online (Sandbox Code Playgroud)

或者:

$ myscript.sh < myfile
Run Code Online (Sandbox Code Playgroud)

在一些脚本中,我总是访问myfilewith的内容$1,但现在我想根据不同的情况更改行为。

编辑:在没有任何重定向的情况下调用时,我还想要第三种情况:

$ myscript.sh
Run Code Online (Sandbox Code Playgroud)

unp*_*nic 13

编辑:更改-t-t 0,它可以正确检测来自终端或文件的输入。

我认为这里的关键是知道您的输入是来自终端还是来自文件。对此有一个测试(man test,请参阅-t)。

假设您正在运行 bash 脚本:

if [ -t 0 ]; then
    echo "Input from terminal"
    if [ $# -eq 0 ]; then
        echo "No input files specified on command line.  Error." >&2
    else
        echo "Input file given on command line.  It is $1"
    fi
else
    echo "Input coming from stdin"
fi
Run Code Online (Sandbox Code Playgroud)

您可以通过将实际代码替换为上面的 echo 语句来处理不同的场景。

更新,快速测试脚本:

#!/bin/bash
[ -t 0 ] && echo "t is true" || echo "t is false"
Run Code Online (Sandbox Code Playgroud)

跑步:

$ test.sh testfile
t is true
$ test.sh < testfile
t is false
$
Run Code Online (Sandbox Code Playgroud)


Ric*_*rri 6

通常,表达式$1$2等扩展为脚本命令行上给出的第 1 个、第 2 个等参数。

因此,当您调用脚本时:

myscript.sh myfile
Run Code Online (Sandbox Code Playgroud)

然后$1在脚本中扩展到myfile(和$2$3等等都是空字符串)。

当您调用脚本时:

myscript < myfile
Run Code Online (Sandbox Code Playgroud)

STDIN from 的重定向myfile是由父 shell 完成的,因此实际上不带参数调用脚本并$1扩展为空字符串。