linux管道输出到终端,关于linux:管道输出到bash函数

我在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()函数的第三个参数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值