我有一些bash函数可以输出一些信息:
我一直在编写读取输出并过滤它的函数:
function filter-epson {
find-modelname-in-epson-ppds | sed <bla-blah-blah>
}
function filter-hp {
find-modelname-in-hp-ppds | sed <the same bla-blah-blah>
}
etc ...
但我认为最好做这样的事情:
function filter-general {
(somehow get input) | sed <bla-blah-blah>
}
然后调用另一个高级函数:
function high-level-func {
# outputs filtered information
find-modelname-in-hp/epson/...-ppds | filter-general
}
如何通过最好的bash实践实现这一目标?
答案 0 :(得分:42)
如果问题是How do I pass stdin to a bash function?
,那么答案是:
Shellscript函数以普通的方式使用stdin,就好像它们是命令或程序一样。 :)
input.txt中:
HELLO WORLD
HELLO BOB
NO MATCH
test.sh:
#!/bin/sh
myfunction() {
grep HELLO
}
cat input.txt | myfunction
输出:
hobbes@metalbaby:~/scratch$ ./test.sh
HELLO WORLD
HELLO BOB
请注意,命令行参数也是以普通方式处理的,如下所示:
test2.sh:
#!/bin/sh
myfunction() {
grep "$1"
}
cat input.txt | myfunction BOB
输出:
hobbes@metalbaby:~/scratch/$ ./test2.sh
HELLO BOB
答案 1 :(得分:13)
令人痛苦地明确表示我正在从标准输出管道输出,我有时会写
cat - | ...
答案 2 :(得分:5)
直接致电sed
。就是这样。
function filter-general {
sed <bla-blah-blah>
}
答案 3 :(得分:-1)
非常简单意味着将stdin转换为变量是使用read
。默认情况下,它读取文件描述符“ 0”,即标准输入,即/dev/stdin
。
示例功能:
input(){ local in; read in; echo you said $in; }
示例实现:
echo "Hello World" | input
结果:
您说过Hello World
当然,您不需要将变量声明为局部变量。我只是出于良好形式将其包括在内。普通的read in
会满足您的需求。
因此,您了解read
的工作方式,默认情况下,它会从给定的文件描述符(或隐式stdin)读取数据,并 blocks 直到遇到换行符。在大多数情况下,即使您不知道输入内容,也会隐式地将其附加到输入中。如果您有一个似乎“挂起”的函数,则使用此机制就可以牢记这一点(还有其他方法使用read
来处理此问题)。
在前面的示例中添加了一个变体,可让您通过标准输入或参数传递输入:
input()
{
local in=$1 if [ -z "$in" ]; then read in; fi
echo you said $in
}
通过这种调整,您还可以像下面这样调用函数:
input "Hello World"
如何处理stdin选项以及其他多个参数?许多标准nix实用程序,尤其是那些通常与stdin / stdout一起使用的实用程序,都遵循将破折号-
表示为“默认”的通用做法,即上下文表示stdin或stdout,因此您可以遵循约定,并且将指定为-
的参数视为“ stdin”:
input()
{
local a=$1; if [ "$a" == "-" ]; then read a; fi
local b=$2
echo you said $a $b
}
这样称呼:
input "Hello" "World"
或
echo "Hello" | input - "World"
更进一步,实际上没有理由仅将stdin限制为仅 first 参数的选项!您可能会创建一个超级灵活的函数,可以将其用于其中任何一个...
input()
{
local a=$1; if [ "$a" == "-" ]; then read a; fi
local b=$2; if [ "$b" == "-" ]; then read b; fi
echo you said $a $b
}
那你为什么呢?因为您可以制定并插入您可能需要的任何参数...
myFunc | input "Hello" -
在这种情况下,我使用myFunc
的结果输入第二个参数,而不是唯一使用第一个参数的选项。