我有一些脚本,用参数工作,他们工作得很好,但我想他们能够从标准输入读取,例如从一个管道,一个例子,假设这就是所谓的读:
#!/bin/bash
function read()
{
echo $*
}
read $*
Run Code Online (Sandbox Code Playgroud)
现在这适用read "foo" "bar",但我想用它作为:
echo "foo" | read
Run Code Online (Sandbox Code Playgroud)
我该如何做到这一点?
fed*_*qui 39
您可以使用它<<<来获取此行为.read <<< echo "text"应该成功.
测试readly(我不喜欢使用保留字):
function readly()
{
echo $*
echo "this was a test"
}
$ readly <<< echo "hello"
hello
this was a test
Run Code Online (Sandbox Code Playgroud)
使用管道,根据"Bash脚本的答案,从stdin管道读取值":
$ echo "hello bye" | { read a; echo $a; echo "this was a test"; }
hello bye
this was a test
Run Code Online (Sandbox Code Playgroud)
che*_*ner 37
编写一个可以读取标准输入的函数有点棘手,但是在没有给出标准输入时可以正常工作.如果您只是尝试从标准输入读取,它将阻塞,直到它收到任何,就像您只需cat在提示符处输入一样.
在bash 4中,你可以通过使用参数为0 -t来解决这个问题.read如果有任何输入可用,它会成功,但不会消耗任何输入; 否则,它失败了.
这是一个简单的函数,就像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
Run Code Online (Sandbox Code Playgroud)
这使得标准输入优先于命令行参数,即echo foo | catecho bar输出foo.要使参数优先于标准输入(echo foo | catecho bar输出bar),可以使用更简单的函数
catecho () {
if [ $# -eq 0 ]; then
cat
else
echo "$*"
fi
}
Run Code Online (Sandbox Code Playgroud)
(它还具有使用任何 POSIX兼容外壳的优势,而不仅仅是某些版本bash).
And*_*ndy 14
将许多其他答案组合成对我有用的东西(这个人为的例子将小写输入变为大写):
uppercase() {
local COMMAND='tr [:lower:] [:upper:]'
if [ -t 0 ]; then
if [ $# -gt 0 ]; then
echo "$*" | ${COMMAND}
fi
else
cat - | ${COMMAND}
fi
}
Run Code Online (Sandbox Code Playgroud)
一些例子(第一个没有输入,因此没有输出):
:; uppercase
:; uppercase test
TEST
:; echo test | uppercase
TEST
:; uppercase <<< test
TEST
:; uppercase < <(echo test)
TEST
Run Code Online (Sandbox Code Playgroud)
一步步:
测试/dev/stdin终端是否打开了文件描述符0()
if [ -t 0 ]; then
Run Code Online (Sandbox Code Playgroud)测试CLI调用参数
if [ $# -gt 0 ]; then
Run Code Online (Sandbox Code Playgroud)回显命令的所有CLI参数
echo "$*" | ${COMMAND}
Run Code Online (Sandbox Code Playgroud)否则如果stdin是管道(即不是终端输入),输出stdin到命令(cat -并且cat是简写cat /dev/stdin)
else
cat - | ${COMMAND}
Run Code Online (Sandbox Code Playgroud)这是sprintfbash中使用printf和标准输入的函数的示例实现:
sprintf() { local stdin; read -d '' -u 0 stdin; printf "$@" "$stdin"; }
Run Code Online (Sandbox Code Playgroud)
用法示例:
$ echo bar | sprintf "foo %s"
foo bar
Run Code Online (Sandbox Code Playgroud)
这将让您了解函数如何从标准输入读取.
这里的聚会迟到了。根据 的@andy答案,这是我定义to_uppercase函数的方式。
to_uppercase() {
local input="$([[ -p /dev/stdin ]] && cat - || echo "$@")"
[[ -n "$input" ]] && echo "$input" | tr '[:lower:]' '[:upper:]'
}
Run Code Online (Sandbox Code Playgroud)
用途:
$ to_uppercase
$ to_uppercase abc
ABC
$ echo abc | to_uppercase
ABC
$ to_uppercase <<< echo abc
ABC
Run Code Online (Sandbox Code Playgroud)
Bash 版本信息:
$ bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin17)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
84975 次 |
| 最近记录: |