将输出管道传输到 bash 函数
- 2024-10-29 08:35:00
- admin 原创
- 43
问题描述:
我在 bash 脚本中有一个简单函数,我想将 stdout 作为输入传送给它。
jc_hms(){
printf "$1"
}
我想以这种方式使用它。
var=`echo "teststring" | jc_hms`
当然,我使用了冗余函数 echo 和 printf 来简化问题,但您明白我的意思。现在我收到“未找到”错误,我猜想这意味着我的参数分隔错误(“$1”部分)。有什么建议吗?
最初jc_hms函数的使用方式如下:
echo `jc_hms "teststring"` > //dev/tts/0
但我想先将结果存储在变量中以供进一步处理,然后再将其发送到串行端口。
编辑:因此需要澄清的是,我并不是想将东西打印到串行端口,我想通过“|”管道字符与我的 bash 函数进行交互,我想知道这是否可行。
编辑:好的,这是完整的功能。
jc_hms(){
hr=$(($1 / 3600))
min=$(($1 / 60))
sec=$(($1 % 60))
printf "$hs:%02d:%02d" $min $sec
}
我正在使用该函数来形成一个字符串,该字符串来自以下代码行
songplaytime=`echo $songtime | awk '{print S1 }'`
printstring="`jc_hms $songplaytime`" #store resulting string in printstring
其中 $songtime 是一个字符串,表示为“playtime totaltime”,以空格分隔。
我希望我可以在一行中完成这个操作,然后在 awk 之后进行管道操作
printstring=`echo $songtime | awk '{print S1 }' | jc_hms`
就像这样。
解决方案 1:
回答您的实际问题,当 shell 函数位于管道的接收端时,标准输入会被函数中的所有命令继承,但只有实际从其标准输入读取的命令才会使用任何数据。对于一个接一个运行的命令,后面的命令只能看到前面的命令未使用的内容。当两个命令并行运行时,哪些命令查看哪些数据取决于操作系统如何调度命令。
由于printf
是函数中第一个也是唯一一个命令,因此标准输入实际上被忽略了。有几种方法可以解决这个问题,包括使用read
内置函数将标准输入读入可传递给的变量printf
:
jc_hms () {
read foo
hr=$(($foo / 3600))
min=$(($foo / 60))
sec=$(($foo % 60))
printf "%d:%02d:%02d" "$hr" "$min" "$sec"
}
但是,由于您对管道的需求似乎取决于您认为的使用需求awk
,因此我建议采用以下替代方案:
printstring=$( jc_hms $songtime )
由于songtime
由一对空格分隔的数字组成,因此 shell 对 的值进行分词songtime
,并jc_hms
看到两个单独的参数。这不需要更改 的定义jc_hms
,也不需要通过标准输入将任何内容导入其中。
如果您仍有其他理由jc_hms
读取标准输入,请告知我们。
解决方案 2:
您不能将内容直接通过管道传输到这样的 bash 函数,但是您可以使用它read
来将其拉入:
jc_hms() {
while read -r data; do
printf "%s" "$data"
done
}
应该是你想要的
解决方案 3:
1)我知道这是一篇很老的文章
2)我喜欢这里的大部分答案
但是,我找到了这篇文章,因为我需要一些类似的东西。虽然每个人都同意需要使用 stdin,但这里的答案缺少的是 /dev/stdin 文件的实际用途。
使用 read 内置命令会强制此函数与管道输入一起使用,因此它不再能以典型方式使用。我认为利用 /dev/stdin 是解决这个问题的更好方法,因此我想补充一些我的看法以保证完整性。
我的解决方案:
jc_hms() {
declare -i i=${1:-$(</dev/stdin)};
declare hr=$(($i/3600)) min=$(($i/60%60)) sec=$(($i%60));
printf "%02d:%02d:%02d
" $hr $min $sec;
}
实际操作:
user@hostname:pwd$ jc_hms 7800
02:10:00
user@hostname:pwd$ echo 7800 | jc_hms
02:10:00
我希望这可以帮助到别人。
快乐黑客!
解决方案 4:
或者,您也可以用一种简单的方法来做。
jc_hms() {
cat
}
尽管到目前为止所有的答案都忽略了这不是 OP 想要的事实(他表示该功能已经简化)
解决方案 5:
我喜欢 user.friendly 使用Bash
内置条件取消设置替换语法的答案。下面是一些小调整,使他的答案更加通用,例如对于参数数量不确定的情况:
function myfunc() {
declare MY_INPUT=${*:-$(</dev/stdin)}
for PARAM in $MY_INPUT; do
# do what needs to be done on each input value
done
}
解决方案 6:
嗯嗯……
songplaytime=`echo $songtime | awk '{print S1 }'`
printstring="`jc_hms $songplaytime`" #store resulting string in printstring
如果你无论如何都要调用 awk,为什么不使用它呢?
printstring=`TZ=UTC gawk -vT=$songplaytime 'BEGIN{print strftime("%T",T)}'`
我假设您使用的是 Gnu 的 Awk,它是最好的,而且是免费的;它将在常见的 Linux 发行版中工作,而这些发行版不一定使用最新的 gawk。最新版本的 gawk 将允许您将 UTC 指定为 strftime() 函数的第三个参数。
解决方案 7:
建议的解决方案要求内容stdin
或read
仅被有条件地调用。否则,该函数将等待来自控制台的内容,并要求Enter
或Ctrl
+D
才能继续。
一种解决方法是使用read
超时。例如read -t <seconds>
function test ()
{
# ...
# process any parameters
# ...
read -t 0.001 piped
if [[ "${piped:-}" ]]; then
echo $piped
fi
}
注意,-t 0
对我来说没用。
您可能必须使用不同的超时值。值太小可能会导致错误,而超时值太大会延迟脚本。
解决方案 8:
似乎没有什么效果,但有解决办法
提到了解决 xargs ref 函数的问题
$ FUNCS=$(functions hi); seq 3 | xargs -I{} zsh -c "eval $FUNCS; hi {}"
那么这也不起作用,因为你的函数可以引用另一个函数。所以我最终编写了一些接受管道输入的函数,如下所示:
somefunc() {
while read -r data; do
printf "%s" "$data"
done
}
解决方案 9:
我知道这是一篇旧帖子,但当我寻找正确的方法时,这是搜索引擎给我带来的第一个结果。
我更喜欢这种方式,因为它可以涵盖所有情况:
(a)通过函数内的 $1 等参数接受数据
(b)通过管道接受数据
(c)如果 /dev/stdin 未打开则避免挂起 - 管道中没有数据或没有给出参数
function somefunc() {
if test -n "$1"; then
dt="$1"
#Read from positional argument $1;
elif test ! -t 0; then
dt="$(</dev/stdin)"
#Read from stdin if file descriptor /dev/stdin is open
else
echo "No standard input."
fi
}
来源:https ://www.baeldung.com/linux/pipe-output-to-function
解决方案 10:
我修改了“Der Schley”的答案https://stackoverflow.com/a/36432966/21633953:
f_myfunc() {
local data=("${@:-$(</dev/stdin)}")
for parm in "${data[@]}" ; do
# do what needs to be done on each input value
done
}
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件