从PATH说起的shell命令行替换

许久之前,师弟问了我一个问题,为什么shell中添加环境变量的写法是下面这种方式

PATH=~/.lib:$PATH; export PATH

而下面这种会报错呢?

$PATH=~/.lib:$PATH; export PATH

当时我的回答是,"shell就是这样子规定的呀"。 回答的同时,也突然间发现有些自己感觉很熟悉的概念,原来自己并没有那么清楚,因此这一篇讲讲shell的命令行替换。先说结论

shell会在命令执行前对命令行进行一些替换

shell替换有如下几种:

替换 语法 含义
历史 ! 之前使用命令
大括号 {} 指定的文本
代字号 ~username 用户的主目录
变量 $, ${...} shell和环境变量
算术 $((..)) 整数运算
命令替换 `...`, $(...) 运行在子shell里命令的输出
路径名 *,?,[...],[^...] 文件系统中匹配的文件名

历史替换是以!开头的替换方式,以下面历史记录为例

历史记录
$ !! # 执行上一个命令,即history
$ !1021 # 支持第1021个命令 即ls
$ !-2 # 执行倒数第二个命令,即ls

大括号替换: 它会将{...}里的内容展开为多个单词,可以快速创建有一定规律的文件. 下面这个命令就把"chap0{1..3}"替换成了chap01, chap02, chap03, 以及每个都还有一个html和text对应。

$ mkdir -p chap0{1..3}/{html,text}
$ tree chap0*
chap01
├── html
└── text
chap02
├── html
└── text
chap03
├── html
└── text

代字号代替: 我们经常会看到别人文章会写用vim ~/.bashrc修改家目录下的配置文件,其中~默认就会替代成自己家目录路径,可以用echo ~确认。

那么问题来了,如何我想快速到别人的家目录下,应该怎么操作。只要在~加上别人的用户名就行了。比如说我/home 下还有一个用户叫做abc, 那么查看它家目录下的内容就是

ls ~abc

注: ~a可以用tab补全成~abc

变量替换: shell会把${变量名}或者$变量名替换成变量所指代的具体字符,比如说我将abc指代为ls,那么shell就会将$abc解释成ls,然后执行ls

abc=ls
$abs
# Desktop  bin  biosoft  blastdb  miniconda3  ncbi

也就是$PATH=~/.lib:$PATH; export PATH报错的原因是,shell在执行命令前会把$PATH成原来PATH里的字符串,显然无法达到修改PATH的目的

算术替换: shell命令行支持整数型的数学运算,下面的运算都是可以的,但是就别拿100/2.5这种浮点运算为难shell了。

echo $((1+2))
echo $((1-2))
echo $((100*101))
echo $((100/50))

命令替换:这个替换非常的实用,可以将shell命令的输入结果立刻作为输入,而不是额外创建一个变量命。有一个应用场景就是在的分析报告里加上完成时间点

touch reports.$(date +%d%b%Y).log

路径名替换:路径替换的语法就4种,*表示0或更多的任意字符,?表示一个任意字符,[...]表示括号内的字符之一,[^...]不包括括号内的字符

以上就是shell命令行替换的几种形式。当然为了再一次强调"shell会在命令执行前对命令行进行一些替换",下面举一个反面例子来说明下。

Linux的/etc目录下有很多以conf结尾的配置文件,我们可以用find命令快速的定位到它们。

find /etc -name *.conf

上面的命令看起来没啥毛病,但是只要多做一件事情,就会有报错哦

touch a.conf b.conf
find /etc -name *.conf
# 如下是报错
find: paths must precede expression: b.conf
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec|time] [path...] [expression]

你会不会好奇,明明是相同的命令,却又不同的境遇呢?让我解释下,在刚开始的时候,文件下面没有"a.conf","b.conf",尽管shell看到"*"会有一种进行通配的冲动,但是很可惜没有对象让它统配。后来我们创建了这两个文件,给shell找到通配的机会,于是实际执行的命令就成了 "find /etc -name a.conf b.conf"。 由于后面这两个是文件路径,不符合find的命令要求,就导致了报错。

其实报错还好,有些时候没有报错,程序运行得到错误的结果反而更惨

如何避免这种错误呢?我们就需要用到"避免\*这个元字符被shell解释。

除了双引号,避免shell进行替换的符号还有 反斜杠\ , 和单引号 '. 单引号和双引号的区别在于,单引号内部所有字符都是普通字符而已,而双引号里的美元符号$, 感叹号! 和反引号 ` 还能被shell解释

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

推荐阅读更多精彩内容