(1)Linux系统高级程序设计:shell脚本

1 shell脚本

1.1 shell作为应用程序

shell 命令解析器可以交互式地解释、执行用户输入的命令,将用户的操作翻译成机器可以识别的语言,完成相应功能。shell 是用户和 Linux 内核之间的接口程序。 Linux 系统中提供了好几种不同的 shell 命令解释器, 如 sh、 ash、 bash 等。一般默认使用 bash 作为默认的解释器。
shell、内核与硬件之间的关系
shell所起到的作用

1.2 作为程序设计语言

它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。完成类似于 windows 下批处理操作,简化我们对系统的管理与应用程序的部署称之为 shell 脚本。 shell 脚本是一种脚本语言,我们只需使用任意文本编辑器,按照语法编写相应程序,增加可执行权限,即可在安装 shell 命令解释器的环境下执行.

2 shell语法

2.1 shell 脚本的定义与执行

#!/bin/bash #!用来声明脚本由什么 shell 解释,否则使用默认 shell
#"#"号代表注释当前行
chmod + x test.sh ./test.sh # 增加可执行权限后执行
bash test.sh # 直接指定使用 bash 解释 test.sh
.test.sh(source test.sh) # 使用当前 shell 读取解释 test.sh

三种执行脚本的方式不同点:
./和 bash 执行过程基本一致,后者明确指定 bash 解释器去执行脚本,脚本中#!指定的解释器不起作用。前者首先检测#!,使用#!指定的 shell,如果没有使用默认的 shell
用./和 bash 去执行会在后台启动一个新的 shell 去执行脚本。用.去执行脚本不会启动新的 shell,直接由当前的 shell 去解释执行脚本。

2.2 变量

2.2.1 自定义变量

num=10 # 定义变量
i=$num # 把变量 num 的值付给变量 i
echo $num # 显示变量
unset varname # 清除变量
read string # 从键盘输入一个字符串付给变量 string
readonly var=100 # 定义一个只读变量,只能在定义时初始化,以后不能改变,不能被清除。
export var=300 # 使用 export 说明的变量,会被导出为环境变量,其它 shell 均可使用

等号两边不能直接接空格符,若变量中本身就包含了空格,则整个字符串都要用双引号、或单引号括起来;双引号内的特殊字符可以保有变量特性,但是单引号内的特殊字符则仅为一般字符。
name = aa //错误
name=aa bb //错误
name=“aa bb” //正确
echo “$name is me” //输出: aa bb is me

echo ‘$name is me’ //输出: $name is me

#!/bin/bash
echo "this is the var test shell script "
name="edu"
echo "$name is me"
echo '$name is me'
echo "please input a string"
read string
echo "the string of your input is $string"

2.2.2 环境变量

shell 在开始执行时就已经定义了一些和系统的工作环境有关的变量,我们在 shell 中可以直接使用$name 引用。定义:一般在~/.bashrc 或/etc/profile 文件中(系统自动调用的脚本)使用 export 设置,允许用户后来更改。

env # 查看所有的环境变量
unset # 清除环境变量

常见环境变量:
HOME:用于保存注册目录的完全路径名。
PATH:用于保存用冒号分隔的目录路径名, shell 将按 PATH变量中给出的顺序搜索这些目录,找到的第一个与命 令名称一致的可执行文件将被执行。
HOSTNAME:主机名
SHELL:默认的 shell命令解析器
LOGNAME:此变量保存登录名
PWD:当前工作目录的绝对路径名

#!/bin/bash
echo "You are welcome to use bash"
echo "Current work dirctory is $PWD"
echo "the host name is $HOSTNAME"
echo "your home dir $HOME"
echo "Your shell is $SHELL"

2.2.3 预设变量

$#: 传给 shell 脚本参数的数量
$*:传给 shell 脚本参数的内容
$1、 $2、 $3、 …、$9:运行脚本时传递给其的参数,用空格隔开,第10个表示为${10}
$?:命令执行后返回的状态,通常用于检查上一个命令执行是否正确(在 Linux 中,命令退出状态为 0 表示该命令正确执行,任何非 0 值表示命令出错)。
$0:当前执行的进程名

#!/bin/bash
echo "your shell script name is $0"
echo "the params of your input is $*"
echo "the num of your input params is $#"
echo "the params is $1 $2 $3 $4"

2.2.4 引号的用法

“”(双引号):包含的变量会被解释
‘’(单引号):包含的变量会当做字符串解释
``(数字键 1 左面的反引号):反引号中的内容作为系统命令,并执行其内容,可以替换输出为一个变量。例如$ echo "today is date "的输出是:today is 2012 年 07 月 29 日星期日 12:55:21 CST

2.3 条件测试语句

2.3.1 对文件的测试

1)按照文件类型
-e 文件名 文件是否存在
-s 文件名 是否为非空
-b 文件名 块设备文件
-c 文件名 字符设备文件
-d 文件名 目录文件
-f 文件名 普通文件
-L 文件名 软链接文件
-S 文件名 套接字文件
-p 文件名 管道文件
2)按照文件权限
-r 文件名 可读
-w 文件名 可写
-x 文件名 可执行
3)两个文件之间的比较
文件 1 -nt 文件 2 文件 1 的修改时间是否比文件 2 新
文件 1 -ot 文件 2 文件 1 的修改时间是否比文件 2 旧
文件 1 -ef 文件 2 两个文件的 inode 节点号是否一样,用于判断是否是硬链接

#!/bin/bash
test -e /dev/qaz
echo $?
test -e /home
echo $?
test -d /home
echo $?
test -f /home
echo $?
mkdir test_sh
chmod 500 test_sh
[ -r test_sh ]
echo $?
[ -w test_sh ]
echo $?
[ -x test_sh ]
echo $?
[ -s test_sh ]
echo $?
[ -c /dev/console ]
echo $?
[ -b /dev/sda ]
echo $?
[ -L /dev/stdin ]
echo $?

2.3.2 对字符串进行测试

s1 = s2 测试两个字符串的内容是否完全一样
s1 != s2 测试两个字符串的内容是否有差异
-z s1 测试 s1 字符串的长度是否为 0
-n s1 测试 s1 字符串的长度是否不为 0

#!/bin/bash
test -z $yn
echo $?
echo "please input a y/n"
read yn
[ -z "$yn" ]
echo 1:$?
[ $yn = "y" ]
echo 2:$?

2.3.3 对数字进行测试

a -eq b 测试 a 与 b 是否相等
a -ne b 测试 a 与 b 是否不相等
a -gt b 测试 a 是否大于 b
a -ge b 测试 a 是否大于等于 b
a -lt b 测试 a 是否小于 b
a -le b 测试 a 是否小于等于 b

#!/bin/bash
echo "please input a num(1-9)"
read num
[ $num -eq 5 ]
echo $?
[ $num -ne 5 ]
echo $?
[ $num -gt 5 ]
echo $?
[ $num -ge 5 ]
echo $?
[ $num -le 5 ]
echo $?
[ $num -lt 5 ]
echo $?

2.3.4 复合测试

test -e /home && test -d /home && echo "true"
test 2 -lt 3 && test 5 -gt 3 && echo "equal"
test "aaa" = "aaa" || echo "not equal" && echo "equal"

2.4 控制语句

if语句
#!/bin/bash
echo "Press y to continue"
read yn
if [ $yn = "y" ]; then # 这里注意中括号和表达式之间必须有空格
	echo "script is running..."
else
	echo "stopped!"
fi
case语句
#!/bin/bash
echo "This script will print your choice"
case "$1" in
	"one")
		echo "your choice is one"
		;;
	"two")
		echo "your choice is two"
		;;
	"three")
		echo "Your choice is three"
		;;
	*)
		echo "Error Please try again!"
		exit 1 # 也可以不加这一句
		;;
esac
复合条件的case语句
#!/bin/bash
echo "Please input your choice:"
read choice
case "$choice" in
	Y | yes | Yes | YES)
		echo "It's right"
		;;
	N* | n*)
		echo "It's wrong"
		;;
	*)
		exit 1
esac
for语句
#!/bin/bash
declare -i sum # 将sum声明为int类型
for (( i=1; i<=100; i=i+1 ))
do
	sum=sum+i
done
echo "The result is $sum"
带判断的for语句
#!/bin/bash
for name in `ls`
do
	if [ -f $name ];then
		echo "$name is file"
	elif [ -d $name ];then
		echo "$name is directory"
	else
		echo "^_^"
	fi
done
while语句
#!/bin/bash
declare -i i
declare -i s
while [ "$i" != "101" ]
do
	s+=i;
	i=i+1;
done
echo "The count is $s"
until语句
# 与 while 恰恰相反,当 condition 成立的时候退出循环,否则继续循环。
#!/bin/bash
declare -i i
declare -i s
until [ "$i" = "101" ]
do
s+=i;
i=i+1;
done
echo "The count is $s"
break和continue语句
break # break 命令允许跳出循环。break 通常在进行一些处理后退出循环或 case 语句。
continue # continue 命令类似于 break 命令。只有一点重要差别,它不会跳出循环,只是跳过这个循环步骤。

2.5 函数

#!/bin/bash
is_it_directory()
{
	if [ $# -lt 1 ]; then
		echo "I need an argument"
		return 1
	fi
	if [ ! -d $1 ]; then
		return 2
	else
		return 3
	fi
}
echo -n "enter destination directory:"
read direct
is_it_directory $direct
echo "the result is $?"
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值