Bash基础知识

在上一篇文章《不过时的技术-Bash脚本》中,我们简单介绍了Bash脚本,并且学会如何编写、运行一个Bash脚本。这篇文章我们将目光转向Bash脚本的一些基础知识:

  1. 如何定义、使用变量
  2. export和source
  3. 特殊字符及转义
  4. 脚本参数
  5. 命令替换
  6. 字符串验证
  7. Here文档

变量

有三种方式定义变量:

  1. 在命令行或脚本中直接显式定义
    COLOR=red
    千万不要像其他编程语言一样在变量和=之间加空格!!!
  2. 使用read命令从标准输入给变量赋值
    read COLOR
  3. 第三种变量比较特殊,由参数直接传入:$0$1$2……其中$0为脚本名,$1是第一个参数,以此类推。

在变量名前加$符引用变量,比如$COLOR。下面这段脚本让用户输入进程名,保存到一个变量里,然后查找相关进程并杀掉。

#!/bin/sh

# Ask what to stop using the kill command and then kill it
echo which process do you want to kill?
read TOKILL

kill $(ps aux | grep $TOKILL | grep -v grep | awk '{print $2}')

这个脚本的最后一句看起来有点复杂,用到了命令替换、管道、awk等知识。如果你是那种不怕麻烦的人,可在命令行中一点一点去执行,看看发生了什么:比如ps aux返回当前进程,ps aux | grep http在当前进程中找出http相关进程,以此类推……事实上这是编写脚本时常用的方法,先在命令行中一部分一部分实验,成功后再组织成一段脚本。

如果执行脚本时出错怎么办?比如上面这段脚本运行第二次时,如果输入的值一样,就会报错。此时运行bash -x tokill.sh可以打印出详细的诊断信息:

foo:bin muxi$ bash -x tokill.sh 
+ echo which process do you want to 'kill?'
which process do you want to kill?
+ read TOKILL
http
++ ps aux
++ grep -v grep
++ grep http
++ awk '{print $2}'
+ kill
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]

相信你已经看出了问题所在,最后一步kill进程时传入的参数不对(为空)。这点不难想象,因为我们已经在上一次运行时杀掉所有相关进程了。

需要注意的是变量只在定义它的脚本中起效,如果在当前脚本中进入子脚本,那么该变量在子脚本中就不存在了。这点可以在命令行中得到验证:

foo:bin muxi$ COLOR=red
foo:bin muxi$ echo $COLOR
red
foo:bin muxi$ bash
bash-3.2$ echo $COLOR

bash-3.2$ COLOR=green
bash-3.2$ echo $COLOR
green
bash-3.2$ exit
exit
foo:bin muxi$ echo $COLOR
red

细心的读者可能会注意到,定义变量时我一直用的大写,这是一个好的编程习惯,人家一看就知道这是个变量。

export 和 source

如果想使用父脚本中定义的变量该怎么办?答案是使用export将变量导入子脚本:

foo:bin muxi$ export COLOR=red
foo:bin muxi$ echo $COLOR
red
foo:bin muxi$ bash
bash-3.2$ echo $COLOR
red

source更厉害,它能将一个脚本中的所有内容导入到另外一个脚本中。

#!/bin/sh

. ./slave.sh

echo the value of variable '$COLOR' is $COLOR

exit 0
#!/bin/sh

COLOR=yellow

source的厉害之处在于它能将变的东西和不变的东西分离开,听着是不是很熟悉?这是计算机世界里一个基本的原则之一。以后大家会经常在脚本中看到exportsource

特殊字符和转义

在Shell脚本中,很多字符有特殊的含义:~代表当前用户主目录, #注释等,更多内容可参考特殊字符列表。比如下面这段脚本,你觉得输出会是什么?

echo 2 * 3 > 5

上面的脚本什么也没输出,它将一段文本重定向到文件5中。为了输出2 * 3 > 5,需要这样:echo '2 * 3 > 5'

脚本参数

执行脚本时可传入参数,在脚本中使用$0, $1, $2……${10}, ${11}……引用参数,其中$0代表脚本名。还有三个特殊变量:$#表示传入参数个数,$@返回所有参数列表,$*将所有参数以一个字符串的形式返回。下面这段程序用来遍历参数列表,你能猜出为什么"$@"要加双引号吗?

for i in "$@"
do
    echo $i
done

命令替换

编写脚本时,经常一个命令需要使用另一个命令执行完成后的结果,此时就用到了命令替换,比如ls -l $(which passwd)列出了passwd命令的文件属性。

字符串验证

test -z $1 && exit 1 #如果第一个参数为空,返回状态1退出
[[ $1=='[a-z]*' ]] || echo $1 does not start with a letter
恐怖的空格!!!$1之前必须有空格,之后必须没空格!!!

Here文档

wall <<End-of-message
----------------------------
This is line 1 of the message.
This is line 2 of the message.
This is the last line of the message.
------------------------------
End-of-message
#!/bin/bash
# example of a scripted FTP session

lftp localhost <<EndOfSession
ls
get hosts
bye
EndOfSession

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

推荐阅读更多精彩内容