shell编程基础
- 变量:字符串,数字,环境和参数
- 条件:shell中的布尔值
- 程序控制:if,elif,for,while,until,case
- 命令列表
- 函数
- shell内置命令
- 获取命令的执行结果
shell脚本是一个包含一系列命令的文本文件.
语法:
#!/bin/sh
符号#!用来指定该脚本的解析程序.
修改脚本的属性:
chmod +x filename
变量
1.引号
#!/bin/sh
myvar="Hi there"
echo $myvar
echo "$myvar"
echo '$myvar'
echo \$myvar
echo Enter some text
read myvar
echo '$myvar' now equals $myvar
exit 0
分析: $获得变量的内容,使用双引号,不影响变量的替换,使用单引号,反斜线不进行变量的替换.
2.参数变量
参数变量 | 说明 |
---|---|
$# | 传入脚本的命令行参数个数 |
$* | 所以命令行参数,各个值之间有空格 |
$@ | 各个参数扩展彼此分开的域,不受IFS值的影响 |
$0 | 命令本身(shell文件名) |
$1 | 第一个命令参数 |
$2 | 第二个命令行参数 |
案例:
#!/bin/sh
echo "number of vars:"$#
echo "values of vars:"$*
echo "value of var1:"$1
echo "value of var2:"$2
echo "value of var3:"$3
echo "value of var4:"$4
条件
(1)
if [ expression ]
then
#code block
fi
(2)
if [ expression ]
then
# code block
else
# code block
fi
(3)
if [ expression ]
then
# code block
else if [ pression ]
then
# code block
else
# code block
fi
fi
(4)
if [ expression ];then
# code block
elif [ expression ]
then
# code block
else
# code blcok
fi
fi
字符串比较
字符串比较 | 结果 |
---|---|
string1 = string2 | 两个字符串相同,结果为真 |
string1 != string2 | 两个字符串不同,结果为真 |
-n string | 字符串不为空,结果为真 |
-z string | 如果字符串为null,则结果为真 |
算术比较
算术比较 | 结果 |
---|---|
ex1 -eq ex2 | 相同结果为真 |
ex1 -ne ex2 | 不相等结果为真 |
ex1 -gt ex2 | ex1 > ex2为真 |
ex1 -ge ex2 | ex1 >= ex2 为真 |
ex1 -lt ex2 | ex1 < ex2 为真 |
ex1 -le ex2 | ex1 <= ex2 为真 |
!ex | 表达式结果为假,结果为真 |
综合比较
比较操作 | 整数比较 | 字符串比较 |
---|---|---|
相同 | -eq | = |
不同 | -ne | != |
大于 | -gt | > |
小于 | -lt | < |
大于或等于 | -ge | |
小于或等于 | -le | |
为空 | -z | |
不为空 | -n |
文件条件测试
文件条件测试 | 结果 |
---|---|
-d file | 文件为目录为真 |
-e file | 文件存在 |
-f file | 文件时普通文件 |
-g file | 文件的set-group-id位被设置为真 |
-r file | 文件可读 |
-s file | 文件大小不为0 |
-u file | 文件的set-urer-id位被设置为真 |
-w file | 文件可写 |
-x file | 文件可执行 |
案例代码:
#!/bin/sh
if [ -f /bin/bash ]
then
echo "file /bin/bash exists"
fi
if [ -d /bin/bash ]
then
echo "/bin/bash is a directory"
else
echo "/bin/bash is NOT a directory "
fi
控制结构
1.for循环
for var in [list] do
- code block
done
其中$var是循环控制变量,[list]是var需要遍历的一个集合,do/done对包含了循环体,相当于C语言中一对大括号.若do 和 for 写在同一行上,需要用”;”.
案例代码:
#! /bin/sh
for day in Sun Mon Tue Wed Thu Fri Sat
do
echo $day
done
exit 0
注意: 在for循环那行,变量day是没有加”
"符号的,而在循环体内,echo所在行变量
day是必须加上”$”符号的.
代码案例:打印当前目录下f开头的所有脚本文件
#!/bin/sh
for file in $(ls f*.sh)
do
echo $file
done
exit 0
2.while循环
while [ condition ]
do
# code blockdone
#! /bin/sh
echo "Enter password"
read trythis
while [ "$trythis" != "secret" ];do
echo "Sorry,try again"
read trythis
done
exit 0
3.until循环
until [ condition ]
do
# code block
done
区别: while 和 until 的区别在于while 为真时执行,until为假时执行.
4. case 语句
case “$var” in
condition1 )
;;
condition2 )
;;
* )
default statments
;;
esac
#! /bin/sh
echo "Hit a key,then hit return. "
read Keypress
case "$Keypress" in
[A-Z]) echo "Uppercase letter"
;;
[a-z]) echo "Lowercase letter"
;;
[0-9]) echo "Digit"
;;
*) echo"Punctuation,whitespace,or other"
;;
esac
exit 0
函数
函数的定义方式
function_name(){
statements
}
#! /bin/sh
yes_or_no()
{
echo "Is your name $* ?"
while true
do
echo -n "Enter yes or no:"
read x
case "$x" in
y | yes ) return 0 ;;
n | no ) return 1 ;;
* ) echo "Answer yes or no" ;;
esac
done
}
echo "Original parameters are $*"
if yes_or_no "$1"
then
echo "Hi $1,nice name"
else
echo "Never mind"
fi
exit 0
命令
1. break命令
默认情况下,break只跳出一层循环.
2. : 命令
冒号(:)命令只是一个空命令.
相当于true的别名. while : 实现无限循环
: 结构也会用在变量的条件设置中.
: $ {var:=value}
3. continue命令
使得for,while,untill循环跳到下一次循环继续执行.
4. .命令
点(.)命令用于当前shell中的执行命令.
5.echo命令
使用echo命令输出结尾带有换行符的的字符串.
去掉换行符:
(1)使用 -n
echo -n "string to output"
(2)使用 -e 启动反斜线转义字符(\c代表去掉换行符,\t代表制表符,\n代表回车)
echo -e "string to output\c"
6.eval命令
eval命令允许对参数进行求值.
foo=10
x=foo
y='$'$x
echo $y # 输出为 $foo
foo=10
x=foo
eval y='$'$x
echo $y # 输出为10
7.exec命令
两种不同的用法
(1)将当前shell替换成一个不同的程序.
(2)修改当前文件描述符
8.exit命令
exit命令使得脚本以退出码n结束运行.
在退出码0代表成功.
退出码1~125是脚本程序使用的错误代码.
退出码 | 说明 |
---|---|
126 | 文件不可执行 |
127 | 命令未找到 |
128以上 | 出现一个信号 |
9.export命令
export:将自定义变量设定为环境变量,这个环境变量可以被当前调用的其他脚本和程序看到.(当前shell中有效)
10.expr命令
expr命令将它的参数当做一个表达式求值.
expr 2 + 3
11.printf命令
格式化输出,和C语言中的有点像
$ printf "%s\n" hello
hello
$ printf "%s %d\t%s" "Hi There" 15 people
Hi There 15 people
字符转换限定符 | 说明 |
---|---|
d | 十进制输出 |
c | 输出一个字符 |
s | 输出一个字符串 |
12.return命令
return命令的作用使函数返回值.
13.set命令
set命令的作用是为shell设置参数变量.
案例代码:
#! /bin/sh
echo the date is $(date)
set $(date)
echo $0
echo The year is: $1
echo The month is: $2
echo The day is: $3
exit 2
14.shift命令
把所有参数变量左移一个位置,使得$2变成$1,$3变成$2
15.trap命令
trap命令的一种常见用途是在脚本程序被中断时完成清理工作.
trap command signal
两个参数,一个是接收到指定信号采取的行动,一个是处理的信号名.
信号 | 说明 |
---|---|
HUP(1) | 挂起 |
INT(2) | 中断,Ctrl+C |
QUIT(3) | 退出,Ctrl+\ |
ABRT(6) | 终止,严重执行错误发送 |
ALRM(14) | 报警,处理超时 |
TERM(15) | 终止,系统关机发送 |
#! /bin/sh
trap 'rm -f /tmp/my_tmp_file_$$' INT # 捕捉中断信号,捕捉到后执行命令,但是程序可以继续运行.
echo creating file /tmp/my_tmp_file_$$
date > /tmp/my_tmp_file_$$
echo "press interrupt (CTRL-C) to interrupt...."
while [ -f /tmp/my_tmp_file_$$ ];do
echo File exists
sleep 1
done
echo The file no longer exists
trap INT #只捕捉到INT信号,但是不执行任何命令.采取默认处理方式,立即终止脚本
echo creating file /tmp/my_tmp_file_$$
date > /tmp/my_tmp_file_$$
echo "presss interrrupt (CTRL-C) to interrrupt..."
while [ -f /tmp/my_tmp_file_$$ ];do
echo File exists
sleep 1
done
echo we never get here
exit 0
16.unset命令
unset命令的作用是从环境中删除变量和函数.
#! /bin/sh
foo="Hello world"
echo $foo
unset foo
echo $foo
说明:和foo= 执行结果一样,但是并不等同.foo=把foo设置设置为空.但是foo变量仍然存在,使用unset foo 效果是把变量foo从环境中删除.
参考书籍:
Linux 程序设计