我有一些使用参数的脚本,它们工作得很好,但我希望它们能够从stdin中读取,例如管道,例如,假设这被称为read:
#!/bin/bash
function read()
{
echo $*
}
read $*
现在这适用于read "foo" "bar"
,但我想将其用作:
echo "foo" | read
我如何做到这一点?
答案 0 :(得分:39)
您可以使用<<<
来获取此行为。 read <<< echo "text"
应该成功。
使用readly
进行测试(我不喜欢使用保留字):
function readly()
{
echo $*
echo "this was a test"
}
$ readly <<< echo "hello"
hello
this was a test
使用管道,基于this answer to "Bash script, read values from stdin pipe":
$ echo "hello bye" | { read a; echo $a; echo "this was a test"; }
hello bye
this was a test
答案 1 :(得分:36)
编写一个可以读取标准输入的函数有点棘手,但在没有给出标准输入时可以正常工作。如果您只是尝试从标准输入读取,它将阻塞直到它收到任何内容,就像您只是在提示符下键入cat
一样。
在bash 4中,您可以使用参数为0的-t
read
选项解决此问题。如果有任何输入可用,但不消耗任何输入,则成功;否则,它会失败。
这是一个简单的函数,如果它有标准输入的任何内容,就像cat
一样,否则echo
。{/ p>
catecho () {
if read -t 0; then
cat
else
echo "$*"
fi
}
$ catecho command line arguments
command line arguments
$ echo "foo bar" | catecho
foo bar
这使得标准输入优先于命令行参数,即echo foo | catecho bar
将输出foo
。要使参数优先于标准输入(echo foo | catecho bar
输出bar
),您可以使用更简单的函数
catecho () {
if [ $# -eq 0 ]; then
cat
else
echo "$*"
fi
}
(它还具有使用任何 POSIX兼容shell的优势,而不仅仅是某些版本的bash
)。
答案 2 :(得分:13)
将许多其他答案组合成对我有用的答案(这个人为的例子将小写输入变为大写):
uppercase() {
local COMMAND='tr [:lower:] [:upper:]'
if [ -t 0 ]; then
if [ $# -gt 0 ]; then
echo "$*" | ${COMMAND}
fi
else
cat - | ${COMMAND}
fi
}
一些例子(第一个没有输入,因此没有输出):
:; uppercase
:; uppercase test
TEST
:; echo test | uppercase
TEST
:; uppercase <<< test
TEST
:; uppercase < <(echo test)
TEST
一步一步:
测试终端是否打开了文件描述符0(/dev/stdin
)
if [ -t 0 ]; then
测试CLI调用参数
if [ $# -gt 0 ]; then
回显命令
的所有CLI参数echo "$*" | ${COMMAND}
如果管道stdin
(即不是终端输入),则输出stdin
到命令(cat -
和cat
是cat /dev/stdin
的简写)
else
cat - | ${COMMAND}
答案 3 :(得分:5)
以下是使用sprintf
和标准输入的bash中printf
函数的示例实现:
sprintf() { local stdin; read -d '' -u 0 stdin; printf "$@" "$stdin"; }
使用示例:
$ echo bar | sprintf "foo %s"
foo bar
这将让您了解函数如何从标准输入中读取。
答案 4 :(得分:0)
我发现可以使用btn.isTreasure()
和test
在一行中完成此操作...
awk
test -p /dev/stdin && awk '{print}' /dev/stdin
测试管道输入,通过stdin接受输入。只有输入存在才能运行test -p
,否则它将无限期地挂起,等待永远不会出现的输入。
我已将此功能放入功能中以便于使用...
awk
...用法
inputStdin () {
test -p /dev/stdin && awk '{print}' /dev/stdin && return 0
### accepts input if any but does not hang waiting for input
#
return 1
}
另一个函数使用awk而不进行测试等待命令行输入......
_stdin="$(inputStdin)"
...用法
inputCli () {
local _input=""
local _prompt="$1"
#
[[ "$_prompt" ]] && { printf "%s" "$_prompt" > /dev/tty; }
### no prompt at all if none supplied
#
_input="$(awk 'BEGIN {getline INPUT < "/dev/tty"; print INPUT}')"
### accept input (used in place of 'read')
### put in a BEGIN section so will only accept 1 line and exit on ENTER
### WAITS INDEFINITELY FOR INPUT
#
[[ "$_input" ]] && { printf "%s" "$_input"; return 0; }
#
return 1
}
请注意,在命令替换_userinput="$(inputCli "Prompt string: ")"
中调用函数时,似乎需要第一个> /dev/tty
上的printf
来获取打印提示。
$(...)
的这种使用允许消除用于从键盘或标准输入收集输入的奇怪awk
命令。
答案 5 :(得分:0)
在这里晚聚会。以@andy
的{{3}}为基础,这就是我定义to_uppercase
函数的方式。
to_uppercase() {
local input="$([[ -p /dev/stdin ]] && cat - || echo "$@")"
[[ -n "$input" ]] && echo "$input" | tr '[:lower:]' '[:upper:]'
}
用法:
$ to_uppercase
$ to_uppercase abc
ABC
$ echo abc | to_uppercase
ABC
$ to_uppercase <<< echo abc
ABC
bash版本信息:
$ bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin17)
答案 6 :(得分:0)
另一个版本:
window.location.reload(true)
用法:
` <p-table ...>
<ng-template pTemplate="colgroup" let-columns>
<colgroup>
<col *ngFor="let col of columns" style="width: 40px;">
</colgroup>
</ng-template>
</p-table>`