一、Shell概述
什么是shell
1.shell是操作系统的最外层,是一个用户跟操作系统之间交互的命令解释器。
2.大多数linux默认的shell命令解释器是 bash(/bin/bash)
3.shell独立于内核,是链接内核和应用程序的桥梁,通俗来讲shell是内核周围的外壳
Shell既是一种应用程序,又是一种程序设计语言。
shell的作用 --命令解释器,翻译官
什么是shell脚本
shell脚本是shell命令组成的文件。
换一种说法,shell脚本是利用shell的功能所写的一个程序,
这个程序使用纯文本文件将一些shell语法和指令写在里面,让使用者很容易的就能够一个操作执行多个命令
shell的用途
1、shell可以合并编程语言以控制进程和文件,以及启动和控制其他程序
2、shell能够减少大量的重复输入和交互操作,能够进行批量的处理和自动化完成维护,减轻管理层的负担
1.作为应用程序
交互式地解释、执行用户输入的命令,将用户的操作翻译成机器可以识别的语言,完成相应功能。
shell 命令解释器
Linux 系统中提供了好几种不同的 shell 命令解释器, 如 sh、ash、bash 等。
/bin/bash
/bin/sh
shell 是用户跟内核通信方式的之一
2.作为程序设计语言
它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支,完成类似于 windows 下批处理操作,简化我们对系统的管理与应用程序的部署称之为 shell 脚本。
shell与c等语言的区别
c/c++等语言,属于编译性语言(编写完成后需要使用编译器完成编译、汇编、链接等过程变为二进制代码方可执行), shell 脚本是一种脚本语言,我们只需使用任意文本编辑器,按照语法编写相应程序,增加可执行权限,即可在安装 shell 命令解释器的环境下执行。
shell脚本文件是.sh的文件
shell 脚本分类
1.系统进行调用
这类脚本无需用户调用,系统会在合适的时候调用,如:/etc/profile、~/.bashrc 等
/etc/profile
此文件为系统的每个用户设置环境信息,当用户第一次登录时该文件被执行
系统的公共环境变量在这里设置
开始自启动的程序,一般也在这里设置
~/.bashrc
用户自己的家目录中的.bashrc
登录时会自动调用,打开任意终端时也会自动调用
这个文件一般设置与个人用户有关的环境变量,如交叉编译器的路径等等
2.手动进行调用
用户编写,需要手动调用的
二、shell 语法
shell 脚本的定义与执行
定义以开头:#!/bin/bash
#!用来声明脚本由什么 shell 解释,否则使用默认 shell
单个"#"号代表注释当前行
三种执行方式:
1) chmod +x test.sh
./test.sh 增加可执行权限后执行
2) bash test.sh 直接指定使用 bash 解释 test.sh
3). test.sh 使用当前 shell 读取解释 test.sh
区别
1.bash 明确指定 bash 解释器去执行脚本 ,脚本中#!指定的解释器不起作用
2. 用./ 首先检测#!,使用#!指定的 shell,如果没有使用默认的 shell
3.用 . 去执行脚本不会启动新的 shell,直接由当前的 shell 去解释执行脚本。
变量
自定义变量 【重点】
定义语法:
变量名=变量值
引用语法:
$变量名
清除变量语法:
unset varname
示例一
#!/bin/bash
age=20
name=hello
echo "$name $age"
其他用法
read string 从键盘输入一个字符串付给变量 string
readonly var=100 定义一个只读变量,只能在定义时初始化,以后不能改变,不能被清除
示例二
#!/bin/bash
readonly PI=3
echo $PI
x=1
x=2
echo $x
# 清除x变量之后,变量还可以再次读取,但变量的内容是空
unset x
echo $x
r=2
# shell进行算术运算时,bash/sh 不运行小数点计算
S=$(( PI*r ))
echo $S
结果
注意:
1)引用语法:$变量名
2)readonly var=100 定义一个只读变量,只能在定义时初始化,以后不能改变,不能被清除
3)# 清除x变量之后,变量还可以再次读取,但变量的内容是空
4)# shell进行算术运算时,bash/sh 不运行小数点计算
5)变量名只能包含英文字母下划线,不能以数字开头
6)等号两边不能直接接空格符,若变量中本身就包含了空格,则整个字符串都要用双引号、或单引号括起来;
7)双引号内的特殊字符可以保有变量特性,但是单引号内的特殊字符则仅为一般字符
#!/bin/bash
msg="hi disen"
echo $msg
echo "$msg very good"
echo '$msg very good'
bye='bye bye'
echo "$bye"
结果
预设变量
$#:传给 shell 脚本参数的数量
$*:传给 shell 脚本参数的内容
$1、$2、$3、...、$9:运行脚本时传递给其的参数,用空格隔开
$?:命令执行后返回的状态
"$?" 用于检查上一个命令执行是否正确(在 Linux 中,命令退出状态为 0 表示该命令正确执行,任何非 0 值表示命令出错)。
$0:当前执行的进程名
$$:当前进程的进程号
"$$"变量最常见的用途是用作临时文件的名字以保证临时文件不会重复
示例一
#!/bin/bash
echo "$#"
echo "$*"
echo "$1,$2,$3"
#双引号可以保持变量活性
echo $?
rm a.txt
echo $?
执行
bash t1.sh 1 2 3
结果
0成功,1失败,因此最后为1
示例二
echo "当前的进程名: $0"
echo "当前的进程号: $$"
结果
""(双引号):包含的变量会被解释
''(单引号):包含的变量会当做字符串解释
`` (反引号):反引号中的内容作为系统命令,并执行其内容,可以替换输出为一个变量
$ echo "today is `date` "
\ 转义字符: 同 c 语言 \n \t \r \a 等 echo 命令需加-e 转义
(命令序列): 由子 shell 来完成,不影响当前 shell 中的变量, 命令之间使用分号分隔。
{ 命令序列 }: 在当前 shell 中执行,会影响当前变量, 每个命令都要加分号";"
示例三
echo "current datetime is `date +%Y-%m-%d\ %H:%M:%S`"
示例四
name=Disen
echo "0 $name"
(name=Lucy; echo "1 $name")
echo 0:$name
{name=Jack; echo "2 $name";}
echo 0:$name
说明() 不影响当前shell中的变量 而 { } 却会影响
注意
(命令序列): 由子 shell 来完成,不影响当前 shell 中的变量, 命令之间使用分号分隔。
{ 命令序列 }: 在当前 shell 中执行,会影响当前变量, 每个命令都要加分号";"
条件测试语句test
在写 shell 脚本时,经常遇到的问题就是判断字符串是否相等,可能还要检查文件状态
或进行数字测试,只有这些测试完成才能做下一步动作。
test 命令有两种格式:
1) test condition
2) [ condition ]
文件
文件测试:测试文件状态的条件表达式
-e 是否存在 -d 是目录 -f 是文件
-r 可读 -w 可写 -x 可执行
-L 符号连接 -c 是否字符设备 -b 是否块设备
-s 文件非空
示例一
示例二
字符串
test str_operator “str”
test “str1” str_operator “str2”
[ str_operator “str” ]
[ “str1” str_operator “str2”]
str_operator:
= 两个字符串相等 != 两个字符串不相等
-z 空串 -n 非空串
示例一
示例二
数字
test num1 num_operator num2
[ num1 num_operator num2 ]
num_operator:
-eq 数值相等 -ne 数值不相等
-gt 数 1 大于数 2 -ge 数 1 大于等于数 2
-lt 数 1 小于数 2 -le 数 1 小于等于数 2
示例一
示例二
复合测试
command1 && command2 左边命令执行成功(即返回 0)shell 才执行右边的命令
command1 || command2 左边的命令未执行成功(即返回非 0)shell 才执行右边的命令
示例
测试a.txt是否存在,如果存在,则写入good内容。
然后创建a.txt ,再次执行
控制语句
if 控制语句
if [ 条件 ] ; then
执行程序
fi
示例
#!/bin/bash
# 验证是否提供了文件路径
if [ $# -eq 1 ]
then
echo "命令行参数有效"
fi
或者
#!/bin/bash
# 验证是否提供了文件路径
if [ $# -eq 1 ] ;then
echo "命令行参数有效"
else
echo "必须提供一个文件名,格式 svim filepath.sh"
fi
注意
[ 的左右必须有一个空格 ] 的左右也必须有一个空格
case 控制语句
case $变量名称 in
“第一个变量内容”)
程序段一
;;
“第二个变量内容”)
程序段二
;;
*)
其它程序段
exit 1 或 ;;
esac
示例
#!/bin/bash
echo "please input y/n"
read yn
case $yn in
y)
echo "you input yes..."
;;
n)
echo "exit..."
;;
*)
echo "you input is invalid argument "
exit 1
esac
扩展
#!/bin/bash
echo "please input y/n"
read yn
case $yn in
y|Y|yes|Yes|YES)
echo "you input yes..."
;;
n|N|no|No|NO)
echo "exit..."
;;
*)
echo "you input is invalid argument "
exit 1
esac
for 控制语句
for (( 初始值; 限制值; 执行步阶 ))
do
程序段
done
示例
求100以内所有5的倍数的和
declare -i s 代表强制把 s 变量当做 int 型参数运算
#!/bin/bash
declare -i total=0
for((i=5;i <= 100; i++)) ;do
# shell中进行算术运算及关系比较,最好使用 (( 算术相关表达式 ))
if (( i%5 == 0 )); then
total+=i
fi
done
echo "$total"
while 控制语句
while [ condition ]
do
程序段
done
until 控制语句
这种方式与 while 恰恰相反,当 condition 成立的时候退出循环,否则继续循环。
until [ condition ]
do
程序段
done
break和continue
break 命令允许跳出循环,通常在进行一些处理后退出循环或 case 语句
continue 命令类似于 break 命令, 只有一点重要差别,它不会跳出循环,只是跳过这个循环步骤。