我在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"是函数的命令行参数,而不是标准输入,这是从管道中找到文本的位置。
那么我将如何访问标准输入。 例?
我认为这可能是XY问题。 您能否更新您的问题以告诉我们您真正想要实现的目标,而不是告诉我们您如何试图实现的目标?
jliu83:如果jc_hms在管道的接收端,则stdin将出现在函数内部的第一个命令中。 但是,请发布jc_hms的实际外观,以便我们确定适合您情况的最佳解决方案。
请注意,您的功能有误。 它应该真的像jc_hms() { hr=$(($1 3600)); min=$((($1 % 3600) 60)); sec=$((1 % 60)); printf"$hs:%02d:%02d" $min $sec; }
为了回答您的实际问题,当外壳函数位于管道的接收端时,标准输入由该函数内部执行的第一个命令读取。由于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由一对空格分隔的数字组成,因此外壳程序会对songtime的值进行单词拆分,并且jc_hms看到两个单独的参数。这不需要更改jc_hms的定义,也不需要通过标准输入将任何内容通过管道传递给它。
如果您还有其他原因需要jc_hms读取标准输入,请告诉我们。
我遇到与read相关的问题,请尝试以下操作:echo -e"\ta" |if read str;then echo"$str";fi,它将忽略选项卡并仅打印" a",有什么提示吗?
在此处找到修复程序:stackoverflow.com/questions/7314044/
echo比printf更为简洁,不是吗?
echo从未被完全标准化,因为已经存在太多不同的实现(在某些情况下甚至是相互矛盾的)实现。 (例如,POSIX标准用于echo处理诸如\t和之类的序列,除非您使用非标准选项-e,否则bash的实现是不执行的。)printf是更加便携。
您不能将内容直接通过管道传递给bash函数,但是可以使用read将其拉入:
jc_hms(){
while read data; do
printf"%s""$data"
done
}
应该是你想要的
您可以举一个使用它的例子吗?我仍然必须以相同的方式使用它吗?
您可以使用此答案,也可以使用我的答案,就像您在问题中指出的那样。
它会按照您的建议工作。如果我将printf替换为echo" manipulated $ data"并运行var = $(echo" teststring" | jc_hms);从命令行回显$ var我得到"操纵的测试字符串"。编辑为$(..),因为反引号不会出现在注释中,但您的原始作业应该可以工作
这为我做到了。有一种方法可以用一根衬管一次读取所有数据吗?
它应该是printf"%s""$data",否则$data将作为格式字符串输入。
@RaphaelAhrens您的权利,谢谢更新。
1)我知道这是一个很老的帖子
2)我喜欢这里的大多数答案
但是,我找到了这篇文章是因为我需要类似的东西。尽管每个人都同意需要使用stdin,但这里缺少的答案是/ dev / stdin文件的实际用法。
使用内置读取功能时,该功能将与管道输入一起使用,因此无法再以典型方式使用。我认为利用/ dev / stdin是解决此问题的一种更好的方法,因此为了完整性我想加2美分。
我的解决方案:
jc_hms() {
declare -i i=${1:-$(
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
我希望这可以帮助某人。
骇客入侵!
非常有用-我正是有这个需要,以便能够在函数中处理args或stdin。
很好!但似乎是一种bashism(在BASH下工作,但在DASH下不行)我将其放在文件中:#!/ bin / sh jc_hms(){i =" $ {1:-$( dev / stdin)}" printf"%02d:%02d:02d n" $(($ i / 3600))$(($ i / 60%60))$(($ i%60))} jc_hms 7800 echo 7800 | jc_hms然后chmod + x test.sh ./test.sh 02:10:00 ./test.sh:6:./test.sh:算术表达式:期望主变量:" / 3600"
绝对的金,谢谢!在安装了bash 4.4的MacOS上,我无法使用declare -i,但只是执行了我的任务:i=${1:-$(
或者,您也可以通过简单的方式进行操作。
jc_hms() {
cat
}
尽管到目前为止所有答案都忽略了这不是OP想要的事实(他表示功能得到了简化)
谢谢你现在我知道我可以将其用于管道到printf中,例如xdotool search --onlyvisible --name Audacity | printf"0x%08x
" `cat`
不,您绝对不能通过管道输入printf!你错了ID建议您阅读有关Shell基础的教程。
您实际上可以使用此方法,请参考下面的答案:# echo 12345-1234 | printf Zip: %s
$(Zip: 12345-1234 # echo 1 2 3 4 | printf Number: %d
$(Number: 1 Number: 2 Number: 3 Number: 4
@TrueFalse:是的,可以,但是它使用外壳将标准输入转换为printf的参数。 printf从不从stdin读取,没有指向它的管道。 (您所做的与printf Number: %d
$(echo 1 2 3 4)相同)
@Jo So:没错,关于OP的问题也可以这么说。以我在这里使用的方式使用它是没有意义的,但这证明了该方法。您说不能通过管道传递给printf;那不是真的,所以我只是为那些非常希望通过管道传递给printf的人争论。
@TrueFalse:您不能通过管道传输到printf。您将管道输送到
我喜欢使用Bash内置条件未设置替换语法的user.friendly答案。
为了使他的答案更加通用,需要做一些细微的调整,例如对于参数计数不确定的情况:
function myfunc() {
declare MY_INPUT=${*:-$(
for PARAM in $MY_INPUT; do
# do what needs to be done on each input value
done
}
嗯...
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,您可以将UTC指定为strftime()函数的第三个参数。