我需要一个bash函数来返回一个dynamic构造的string返回到调用者空间。 即
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")
但是这个代码在没有任何原因或错误的情况下被触发了。 我希望它也接受某种types的I / O。 那没有发生。
bash使用的return语句用于返回一个数字值作为状态码,通过$?来检索$? 通过调用函数。 你不能返回一个字符串。 也可以看看
你可以使用@konsolebox提出的一个特殊的全局变量,或者在你的函数中echo显返回值,并在调用函数时使用命令替换:
makeName() { echo "$fileName.$1.log" } echo -n "Enter fileName:" read fileName name1=$(makeName "type1") name2=$(makeName "type2") echo $name1 echo $name2
[UPDATE]
更新后的问题显示您打算在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" ...
更好的方法是选择一个总是可以使用的变量。 例:
makeName() { __="$fileName.$1.log" } echo -n "Enter fileName:" read fileName makeName "type1" name1=$__ makeName "type2" name2=$__ echo "$name1" echo "$name2"
为了从函数中获得一个值,召集子壳实际上效率低下,速度慢。
只需用echo替换return :
makeName() { echo "Enter Ext: " >&2 read ext echo "$fileName.$1.$ext.log" }