gpt4 book ai didi

bash 使用标准输入作为变量

转载 作者:行者123 更新时间:2023-12-02 00:56:24 25 4
gpt4 key购买 nike

我想确保我的脚本在用户使用如下语法时能够正常工作:

script.sh firstVariable < SecondVariable

出于某种原因,我无法让它工作。

我想要 $1=firstVariable并且 $2=SecondVariable

但出于某种原因,我的脚本认为只有 firstVariable 存在?

最佳答案

这是经典X-Y problem .目标是编写一个实用程序,其中

utility file1 file2

utility file1 < file2

具有相同的行为。似乎很想找到一种方法,通过(以某种方式)找出标准输入的“名称”,然后以与使用第二个参数相同的方式使用该名称,以某种方式将第二次调用转换为第一次调用。不幸的是,这是不可能的。重定向发生在调用实用程序之前,并且没有可移植的方法来获取打开的文件描述符的“名称”。 (实际上,在 other_cmd | utility file1 的情况下,它甚至可能没有名称。)

因此解决方案是关注所要求的内容:使两种行为保持一致。这是大多数标准实用程序(grepcatsort 等)的情况:如果未指定输入文件,实用程序使用 stdin

在许多 unix 实现中,stdin 实际上有一个名称:/dev/stdin。在这样的系统中,可以轻松实现上述目标:

utility() {
utility_implementation "$1" "${2:-/dev/stdin}"
}

utility_implementation 实际上做任何需要做的事情。第二个参数的语法是正常默认 parameter expansion ;如果 $2 存在且非空,它表示 $2 的值,否则表示字符串 /dev/stdin。 (如果您省略 - 使其成为“${2:/dev/stdin}”,那么如果 $2 存在并且空,这可能会更好。)

另一种解决问题的方法是确保第一个语法与第二个语法相同,这样输入总是来自stdin,即使是命名文件。显而易见的简单方法:

utility() {
if (( $# < 2 )); then
utility_implementation "$1"
else
utility_implementation "$1" < "$2"
fi
}

另一种方法是使用 exec 命令和重定向来重定向 shell 自己的 stdin。请注意,我们必须在子 shell ((...) 而不是 {...}) 以便重定向不适用于调用该函数的 shell:

utility() (
if (( $# > 1 )) then; exec < "$2"; fi
# implementation goes here. $1 is file1 and stdin
# is now redirected to $2 if $2 was provided.
# ...
)

关于bash 使用标准输入作为变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34610880/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com