为什么bash大括号扩展在某些算术表达式中起作用而在其

时间:2016-10-14 01:19:54

标签: bash brace-expansion

我正在研究一个非常简单的bash脚本,我遇到了一个问题,即低估了为什么弃用$ []工作正常,而$(())似乎打破了整个事情。

我所指的代码是:

for i in {1..10};
do 
    printf %4d $[{1..10}*i]
    echo
done

在这个版本中我没有任何问题,但我不想使用已弃用的bash元素,这就是我想切换到$(())的原因。

不幸的是,只要我将代码更改为:

printf %4d $(({1..10}*i))

我收到错误:

./script_bash.sh: line 8: {1..10}*i: syntax error: argument expected (error token is "{1..10}*i")

我会感谢你对这个的帮助......

4 个答案:

答案 0 :(得分:3)

为1990年设置背机。

Bash实现了每个POSIX P1003.2d9(大约1990年)的$[]语法,这是已发布的P1003.2-1992的草案。在草案和标准之间的两年中,POSIX已经确定了ksh88 $(())语法和行为。 Chet Ramey(bash maintainer)有这样说,back in 2012

  

Bash ......实施了$ [...],因为没有其他的   当时的语法,并获得一些操作经验   shell中的算术扩展。 Bash-1.14 ...列出了两种形式的算术扩展,但是   时间bash-2.0于1995年发布,手册仅提到   $((...))表格。

这向我建议$[]形式是 experimental ,并且当POSIX采用$(())语法时,它具有指定为遗忘的某些行为(如大括号扩展) 。那些实验行为留在了,因为已经存在依赖它们的野外脚本(记得已经过去了2年多)。

切特在同一个帖子中明确表示$[]表单已过时,但未弃用:

  

现在,继续拖动$ [...]语法几乎没有任何问题。   它只需要几十个字节的代码。我没有计划将其删除。

current POSIX standard, C.2.6 Word Expansions > Arithmetic Expansion提到语法(强调我的):

  

在早期提案中,使用了表单$ [表达式]。 它在功能上等同于" $(())"目前的文字,但提出反对意见,即1988年KornShell已经实施了#34; $(())"并没有令人信服的理由发明另一种语法。此外," $ []"语法与case语句中的模式有轻微的不兼容性。

所以bash中实现的行为并不符合规范,但由于没有计划将其删除,我认为没有理由放弃它的好处,如果它能整齐地解决你的问题。但是,正如@Barmar的评论所指出的那样,对这些代码进行评论并将其链接在这里是一个好主意,以便未来的开发人员知道你的意思是什么!

答案 1 :(得分:1)

$(())用于算术表达式,并且括号扩展不在算术中完成。

使用循环创建一个数组:

for i in {1..10}
do
    vals=()
    for j in {1..10}
    do
        vals+=($((i*j)))
    done
    printf "%4d" ${vals[@]}
done

答案 2 :(得分:1)

bash

由于在{}中扩展参数的顺序,

不起作用。大括号扩展($(()))比bash的算术扩展(man bash)更早完成。如果是相反的话,你的代码肯定会有效。

来自def isRoot(n, root): return not math.log(n, root)%1

  

扩展的顺序是:支撑扩展;代码扩展,参数和变量扩展,算术扩展和命令替换(以从左到右的方式完成);分词;和路径名扩展。

答案 3 :(得分:0)

遇到这样的重击。这个问题需要解释,而不是解决方案,但这是一种表达这种方式的$(())方式。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


from keras.models import Model
from keras.layers import Input, Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D


def build_model(input_shape, num_classes):
    """
    Builds the model architecture based on MNIST CNN
    https://www.tensorflow.org/tutorials/estimators/cnn

    Args:
        input_spape: Input shape of the model
        num_classes: Number of classes

    Returns:
        keras.models.Model: The created model

    """



    inputs = Input(shape=input_shape)

    x = Conv2D(32, (5,5), activation='relu')(inputs)
    x = MaxPooling2D(pool_size=(2, 2))(x)
    x = Conv2D(128, (3, 3), activation='relu')(x)
    x = MaxPooling2D(pool_size=(2, 2))(x)
    x = Dropout(0.2)(x)
    x = Flatten()(x)
    x = Dense(512, activation='relu')(x)
    x = Dense(256, activation='relu')(x)
    predictions = Dense(num_classes, activation='softmax')(x)


    return Model(inputs=inputs, outputs=predictions)

像参数扩展一样,在算术扩展中禁止括号扩展。

(打击手册)

  

为避免与参数扩展冲突,请不要使用字符串“ $ {”   被认为适合大括号扩张,并禁止大括号扩张   直到结尾的“}”。