linux 函数返回string,关于linux:bash:从bash函数返回一个字符串

本问题已经有最佳答案,请猛点这里访问。

我需要一个bash函数来将动态构造的字符串返回给调用者空间。

makeName()

{

echo"Enter Ext:"

read ext

return"$fileName.$1.$ext.log"

}

echo -n"Enter fileName:"

read fileName

name1=makeName"type1"

name2=makfName"type2"

因此,我可以获得具有相同基本文件名的两个不同文件名。

我尝试这样做

#echo $(makeName"type1")

但是,此代码没有任何原因或错误地被删除。 我希望它也可以通过该过程接受某种I / O。 那没有发生。

bash所使用的return语句用于返回一个数值,作为状态代码,以由调用函数通过$?进行检索。您不能返回字符串。也可以看看

从Bash函数返回值

如何从Bash函数返回字符串值

您可以使用@konsolebox建议的特殊全局变量,也可以使用echo函数内部的返回值,并在调用函数时使用命令替换:

makeName()

{

echo"$fileName.$1.log"

}

echo -n"Enter fileName:"

read fileName

name1=$(makeName"type1")

name2=$(makeName"type2")

echo $name1

echo $name2

[更新]

更新后的问题表明,您打算读取makeName函数内部的另一个值,而该函数还打算向用户提示echo。因此,在这种情况下,命令替换方法将不起作用-您需要使用全局变量,例如

makeName() {

echo -n"Enter Ext:"

read ext

__="$fileName.$1.$ext.log"

}

echo -n"Enter fileName:"

read fileName

makeName"type1" ; name1=${__}

makeName"type2" ; name2=${__}

echo $name1

echo $name2

$ ./sample.sh

Enter fileName:filename

Enter Ext: ext1

Enter Ext: ext2

filename.type1.ext1.log

filename.type2.ext2.log

更好的做法是,为了使代码更简洁并避免在函数内部使用全局变量,可以使用"从Bash函数返回值"中所述的方法,并将返回变量的名称作为参数传递,并且理想情况下还将fileName作为参数传递:

makeName() {

local  __type=$1

local  __fileName=$2

local  __resultvar=$3

local ext

local myresult

echo -n"Enter Ext:"

read ext

myresult="$__fileName.$__type.$ext.log"

eval $__resultvar="'$myresult'"

}

echo -n"Enter fileName:"

read fileName

makeName"type1" $fileName theResult ; name1=${theResult}

makeName"type2" $fileName theResult ; name2=${theResult}

echo $myresult

echo $name1

echo $name2

旁注:请参阅为什么在Bash中应避免使用eval,而应该使用什么呢?讨论为什么应避免使用eval。当使用bash 3.1或更高版本时,可以使用printf代替eval:

...

printf -v"$__resultvar" '%s'"$myresult"

...

最后,在bash 4.3或更高版本中,我们可以使用declare -n将nameref属性分配给变量,以便该变量实际上是对另一个变量的引用:

...

declare -n myresult=$3

myresult="$__fileName.$__type.$ext.log"

...

嗨,安德里亚斯,我已经更新了我的问题。

请参阅我更新的答案-本质上,您滥用了return,并且当您的函数打算将输出打印到stdout时(返回值除外),还需要使用@konsolebox建议的方法。

谢谢安德烈亚斯。现在工作正常。 :)

theResult仍然是全局变量;您只是采用了更复杂的路径(使用eval更危险)来设置它。

@chepner是的,但仅在全局范围内使用,而不在函数内使用。因此,函数封装得很好-适当的封装通常会更复杂;)无论如何,我认为每种方法都有其优缺点,您仍然需要明智地决定在特定情况下使用哪种方法...

通常,封装意味着不会全局访问局部变量,而不是仅全局使用局部变量。

好的,因为我的想法已经包含在这里,下面再给我一个提示:由于返回的值是一个普通值而不是数组,因此可以不使用eval,而只需使用printf:printf -v"$__resultvar" %s"$myresult"。您需要Bash 3.1。

同样,从Bash 4.3开始,我们已经可以使用最优雅的解决方案declare -n。

@konsolebox printf完美运行!

更好的方法是选择一个您始终可以使用的常规变量。例:

makeName() {

__="$fileName.$1.log"

}

echo -n"Enter fileName:"

read fileName

makeName"type1"

name1=$__

makeName"type2"

name2=$__

echo"$name1"

echo"$name2"

仅仅为了从函数中获取值而召唤子shell确实是低效而缓慢的。

子外壳+1的好处-Id仍然比全局变量更喜欢子外壳;-),但是您的方法肯定更快(将两个makeName调用循环1000次所需的时间不到100ms,而基于子外壳的解决方案则需要花费100ms差不多2秒)。

bash的神秘本质永远不会令我惊叹:-)

只需将return替换为echo:

makeName()

{

echo"Enter Ext:">&2

read ext

echo"$fileName.$1.$ext.log"

}

最后将Enter Ext:作为结果的一部分...

哎呀。应该使用echo"Enter Ext:">&2或使用bash实现的read可用的-p选项来将提示打印为标准错误,而不是显示提示(read -p"Enter Ext:" ext)。

...,而且,在调用makeName时,您仍然需要使用命令替换(OP不能正确执行,并且导致我们刚才使用@konsolebox;-进行讨论))

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值