• Shell 就是一个程序,能解释用户输入的命令和脚本
• 阅读现成的 Shell脚本:哪里去找?
• Linux rc 脚本: 启动各种服务的脚本
位于 /etc/init.d/rc开始启动
• configure 脚本: 配置编译环境的脚本
• 通过 autotools 自动生成的
• 大部分 tar.gz 源码包解开后都有
• 手册:
• info bash
• rc: 第一个 Shell 脚本,rc 的作用: 启动 OS
• 查看当前环境所用shell:echo $SHELL
•
Shell类型
UNIX和LINUX上常见的shell一般有5种,它们是Bourne shell, C shell, Korn shell, Bash shell和TC shell,现在我们的机器上这几种shell都有。这几个shell分为两大分支,一个是Bourne shell和其延伸版本,一个是C shell和其延伸版本。
1 怎样编写SHELL
利用vi编辑器编辑脚本,将脚本命名为脚本功能.sh
Shell脚本不是复杂的程序,它是按行解释的,脚本第一行总是以 #!/bin/sh 开头,它通知系统以下的Shell程序使用系统上的Bourne Shell来解释。
第二行注释中写入脚本名,第三行注释开始写入脚本功能——习惯。
以下行进入脚本正式编写
编写完后给脚本添加执行权限:
chmod u+x ScripName
运行脚本:ScripName 或 ./ScripName
简单脚本示例:
vi ShowHello.sh
bash路径查询:
E0247F00-2436-0000-1000-1DD300002500:/home/fsp/cxy # export | grep bash
declare -x ENV="/etc/bash.bashrc"
declare -x SHELL="/bin/bash"
以下为脚本内容:
#!/bin/sh
#ShowHello.sh
#To show hello to somebody
echo -n“Enter Your Name:”
read NAME
echo “Hello,$NAME!”
保存,退出vi编辑器。
为脚本添加可执行权限:
chmod u+x ShowHello.sh
运行脚本:ShowHello.sh : sh ShowHello.sh
/dev/null
是一个虚设的设备,俗称“Linux黑洞”,任何对/dev/null的写入都会成功,但数据会消失得无影无踪,没有任何反馈。所以经常把不想在屏幕显示的信息全部送到/dev/null中,在shell脚本中用得比较多。
如:ls –l > /dev/null
还可以用来清空文件的内容:cat /dev/null > FileName
2 命令
本地变量基本命令:
echo 可以显示单个变量取值,并在变量名前加 $
unset 命令清除变量
set 命令显示所有本地定义的s h e l l变量
set val = 32
echo $val
unset val
环境变量与本地变量设置方式相同,可以使用env命令可以查看所有的环境变量
echo 可以显示单个变量取值,并在变量名前加 $
export 设置环境变量
unset 命令清除变量
export LM_LICENSE_FILE = 300@SHHW84
l 命令read从键盘读取变量var的值:
read var
echo $var
文件重定向
Ö 作用:改变输出方向或输入来源
Ö 使用说明:
ó cmd > file
将标准输出重定向到新文件file中
ó cmd >> file
将标准输出重定向追加到文件file中
ó cmd > file 2>&1
将标准输出和标准错误重定向到文件file
ó cmd 2 > file
将标准错误重定向到新文件file中
ó cmd >> file 2>&1
将标准输出和标准错误重定向追加到文件file
ó cmd < file1 > file2
cmd以file1为输入,file2为输出
ó cmd < file
cmd以file为标准输入
ó cmd << delimiter
从标准输入里面读入,直到遇到delemiter分界符
字符串比较操作符 | =、== | 两个字符串相同 |
!= | 两个字符串不等 | |
-z | 空串 | |
-n | 非空串 | |
数字逻辑操作符 | -eq | 数值相等 |
-ne | 数值A 不等于数值B | |
-gt | 数值A 大于数值B | |
-lt | 数值A 小于数值B | |
-le | 数值A小于等于数值B | |
-ge | 数值A大于等于数值B | |
文件状态逻辑操作符 | -d | 该文件是目录 |
-f | 该文件为正规文件 | |
-L | 该文件为符号链接 | |
-r | 该文件可读 | |
-s | 文件长度大于0 | |
-w | 该文件可写 | |
-x | 该文件可执行 |
Shell文件操作
写文件
>, >>, tee, tee –a
读文件
read, <
cat 显示文本内容,可实现文本插入
touch 实现文件时间戳操作
IF语句
if expr1 # 如果expr1 为真(返回值为0)
then # 那么
commands1 # 执行语句块 commands1
elifexpr2 # 若expr1 不真,而expr2 为真
then # 那么
commands2 # 执行语句块 commands2
... ... # 可以有多个 elif语句
else # else 最多只能有一个
commands4 # 执行语句块 commands4
fi #if 语句必须以单词 fi终止
CASE
case exprin # expr为表达式,关键词in不要忘!
pattern1) # 若expr与pattern1匹配,注意括号
commands1 # 执行语句块commands1
;; # 跳出case结构
pattern2) # 若expr与pattern2匹配
commands2 # 执行语句块commands2
;; # 跳出case结构
... ... # 可以有任意多个模式匹配
*) # 若expr与上面的模式都不匹配
commands # 执行语句块commands
;; # 跳出case结构
esac # case语句必须以esac终止
FOR
for variableinlist
# 每一次循环,依次把列表list中的一个值赋给循环变量
do # 循环开始的标志
commands # 循环变量每取一次值,循环体就执行一遍
done # 循环结束的标志
执行第一轮循环时,将 list中的第一个词赋给循环变量,并把该词从 list中删除,然后进入循环体,
执行 do和 done之间的命令。下一次进入循环体时,则将第二个词赋给循环变量,并把该词从 list 中删除。
以后的循环以此类推。当 list中的词全部被移走后,循环结束。
while 循环语句
while expr # 执行expr
do # 若expr的退出状态为0,进入循环,否则退出while
commands # 循环体
done
先执行 expr,如果其退出状态为 0,就执行循环体。执行到关键字 done后,回到循环的顶部,while命令再次检查 expr的退出状态。以此类推,循环将一直继续下去,直到 expr的退出状态非 0 为止,循环结束。
until 循环语句
until expr # 执行 expr
do # 若expr的退出状态非0,进入循环,否则退出until
commands # 循环体
done # 循环结束标志,返回循环顶部
与 while循环类似,区别是当 expr退出状态非 0 时才执行循环体,直到 expr为 0 时退出循环。
break n
(最内层为第 1层)
continue n
(最内层为第 1层)
exit n
sleep n
shift n
$?:表示命令返回值,一般情况,0表示成功,其他表示失败;
$#:表示函数体执行时候,传入该函数的参数个数;
$@:表示传入函数体所有参数信息;
Shell脚本中的函数
functionfunction_name {
commands
}
function_name() {
commands
}
#!/bin/bash
fun1 () { echo "This is a function"; echo; }
# 一个函数可以写成一行,但命令之间必须用分号隔开
# 特别注意,最后一个命令后面也必须加分号
fun2 ()
{
echo "This is fun2."
echo "Now exiting fun2."
}
function 函数名()
{
执行体
}
调用语法结构:
函数名 参数1 参数2 …
函数调用中,使用$+n来解析参数,其中n表示第几个参数。其他的与函数体外规则基本一致。
另外,$?:表示命令返回值,一般情况,0表示成功,其他表示失败;
$#:表示函数体执行时候,传入该函数的参数个数;
$@:表示传入函数体所有参数信息;
示例:
#!/bin/sh
#定义函数
function Func()
{
echo P_count = $#
echo p_all = $@
echo P1 = $1
echo P2 = $2
return 100
}
#调用函数Func
Func x1 x2
echo “Return Value = $?”
3 常用字符串处理命令
3.1 grep
grep命令在shell脚本中被大量的使用,对文本进行模式匹配查找,并打印符合模式的所有行。
一般格式为:
grep [options]基本正则表达式 [files]
常用的options有:
-c只输出匹配行的计数
-i不区分大小写
-h查询多文件时不显示文件名
-l查询多文件时只输出包含匹配字符的文件名
-n显示匹配行及行号
-s不显示不存在或无匹配文本的错误信息
-v显示不包含匹配文本的所有行
例如:
ps -ef | grep --color –w –i "proc"
输出:
root 22718 4664 0 01:26 pts/0 00:00:00 grep --color -w -i proc
root 29267 28514 2 00:57 ? 00:00:40 /opt/ne/0000/proc/00000000/prog/sbu.bin ,0,0,0,0 0
root 30719 28514 1 00:57 ? 00:00:33 /opt/ne/0000/proc/00000001/prog/rmu.bin 0,0,0,0,1 0
3.2 awk
awk命令可以通过制定分隔符来识别文本的列,然后对文本进行处理和格式化。
awk常用的格式为:
awk [–F ‘列分隔符’] ‘执行脚本’ files
其中,在执行脚本中$1、$2 … 标识某行的第1列、第2列 …
3.3 SORT排序
该命令用于对文本进行排序,类似于UE中排序功能;
使用格式:
sort [options] [fils]
例如:
ll | sort -k2 使用第2列进行排序
3.4 uniq
该命令一般情况下和sort配合使用,对文本进行唯一性过滤操作。
使用格式:
uniq [OPTION] [INPUT [OUTPUT]]
4 调试shell程序
写好的Shell脚本,在其运行结果不正确的情况下,需要对程序进行调试。除了大家都能想到的通过echo命令在某些点打印变量信息外,bash提供了另外的调试功能,即“bash –x 脚本名称”,通过该命令的输出结果可以清楚看到程序的执行流程和每个变量在某点的值。这种方法被广泛应用到实际工作中,可以帮助我们很快的定位问题。另外,我们也可以在脚本中使用调试开关。打开调试开关:set –x; 关闭调试开关:set +x 来具体根据脚本中某块执行情况。
示例:
5 管道使用说明
作用:将一个命令的输出作为另一个命令的输入
格式:命令1 |命令2
实例:
% echo “1 2 3” | awk ‘{print $2}’
2
6 本地变量
设置
<varname>=<value>
引用
$<varname>
清除
unset <varname>
7 环境变量
设置
<varname>=<value>
export <varname> #引出变量为环境变量
引用和清除
同本地变量
8 引号
“ ” 引用除$ \ `外的任意字符
‘ ’ 屏蔽任何引用
` ` 将反引号中的内容作为一个系统命令执行
\ 转义标志
例
% cat test.sh
#!/bin/sh
firstname=“Liu”
echo “How are you, Mr. $firstname ?”
echo ‘How are you, Mr. $firstname ?’
`uname`
echo “I have \$600.”
% ./test.sh
How are you, Mr. Liu ?
How are you, Mr. $firstname ?
SunOS
I have $600