Shell自定义函数如何接收管道传递的标准输入?
问题解析与解决方法
为什么管道直接调用sqr会报错
你定义的sqr()函数依赖位置参数$1接收输入,但管道(|)传递的是标准输入(stdin),而非位置参数。执行echo 4 | sqr时,sqr的$1是空值,计算$((空值 * 空值))会触发语法错误。
为什么用xargs会报“No such file or directory”
xargs会启动子shell进程执行指定命令,但你在当前shell定义的sqr是内部函数,默认不会被子shell继承。子shell会把sqr当成外部系统命令查找,自然找不到,因此报错。
解决方法
方法1:修改函数读取标准输入
把函数改成从标准输入读取内容,不再依赖位置参数:
sqr() { read num; echo $(( num * num )); }
此时执行echo 4 | sqr就能正常输出16。
方法2:导出函数后用xargs传递参数
如果想保留位置参数的调用方式,先将函数导出到子shell环境:
# 导出函数,让子shell可见 export -f sqr # 用xargs将标准输入转为位置参数传递 echo 4 | xargs sqr
xargs会把echo 4的输出作为位置参数传给sqr,此时$1为4,计算正常。
方法3:用命令替换传递参数
无需管道,直接把echo的输出作为位置参数传入:
sqr $(echo 4)
这种方式也能得到正确结果16。
内容的提问来源于stack exchange,提问作者Mark Giddens
相关产品推荐
相关产品推荐

