Shell 引号嵌套

 在写shlle脚本或者自定义alias时有一个坑总是无法避开,那就是引号,不管如何尝试系统总是无情的提示“ unmatched ' ”,多方寻找终得正解,遂做此记录。

先抛结论:

1、在使用多重引号时系统是从前往后看的,能匹配就算一对,所以这样一对一对的断句将整个命令串分为若干部分;

2、为了使系统识别后(被识别的引号会消失)的命令串功能正确,需要使用转义字符手动的在合适的地方加入合适的引号;

下面举例来谈。首先明了为何要用引号,不外乎如下几种:

将不连续的一串(比如包含空格)作为一个整体,需用单引号或双引号括起来,区别在于双引号仍能解析其中的变量等;

倒引号用于命令替换,不过倒引号一般不嵌套,在此主要讨论单双引号的嵌套。

比如下面这个命令:

gnome-terminal --tab -t "$start-$end"

-e 'bash -c 'sleep 1m;echo "$start $end" ' '

第一行"$start-$end"是因为其中有变量一般需要用双引号保护一下,但其实这里不加也可以的,第二行“$start $end”也是,而且这里还有一个空格,想要表示他们作为一个整体输出就用了双引号括起来,但其实好像不用echo也能识别的;

第二行-e后面有一对''将一串复杂的命令括了起来同样也是表示他们作为一个整体作为-e的参数,这里把''换成""问题也不大,只不过大家习惯用单引号来括起复杂的命令;

第二行-c后面同样用了一对''原理同上,表示那两条命整体作为-c的参数。

  但其实这样的写法系统是不认的,它是这样断句的(第行没问题,接下来我们只关心-e后面的写法):

即开头提到的从前往后数,能凑一对就先凑一对,这样以看到中间sleep 1m;echo是不连续的(sleep后面有格)。正确的写法有下面四种:

  头大不 : )

前2条还是那个思路,从前往后挨个配对,断句都用下线表示了,其中穿插的 \" 和 \'是出于功能的考虑,即我想在那个地方人为的加引号,具体看下面编译之后的就明白了;

3和4两条就是简单的单双引号嵌套,并且是单双交替的,这样就比较简单,可以由内而外的看,如3,第一是'$start $end',第二层是"sleep 1m;echo'$start $end' ",第三层是'bash -c "sleep 1mecho '$start $end' " '。注意,这样来看与上述从往后挨个匹配并不冲突,只是这样更清楚。

第五条是不用单引号,只用转义符使大家连成一个整体这样写语法上是没问题的,但是功能是不对的,因sleep\ 1m由于转义符导致1m不能与sleep连成一个小体,及1m不能被sleep识别,而是被算作一个与sleep等级的了。可见只用转义符这种方法只适用于单层命(见下面参考链接1),不太适用于嵌套的,嵌套还是用引号。

再来看这些命令经过系统识别以后长啥样,注意,被识为配对的引号都会消失,但一次识别只会消失最外面层:

  可见只消掉最外面一层的话12和34的方式看起来是不一的,以为12是用相同的引号做的嵌套,而34是拿不同的号做的嵌套,所以看起来更直观。

  再做一层解析如下,注意这层解析只是我认为的把它还成我们正常写命令的样子,上面经过一层解析之后的命串系统已经可以执行起来了。下面这些只是他们看起来直观的样子,也是我们最初想写的命令:

可以看出2和3.1等价,而3.2由于bash -c内部这层使的是相同的引号做的嵌套(由外而内3,2,1三层,它第层和第2层用的不同引号,第2层和第1层用的相同引号,所以与他们略有不同。

本来1和4.1也应该是等价的,但大家看一下1和2在echo\"$start这里,我都用的\",这里用\"或\'语法上都以,因为系统不会解析转义符,但2的选择是对的,它的是与外面一层不一样的;而1与外面一样,这在功能不对。

这就是开头我们提到的:为了使系统识别后(被识别的引号会消失)的命令串功能正确,需要使用转义字符手动的在合适的地方加入合适的引号。

  现在我们将1更正回来,以保证它被解析之后的功能正确性:

好了,看到这里你已经掌握引号嵌套的精髓了,但实际用场景往往都很复杂,比如其实上面这句命令我是想把赋值给一个变量的,众所周知赋给变量的必须得是一个体(字符串),So,又要有一层嵌套了 : )

我已经码了一个多小时了(这效率,唉···),所以这只放结果了,聪明的你一定看的懂吧:)(我用的CShell,不同shell赋值略有不同,但本质一的;并且上面34也可以看出用同样的引号做嵌套很麻烦,所这里就没有头铁,而是选择与倒数第二层不同的引号来的)

  可以看出,我是无脑按与第三层不同的引号套的第四层但这样34是错的,如上3所示,中间部分不连续,正确法如下:

其实这里 \" 和 \'的选择也是考虑到而功能正确性的,就再赘述了。

最后,最后再送一个alias(同样是csh,别的sh略有别),其实主要是alias和awk都要单引号导致的冲突,握了这套武林绝学,统统都是小意思

:)

  万恶的引号。

参考链接1

参考链接2

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,302评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,232评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,337评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,977评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,920评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,194评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,638评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,319评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,455评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,379评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,426评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,106评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,696评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,786评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,996评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,467评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,043评论 2 341