V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
ivito
V2EX  ›  Linux

Linux shell 赋值语句为什么不能有空格

  •  
  •   ivito ·
    fireboyvt · 2015-12-02 17:31:45 +08:00 · 7323 次点击
    这是一个创建于 3314 天前的主题,其中的信息可能已经有所发展或是发生改变。
    比如
    a='haha' # ok
    a = 'haha' # not ok
    a= 'haha' # not ok

    再比如

    a=$(echo 'aaa\n bbb' | grep aaa ) # ok
    a= $(echo 'aaa\n bbb' | grep aaa ) # not ok
    为什么变量后边必须直接跟"=",不能有空格呢,为什么"="后边也不能有空格呢,有空格会直接当成命令执行
    30 条回复    2015-12-04 15:16:53 +08:00
    surfire91
        1
    surfire91  
       2015-12-02 17:36:28 +08:00
    语法就是这么设计的,这个解释你满意吗?
    superhxnju
        2
    superhxnju  
       2015-12-02 17:40:24 +08:00 via iPhone
    有空格,会认为是命令
    ivito
        3
    ivito  
    OP
       2015-12-02 17:41:44 +08:00
    @surfire91 我是想搞明白为什么这么设计,我们都知道 c 语言是忽略空格的, shell 这么设计从语法层面是如何造成的,不忽略空格这一事实从设计方面又是怎么考虑的
    SpicyCat
        4
    SpicyCat  
       2015-12-02 17:57:43 +08:00
    http://tldp.org/LDP/abs/html/gotchas.html#WSBAD
    如果赋值语句有空格,那就会被认为是执行命令并带两个参数。
    workwonder
        5
    workwonder  
       2015-12-02 19:53:29 +08:00 via iPhone
    我曾经也执着地写 shell 脚本,但实际上真虐心!
    bash 的表达能力太弱,建议还是选其它顺手的语言写命令行脚本。
    lululau
        6
    lululau  
       2015-12-02 20:52:15 +08:00   ❤️ 2
    比如我有两个文件,一个叫“=”,一个叫“ abc ”
    那么我要将这两个文件的内容拼接到一起,那么我用这个命令:

    cat = 123

    按照你的设想,这不就成了个赋值语句了吗

    第二个问题,是因为 var=value command 这个形式在 bash/zsh 里表示执行 command 程序,并为执行此程序的进程添加一个环境变量 var ,其值为 value

    如果你把赋值语句写成: var= 123 ,那么它的意思就是执行 123 这个程序,并为此进程设置一个环境变量 var ,其值为空字符串
    lululau
        7
    lululau  
       2015-12-02 20:56:16 +08:00
    因为 bash 的功能设施比较简单,所以我建议,如果是已经掌握了基本的命令的使用的话,直接看 manual 就行了,总共不到 4 万字,看完基本就是 bash 熟手了
    sinxccc
        8
    sinxccc  
       2015-12-02 21:34:49 +08:00 via iPhone
    因为 shell 既作为脚本的解释器,又用做交互的用途。
    xufang
        9
    xufang  
       2015-12-02 21:37:51 +08:00
    最近一年都在写 shell , 要吐血哦。
    bramblex
        10
    bramblex  
       2015-12-02 21:38:53 +08:00
    举个栗子:
    「我们中出了叛徒」你要理解成 「我们中 /出了叛徒」还是理解成「我们 /中出了 /叛徒」?
    workwonder
        11
    workwonder  
       2015-12-02 21:57:04 +08:00 via iPhone
    @xufang 我是主动放弃了 shell 技能,能用 shell 写的也用 python 写,这样脚本复杂之后还能轻松维护。
    xufang
        12
    xufang  
       2015-12-02 21:58:40 +08:00 via Android
    @workwonder 嗯, bash 的表达能力和复用度太低,写得我不要不要的。
    xufang
        13
    xufang  
       2015-12-02 21:59:50 +08:00 via Android
    哦,我之前还写过半年的批处理,哇,那可真是地狱难度。
    yangff
        14
    yangff  
       2015-12-02 22:03:45 +08:00
    @xufang windows 下对应 shell 的理论应该是 vbs/powershell ……
    lightening
        15
    lightening  
       2015-12-02 22:05:31 +08:00
    @ivito 但是 C 语言调用函数是必须要有括号的。 bash 每个命令都加个括号,用起来烦不烦啊?
    Orzzzz
        16
    Orzzzz  
       2015-12-02 22:11:23 +08:00
    @workwonder 没感觉弱啊,要不举个例子说说?
    xufang
        17
    xufang  
       2015-12-02 22:11:39 +08:00 via Android
    ivito
        18
    ivito  
    OP
       2015-12-02 22:44:04 +08:00
    @SpicyCat
    @lululau
    两位的解释很充分,感谢
    workwonder
        19
    workwonder  
       2015-12-02 22:45:52 +08:00 via iPhone
    @Orzzzz 这个不用例子了吧,像 python 这类脚本语言在运维领域也很火的,自然有道理的。
    bash 由于本身很简单,好上手,极简单的任务用它来写来的很快,但是任务复杂后慢慢就驾驭不了了,一些其它编程语言基础的特性你还得组合各种工具利用各种技巧实现。
    实践上我们写的最多的 shell 脚本是用来完成构建和发布任务的,后来用基于 python 的 fabric 来做这些事情,轻松许多,功能也强大许多。请自行了解 fabric 。
    另外 npm 有一个 shell.js 的模块,实现了许多常用命令行工具的功能,让你可以以 JavaScript 的方式调用它们,不妨去了解下。
    ivito
        20
    ivito  
    OP
       2015-12-02 22:46:55 +08:00
    @xufang
    @workwonder
    个人觉得 bash 还是很方便的,比如处理文本,直接一两个命令,而 Python 则需要好几倍的代码。
    bash 配合 awk 、 sed 等神奇用起来表达能力很强的,补足了 bash 数据结构太少的缺点,况且还有很多不常用的命令作为补充。
    Orzzzz
        21
    Orzzzz  
       2015-12-02 23:28:15 +08:00
    @workwonder Bash Python 两手抓~
    Orzzzz
        22
    Orzzzz  
       2015-12-02 23:29:06 +08:00
    @ivito 除了处理日常事务,还有最经典的 fork 炸弹 :P
    dcoder
        23
    dcoder  
       2015-12-03 00:33:48 +08:00
    @ivito 简单说就是, bash 是一门烂语言
    总是有很多烂工具,因为各种历史原因,一直没废除了,不停虐新的程序员, 比如超复杂的 MakeFile...
    weyou
        24
    weyou  
       2015-12-03 02:27:13 +08:00
    @lululau 反例举的很好,赞一个。
    iptux
        25
    iptux  
       2015-12-03 02:45:59 +08:00 via Android
    bash 本身并不怎么强,它强在可以迅速调用其他命令并把这些命令串起来
    zent00
        26
    zent00  
       2015-12-03 08:31:00 +08:00
    @dcoder Bash 原本并不是以一门语言而被写出来的,而是一个 Unix Shell 。虽然现在能见到的大多数 Shell 都有一些可编程特性,但肯定不能把它和那些“高级编程语言”做对比。如果说 Python 和 Perl 这些脚本语言比 Bash 强多了,那么,请试试把它们作为操作系统的 Shell 来使用看看。
    Arthur2e5
        27
    Arthur2e5  
       2015-12-03 11:44:14 +08:00
    因为 shell 语法的 word 单元这么做就是简单容易。况且这么做完全就是福利懒人,我还可以一行写好多个:

    > t=$b b=$a a=$t g=$(echo 233)

    并且人类的确就是有“对某个命令带着某一堆限定作用域的特殊环境运行( simple_command ::= ASSIGNMENT_WORD* cmd_word cmd_args*)” 的 shorthand 的需求。你可以找个一下子能定义多个的、显而易见的、和变量定义形式一致的这种语法试试……

    你是喜欢
    > ( # create separated environment
    > set -o allexport
    > CC = gcc
    > CXX = g++
    > ./configure
    > )

    还是
    > CC=gcc CXX=g++ ./configure

    你再考虑一下你这样的语法要加多少限制和惊喜,例如符合变量名要求开头的命令的参数里面里面不能有未 escape 的 = 之类的。

    P.S. 关于敲键盘,记得有人吐槽说 dd 这种“出自按键重得按了可能骨折的时代”,倒是没考证过。
    ivito
        28
    ivito  
    OP
       2015-12-04 13:24:08 +08:00
    @Arthur2e5
    这种写法确实带来很多便利
    ( simple_command ::= ASSIGNMENT_WORD* cmd_word cmd_args*)
    这个是正则吧,两个":"是什么意思。
    meloncrashed
        29
    meloncrashed  
       2015-12-04 15:11:53 +08:00
    @bramblex 这个例子好棒
    meloncrashed
        30
    meloncrashed  
       2015-12-04 15:16:53 +08:00
    bash 现用现看吧, bash 是个命令胶水,串联命令用用 bash 。

    反正我学 python, bash 忘得差不多了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2805 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 13:10 · PVG 21:10 · LAX 05:10 · JFK 08:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.