Bash shell脚本中的混淆语句

Bash shell脚本中的混淆语句,bash,shell,unix,Bash,Shell,Unix,我对以下说法感到困惑: while sizes=`sizes $pgid` do set -- $sizes sample=$((${@/#/+})) let peak="sample > peak ? sample : peak" sleep 0.1 done 有人能解释一下吗?这是字符串替换的算术扩展 $(())是算术扩展-例如echo$((1+2))。 ${var/x/y}是字符串替换;在这种情况下,将一行中的第一个#替换为+$@是一个变量,在本例中

我对以下说法感到困惑:

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

有人能解释一下吗?

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

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

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

模式被展开以生成模式,就像在文件名展开中一样。 参数展开,模式与其值的最长匹配为 替换为字符串。如果模式以“
/
”开头,则替换模式的所有匹配项 用绳子。通常只替换第一个匹配项。如果模式开始 使用“
#
”,它必须在参数展开值的开头匹配。 如果模式以“
%
”开头,则它必须在扩展值的末尾匹配 参数如果字符串为空,则删除模式的匹配项,并 图案可以省略。如果参数为“
@
”或“
*
”,则替换操作 依次应用于每个位置参数,展开即为结果 列表如果参数是以“
@
”或“
*
”下标的数组变量,则 替换操作依次应用于数组的每个成员,并且 展开是结果列表

因此,它似乎将参数列表“
$@
”中每个值开头的空字符串替换为“
+
”。它的主要优点是,它一下子为每个论点添加了前缀;否则,它类似于
“+$var”


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

${parameter/pattern/string}

因此,“
28=28
”。

让我们从内到外来理解这条线

set -- 2 3 5 7 11
sample=$((${@/#/+}))
sample1=$((+2 +3 +5 +7 +11))
echo $sample = $sample1
这是一个参数展开,它展开
$@
参数(在本例中,它是
$size
中所有项目的数组),然后对每个项目进行模式匹配,将每个匹配的序列替换为
+
。模式中的
#
匹配输入中每个项目的开头;它实际上并不消耗任何东西,因此用
+
替换只需在每个项目之前添加一个
+
。您可以通过一个简单的测试函数看到这一点:

${@/#/+}

然后将其结果替换为
$(())
,执行算术展开,计算其中的表达式。最终结果是变量
$sample
被设置为
$size

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

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

$ function tst() { echo ${@/#/+}; }
$ tst 1 2 3
+1 +2 +3
$(( ${@/#/+/ ))
展开集合--$sizes中的参数$@,在每个参数前面加一个“+”,并通过算术运算运行结果。看起来它在每行上都添加了所有值。

不,它不会用模式a
${var/pat/string}中的
+
替换第一个
替换将匹配
var
中每个项目的开头,因此它将在
$@
中的元素开头添加一个
+
$ function tst() { echo ${@/#/+}; }
$ tst 1 2 3
+1 +2 +3
$(( ${@/#/+/ ))