如何使一个可以从标准input读取的bash函数?
我有一些脚本的参数工作,他们工作得很好,但我希望他们能够从标准input读取,例如,从一个例子,假设这被称为读:
#!/bin/bash function read() { echo $* } read $*
现在这个read "foo" "bar"
,但我想用它作为:
echo "foo" | read
我如何做到这一点?
您可以使用<<<
来获得这种行为。 read <<< echo "text"
应该做到这一点。
readly
testing(我不喜欢使用保留字):
function readly() { echo $* echo "this was a test" } $ readly <<< echo "hello" hello this was a test
使用pipe道,基于对“Bash脚本,从stdinpipe道读取值”的答案 :
$ echo "hello bye" | { read a; echo $a; echo "this was a test"; } hello bye this was a test
编写一个可以读取标准input的函数有点棘手,但是在没有标准input的情况下可以正常工作。 如果您只是尝试从标准input中读取数据,它将会阻塞,直到接收到任何数据,就像在提示中inputcat
一样。
在bash 4中,可以通过使用-t
选项来read
参数0来解决此问题。如果有任何可用的input,但是不会消耗任何input,则成功; 否则,它失败。
这里有一个简单的函数,如果它有标准input的任何东西,就像cat
一样,否则就是echo
。
catecho () { if read -t 0; then cat else echo "$*" fi } $ catecho command line arguments command line arguments $ echo "foo bar" | catecho foo bar
这使得标准input优先于命令行参数,即echo foo | catecho bar
echo foo | catecho bar
会输出foo
。 要使参数优先于标准input( echo foo | catecho bar
输出bar
),可以使用更简单的函数
catecho () { if [ $# -eq 0 ]; then cat else echo "$*" fi }
(这也有与任何 POSIX兼容的shell,而不仅仅是某些版本的bash
)。
结合其他答案到我的工作(这个人为的例子把小写input转换成大写):
uppercase() { local COMMAND='tr [:lower:] [:upper:]' if [ -t 0 ]; then if [ $# -gt 0 ]; then echo "$*" | ${COMMAND} fi else cat - | ${COMMAND} fi }
一些例子(第一个没有input,因此没有输出):
:; uppercase :; uppercase test TEST :; echo test | uppercase TEST :; uppercase <<< test TEST :; uppercase < <(echo test) TEST
一步步:
-
testing文件描述符0(
/dev/stdin
)是否被terminal打开if [ -t 0 ]; then
-
testingCLI调用参数
if [ $# -gt 0 ]; then
-
将所有CLI参数回显到命令
echo "$*" | ${COMMAND}
-
否则,如果
stdin
是pipe道(即不是terminalinput),输出stdin
命令(cat -
和cat
是cat /dev/stdin
简写)else cat - | ${COMMAND}
下面是使用printf
和标准input的bash中的sprintf
函数的示例实现:
sprintf() { local stdin; read -d '' -u 0 stdin; printf "$@" "$stdin"; }
用法示例:
$ echo bar | sprintf "foo %s" foo bar
这会给你一个想法如何从标准input读取function。