• 形似赋值语句的参数


    我们知道,在 Bash 中,当变量出现在一个赋值语句的右侧时,变量只会展开,不会分词,即便变量两边没有引号: 

    $ foo="1                       2"

    $ bar=$foo # 不会被拆分成 bar=1 和 2 两个词

    $ echo "$bar"

    1                       2

    但是,当一个形似赋值语句的词,作为参数传给一个命令时,这时分词步骤就不会少了:

    $ foo="1                       2"

    $ printf '%s ' bar=$foo

    bar=1

    2

    bar=$foo 虽然看起来像是赋值语句,但因为它出现在了命令名称的后面,所以它就是个普通的参数。它会先展开成 bar=1                       2,然后被拆分成 bar=1 和 2 两个参数传给 printf。外部命令也一样:

    $ valueOfa="1 b=2"

    $ env -i a=$valueOfa env # 你以为传给 env 的第二个参数是 "a=1 b=2",但其实是 "a=1" 和 "b=2" 两个参数

    a=1

    b=2

    可是,有一些命令却是特殊的,比如 alias:

    $ valueOfa="1 b=2"

    $ alias a=$valueOfa # 传给 alias 命令的会是 "a=1" 和 "b=2" 两个参数?

    $ alias

    alias a='1 b=2'  # 并不是,valueOfa 这个变量居然没有被分词!

    像 alias 这样的内部命令一共有 6 个,分别是:alias、declare、typeset、export、readonly、local,它们的功能都是声明一个什么东西,变量或者别名。Bash 对它们的参数做了特殊对待,如果满足赋值语句的格式,则不对其中的变量进行分词。当然你也可以就把它们看成是赋值语句,反正赋值语句的效果是创建一个变量,这些参数的效果也是创建一个变量(除了 alias 命令)。Bash 手册也直接把它们说成是赋值语句:

    Assignment statements may also appear as arguments to the aliasdeclaretypeset,exportreadonly, and local builtin commands. 

    在 Bash 的实现里,是专门用一个函数对这样的参数做了特殊处理:

    /* This is a hack to suppress word splitting for assignment statements
       given as arguments to builtins with the ASSIGNMENT_BUILTIN flag set. */
    static void
    fix_assignment_words (words)
         WORD_LIST *words;
    {
    ...

    等等,还没完。上面说,如果满足赋值语句的格式,这些参数才会被特殊对待,那如果不满足呢?

    我们知道,赋值语句的左边必须是合法的标识符,合法的标识符得符合“字母下划线开头后跟若干个字母数字下划线”。这样的话 1=$foo 就必定不是个合法的赋值语句了,下面试一把:

    $ foo="1 2=2"

    $ alias 1=$foo

    $ alias

    alias 1='1'

    alias 2='2'

    果然,被当成普通的参数了。

  • 相关阅读:
    龙东平:持续提升个人认知的三大底层逻辑
    【科创人独家】美信拓扑创始人一乐:如何登山不是最重要的问题,山峰才是
    【科创人独家】搜狐快站金庸:有情有义,90后技术创业者的问剑之路
    【科创人独家】军哥手记程军:我的2020,先打个60分吧
    【科创人独家】云风:从创业到招安,自由的游戏玩家+务实的程序员
    C语言--->指针
    位运算(一)
    平方根倒数快速算法
    IntelliJ IDEA 配置《算法》(第四版)
    深度学习(一):Python神经网络——手写数字识别
  • 原文地址:https://www.cnblogs.com/ziyunfei/p/4836597.html
Copyright © 2020-2023  润新知