shell脚本中令人困惑的语句

时间:2011-04-21 18:53:47

标签: bash shell unix

while sizes=`sizes $pgid`
do
    set -- $sizes
    sample=$((${@/#/+}))
    let peak="sample > peak ? sample : peak"
    sleep 0.1
done

我对以下陈述感到困惑:

sample=$((${@/#/+}))

任何人都可以解释一下吗?

4 个答案:

答案 0 :(得分:3)

${@/#/+}”部分是正则表达式扩展:

${parameter/pattern/string}
     

扩展模式以生成与文件名扩展一样的模式。   参数被扩展,模式与其值的最长匹配是   用字符串替换。如果模式以“/”开头,则替换模式的所有匹配项   用字符串。通常只替换第一场比赛。如果模式开始   使用“#”时,它必须在参数展开值的开头匹配。   如果模式以“%”开头,则它必须在扩展值的末尾匹配   参数。如果string为null,则删除pattern的匹配项和/ following   模式可以省略。如果参数为“@”或“*”,则为替换操作   依次应用于每个位置参数,并且扩展是结果   名单。如果参数是使用“@”或“*”下标的数组变量,则   替换操作依次应用于数组的每个成员,并且   扩展是最终的清单。

因此,看起来它将参数列表“$@”中每个值的开头的空字符串替换为“+”。它的关键优点是它一举为每个参数添加前缀;否则,它类似于"+$var"


'$(( ... ))部分是算术表达式。它对括号之间的表达式执行算术运算。因此,在上下文中,它将参数列表中的值相加,假设它们都是数字。鉴于扩张,它可能会产生:

set -- 2 3 5 7 11
sample=$((${@/#/+}))
sample1=$((+2 +3 +5 +7 +11))
echo $sample = $sample1

因此'28 = 28'。

答案 1 :(得分:3)

让我们从内到外采取行。

${@/#/+}

这是一个参数扩展,它扩展了$@参数(在本例中,它将是$sizes中所有项目的数组),然后对每个项目进行模式匹配,用+替换每个匹配的序列。模式中的#匹配输入中每个项目的开头;它实际上并不消耗任何东西,因此+的替换只会在每个项目之前添加+。您可以通过简单的测试功能看到这一点:

$ function tst() { echo ${@/#/+}; }
$ tst 1 2 3
+1 +2 +3

然后将其结果替换为$(( )),它执行算术扩展,评估其中的表达式。最终结果是变量$sample设置为$sizes中所有数字的总和。

答案 2 :(得分:1)

这是字符串替换的算术扩展。

$(( ))是算术扩展 - 例如echo $((1 + 2))${var/x/y}是字符串替换;在这种情况下,请将#中的第一个+替换为$@。 {{1}}是一个变量,在这种情况下包含$ sizes;这将替换字符串,然后看起来会在其中添加值。

答案 3 :(得分:1)

$ {var / old / new}扩展$ var,将任何“old”更改为“new”。 $ {var /#old / new}坚持匹配从值的开头开始 $ {var /#/ new}替换每个变量的开头 $ {@ /#/ new}(和$ @)适用于每个参数

$((1 + 3))替换算术结果。

$(( ${@/#/+/ ))

扩展$ @,来自set - $ sizes的参数,为每个参数添加一个“+”,并通过算术评估运行结果。看起来它正在每行添加所有值。