shell脚本学习

来源:互联网 发布:淘宝暗黑3代练 编辑:程序博客网 时间:2024/06/06 14:08

说明

该文档没有将所有的linux脚本的细节涵盖,只是讲解了shell中常用的知识。
测试环境为Ubuntu 16.04。
下面FAQ的问答中,很多答案不止一种方法。

所需知识:

linux常用指令
grep, sed, awk等工具
正则表达式


变量

变量的分类

内置变量和自定义变量。

变量的定义和赋值

无须申明直接可以赋值,例如:variable=“”

注意:等号两边不能使用空格

获取变量中的值

$variable

shell可以直接在字符串中将所有带有 $ 符号的变量进行文本替换。

转义字符

要输出 $符号,bash会将 $ 后面的内容当做变量,然后取出变量的值作为文本替换。
\$ 表示 输出一个简单的美元符号。

反引号 ` `

表示在反引号里面的内容是要执行的命令,有利于构建模块。

current_date=`date`echo “Today is : $current_date

说明:$(date) 和 `date` 效果是一样的。

特殊变量

$? 上一执行的状态码$$ 本进程pid

在函数中

$0 表示函数名$1 ~ $N 表示第1 ~ N个参数$# 表示函数参数个数

注释

单行注释 #

多行注释

可以使用如下方法来进行多行注释。

:<<!...!

说明:在进行shell脚本测试的情况下,多行注释是非常有用的。


加载外部脚本

source file

file脚本中的变量都可以在主脚本中使用。

bash file

开一个子shell进程,共享主shell的变量。

说明:这里不做多的关于bash和source加载脚本方式的介绍。


条件判断

单条件

if [ condition ]; then  statements else  statementsfi

多条件

  if [ condition ]; then    statements  elif [ condition ]; then    statements  else    statments  fi

数字的判断

-eq 相等
-ne 不等
-gt 大于
-lt 小于
-le 小于等于
-ge 大于等于

例子:

    if [ $1 -gt $2 ]; then       echo$1 is greater than $2fi

字符串的判断

=   相等!=  不相等-n  长度不为0-z  长度为0<   小于,(按ASCII码表进行字符比对)>   大于,(按ASCII码表精心字符比对)

例子:

    if [ "[" < "]" ]; then      echo "[ < ]"    fi

文件的判断

-r file     用户文件可读-w file     用户文件可写-x file     用户文件可执行-f file     普通文件-d file     目录文件-c file     字符文件-b file     块文件

或与非

-a      与-o      或!       非

更加接近C语言的写法:

if [ condition ] && [ condition ]; then   ...fi

循环

for循环

for i in {...}do  ...done

还可以使用C语言风格的for循环

for((i=1;i<=$#;i++))do  ...done

字符性循环

for i in $*do   ...done

while循环

while [ condition ]do  ...done

函数

函数声明

function func() {  ...}

说明:可以省略function关键字。

函数调用

直接使用函数名。

函数返回状态码

函数返回有两个函数:return和 exit。
return 表示返回当前函数,不退出shell。
exit 表示退出当前shell。

返回状态码来表示函数是否正确执行?通常0表示成功,1表示失败。可以返回0 ~ 127之间的任意数字。返回的状态码依编程者自己决定。

函数返回字符串

使用echo指令将字符串写入到标准输入,然后在函数外直接使用变量来存储返回字符串。
例子如下:

function test(){  echo “Hello world”}var=`test`

结果:var中的值是“Hello world”

函数参数信息

$0 表示函数名,$1, $2 … $N 表示参数的值,$# 表示参数的个数。


实战演练

脚本要求:每次虚拟机下安装Ubuntu系统,首先会在Ubuntu系统中跟新源列表,然后安装vim并进行vim配置,接着安装openssh,tree等工具。现在使用脚本一键将所有工具全部安装完毕。

github地址:https://github.com/pingsoli/ubuntu


补充知识

shell显示带颜色字体

字体背景颜色范围:40 ~ 49

数字 颜色 40 黑 41 深红 42 绿 43 黄色 44 蓝色 45 紫色 46 深绿 47 白色

字颜色范围:30 ~ 39

数字 颜色 30 黑 31 红 32 绿 33 黄 34 蓝色 35 紫色 36 深绿 37 白色

ANSI控制码

控制码 作用 \33[0m 关闭所有属性 \33[01m 设置高亮度 \33[04m 下划线 \33[05m 闪烁 \33[07m 反显 \33[08m 消隐 \33[30m – \33[37m 设置前景色 \33[40m – \33[47m 设置背景色 \33[nA 光标上移n行 \33[nB 光标下移n行 \33[nC 光标右移n行 \33[nD 光标左移n行 \33[y;xH 设置光标位置 \33[2J 清屏 \33[K 清除从光标到行尾的内容 \33[s 保存光标位置 \33[u 恢复光标位置 \33[?25l 隐藏光标 \33[?25h 显示光标

例子:

echo -e "\033[41;36m something here \033[0m"

41表示底色,36表示字体颜色
注意:36后面有一个m


bash 和 sh的区别

sh (Bourne Shell): 大部分linux支持,但是控制功能不行。
csh (C Shell): 编程风格类似C语言,健壮性不如sh。
Korn Shell (ksh): 克服了C shell的一些缺点,但是应用不广泛。
bash (Bourne Again Shell): 是sh的增强版本。支持了部分C Shell脚本的语言特性,包括了Bourne Shell和Korn Shell的原始功能。目前最流行的shell。

说明:因为sh的控制功能不如bash,写脚本时,如果使用sh可以造成部分指令找不到。

详细请看参考[6]。


FAQ

Q: 变量赋值时为什么不能有空格?
A: 规定。

Q: $(variable) 和$variable 是不是同样的效果?
A: 不是相同效果。
$(variable) 已经不是取出变量中的值了,而是执行名为variable的指令。

Q: 脚本中一次性安装多个应用程序,如何默认Yes?
A: sudo apt-get -y install xxx

Q: 检测是否安装过指定程序?
A: dpkg -l | awk ‘{print $2}’ | grep -w ‘^vim$’
如果显示为 vim ,表示 vim 已经安装过,如果没有内容,表示vim没有安装。
说明:dpkg是debian下的工具,Ubuntu属于debian的分支。其他发行版的linux就不要使用上面的指令。

Q: 获取其他脚本的返回值?
A: 使用 $? 变量,该变量里面存储了上一次返回的状态码。

Q: xxx: not found ?
A: 运行指令xxx,提示找不到,如果确认有该指令,那么应该是shell的问题。
查看脚本文件开头是否是#!/bin/bash。如果是sh有可能不支持部分指令。

Q: 脚本读取配置文件?
A: 使用sed 和 awk工具。
例如,配置文件是以下格式:
done = yes

可以使用下列命令读取出done的值。
DONE = cat eaxmple.ini | grep done | awk -F'=' '{ print $2 }' | sed s/[[:space:]]//g

详细请看参考[1]。

Q: 脚本修改配置文件?
A: 使用sed工具。
配置文件.config内容如下:
cd_quick_set = no

sed -i -e ‘s/^cd_quick_set\(.*\)/cd_quick_set = yes/g’ .config

然后.config文件中的cd_quick_set就会变为yes。

Q: shell脚本中命令太长如何分行?
A: 使用 ‘\’ 分割,结尾加上 enter键。

Q: 转换大小写?
A: 使用tr命令。

echo $var | tr ‘[a-z]’ ‘[A-Z]’echo $var | tr ‘[A-Z]’ ‘[a-z]

Q: 函数返回一个字符串?
A: 通过标准输出。

function to_upper(){  echo `echo $1 | tr ‘[a-z]’ ‘[A-Z]’`}var=`to_upper “Hello world”`

Q: 函数内修改变量的值?
A: 如果是局部变量,那么将不能修改。如果是全局变量,就可以进行修改。

Q: 获取变量的字符数?
A: echo $var | wc -L
说明:wc -m 和 wc -c 都不会得到正确字符数,因为字符后面有一个结束符‘\0’。所以算出来字符数会比 wc -L 大1.

Q: 主shell会不会等待子shell执行完?
A: 主进程会等待子进行执行完毕,然后开始执行主进程,也就是阻塞。

Q: `eval $$i ?`
A: 利用eval展开表达式

for((i=1;i<=$#;i++))do  eval echo \$$idone
for i in $*do  echo $idone

Q: 变量能够存储的最大字符数为多少?
A: 通过 getconf ARG_MXG 或者 xargs --show-limits


参考

[1] shell脚本读取配置文件:
http://blog.csdn.net/u013105439/article/details/52138007
[2] eval指令:
http://blog.csdn.net/damotiansheng/article/details/39735441
[3] shell终端带颜色字体:
http://www.cnblogs.com/wish123/p/4131825.html
[4] shell进程处理:
http://blog.csdn.net/taiyang1987912/article/details/39529291
[5] for循环的几种写法:
http://blog.csdn.net/babyfish13/article/details/52981110
[6] bash 和 sh的区别:
http://www.cnblogs.com/zhangfeionline/p/5893977.html
https://stackoverflow.com/questions/5725296/difference-between-sh-and-bash


原创粉丝点击