1. 初识shell
bash部分快捷键
Ctrl+a 切换到命令行开始(跟home一样,但是home在某些unix环境下无法使用)
Ctrl+e 切换到命令行末尾
Ctrl+u 清除剪切光标之前的内容
Ctrl+k 清除剪切光标之后的内容
ctrl+y 粘贴刚才所删除的字符
Ctrl+r 在历史命令中查找,输入关键字调出之前的命令
通配符置换
在 Shell命令中,通常会使用通配符表达式来匹配一些文件
*,?,[],{}
例:
字符 含义 实例
* 匹配 0 或多个字符 a*b a与b之间可以有任意长度的任意字符, 也可以一个也没有, 如aabcb, axyzb, a012b, ab。
? 匹配任意一个字符 a?b a与b之间必须也只能有一个字符, 可以是任意字符, 如aab, abb, acb, a0b。
[list] 匹配 list 中的任意单一字符 a[xyz]b a与b之间必须也只能有一个字符, 但只能是 x 或 y 或 z, 如: axb, ayb, azb。
[!list] 匹配 除list 中的任意单一字符 a[!0-9]b a与b之间必须也只能有一个字符, 但不能是阿 拉伯数字, 如axb, aab, a-b。
[c1-c2] 匹配 c1-c2 中的任意单一字符 如:[0-9] [a-z] a[0-9]b 0与9之间必须也只能有一个字符 如a0b, a1b... a9b。
{string1,string2,...} 匹配 sring1 或 string2 (或更多)其一字符串 a{abc,xyz,123}b a与b之间只 能是abc或xyz或123这三个字符串之一。
执行脚本方式
1、 sh 脚本.sh
2、 bash 脚本.sh
3、 ./脚本.sh # 需要执行权限
4、 . 脚本.sh
5、 source 脚本.sh
第一行: “#!/usr/bin/env bash”叫做shebang, shell语法规定shell脚本文件第一行为整个文件的解释器
第二行: 为“#”开头的行为注释行默认不会被程序所读取, 用来说明文件及标定所属人员使用, 也可用来解释程序 第七行: 为格式化打印语句printf, printf可以把后面的“hello world”打印到指定的终端中, \n 为换行符
2. 变量的类型
-
预定义变量、环境变量、自定义变量、位置变量
预定义变量
预定义变量
$? 最后一次执行的命令的返回状态。如果这个变量的值为 0,则证明上一条命令正确执行;如果这个变量的值为非 0 ,则 证明上一条命令执行错误
$$ 当前进程的进程号(PID)
$! 后台运行的最后一个进程的进程号(PID)
[root@newrain sh]# ls
count.sh hello.sh parameter2.sh parameter.sh #ls命令正确执行
[root@newrain sh]# echo $?
0
#预定义变量"$?"的值是0,证明上一条命令正确执
[root@newrain sh]# vim variable.sh
#!/bin/bash
echo "The current process is $$"
#输出当前进程的PID
#这个PID就是variable.sh脚本执行时生成的进程的PID
[root@newrain sh]# sleep 3000 &
[1] 12165
#符号"&"的意思是把命令放入后台执行
[root@newrain sh]# echo $!
12165
自定义变量
定义:变量名称=值
变量名称:只能由字母,数字,下划线组成,不能以数字开头;
注意:应该让变量名称有意义;
= 赋值符号 前后不能有空格 ;
值: 所有的字符串和数字都可以;
引用变量: $变量名 或 ${变量名}。
示例:
[root@newrain ~]# a=100
[root@newrain ~]# echo $a
100
[root@newrain ~]# echo $aa
# 这里输出为空,因为解释器认为$aa是变量
[root@newrain ~]# echo ${a}a
100a
查看变量: echo $变量名 set(所有变量:包括自定义变量和环境变量)
取消变量: unset 变量名 仅在当前shell中有效
作用范围: 仅在当前shell中生效
环境变量
shell在开始执行时已经定义好的
env 查看所有环境变量
set 查看所有变量
环境变量拥有可继承性:export之后就拥有继承性
export 导出变量(作用范围)
临时生效
[root@newrain ~]# IPADDR=192.168.1.1
[root@newrain ~]# echo $IPADDR
192.168.1.1
永久生效
写到4个登陆脚本中 ~/.bashrc ~/profile 更好放在/etc/profile.d/* 下建立独立的环境变量配置文件
常用环境变量:USER UID HOME HOSTNAME PWD PS1 PATH
PATH:存储所有命令所在的路径
3. 流程控制
条件
字符串
-n STRING
# -n 字符串长度不为零
-z STRING
# -z 字符串长度为0
STRING1 = STRING2
# = 判断两个字符串是否一样
STRING1 != STRING2
# != 判断两个字符串是否不一样
数字
eq 等于 ne 不等于 #
ge 大于等于 le 小于等于 #
gt 大于 lt 小于 #
文件
test
-f 存在且是普通文件 # 重要
-d 存在且是目录 #
-h 存在且是符号链接
-b 块设备
-c 字符设备
-e 文件存在 #
shell分支if语句
条件判断
If代码返回0表示真,非0为假
if语句语法如下: 1
if [ $1 -eq 1 ]
then
echo '等于1'
elif [ $1 -eq 2 ]
then
echo '等于二'
else
echo '既不等一,也不等于二'
fi
例:
#!/bin/bash
read -p "请输入号码: " num
if [ $num = 1 ];then
echo "1"
elif [ $num = 2 ];then
echo "2"
else
echo "输入有误!"
fi
多个条件联合
逻辑与
if [ $condition1 ] && [ $condition2 ]
if [ $condition -a $condition2 ]
if [[ $condition1 && $condition2 ]]
逻辑或
if [ $condition1 ] || [ $condition2 ]
if [ $condition -o $condition2 ]
if [[ $condition1 || $condition2 ]]
# test 和 [] 中 我们可以使用 [ $condition1 ] && [ $condition2 ] 或者 [ $condition -a $condition2 ]
# 在 [[]] 这种情况,我们可以直接使用[[ $condition1 && $condition2 ]]
建议在if中直接使用[[]]这种方式,这种方式更加稳定。[[]] shell的一个命令。
-a && 逻辑与 and 两端的条件都可以成立
-o || 逻辑或 or 两端的条件有一段成立就行
case 语句
case 语句是 shell 中流控制的第二种方式,语法如下:
case $word in
pattern1)
list1
;;
pattern2)
list2
;;
patternN)
listN
;;
*)
list*
;;
esac
命令;;表明流应该跳转到case语句的最后,类似C语言中的break指令。
4. 循环结构
shell循环-for语句
for i in {取值范围} # for 关键字 i 变量名 in 关键字 取值范围格式 1 2 3 4 5
do # do 循环体的开始
循环体
done # done 循环体的结束
例:
for i in {1..100}
do
echo $i
done
shell 循环while语句
while 条件 # while 关键字 条件 [ $1 -lt 10 ] ,while循环,条件为真的情况下,会循环
do
循环体
done
创建一个文件里面的用户
#!/bin/bash
while read user
do
id $user &>/dev/null
if [ $? -eq 0 ];then
echo "$user is already exists"
else
useradd $user
echo "create $user successfully"
fi
done < user.txt
shell循环until语句
until 条件 # 当后面的条件表达式,为假的时候进行循环,当他为真了就停止循环了。
do
循环体
done
[root@newrain ~]# cat until.sh
#!/bin/bash
x=1
until [ $x -ge 10 ]
do
echo $x
x=`expr $x + 1`
done
x=1
while [ ! $x -ge 10 ]
do
echo $x
x=`expr $x + 1`
done
循环控制shift、continue、break、exit
shift命令
位置参数可以用shift命令左移。比如shift 3表示原来的$4现在变成$1,原来的$5现在变成$2等等,原来的$1、$2、$3丢 弃,$0不移动。不带参数的shift命令相当于shift 1。
对于位置变量或命令行参数,其个数必须是确定的,或者当 Shell 程序不知道其个数时,可以把所有参数一起赋值给变量 $*。
break
结束并退出本次循环
continue
在循环中不执行continue下面的代码,转而进入下一轮循环
exit
退出脚本
常带一个整数给系统,如 exit 0
5. 函数
函数声明:
function_name () {
list of commands
}
function_name //调用函数
unset function_name //取消函数
函数传参:
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数
[root@newrain fun]# cat fun06.sh
#!/bin/bash
fun() {
echo $[$1*$2*$3]
}
fun 1 2 3
修改版:
[root@newrain fun]# cat fun06.sh
#!/bin/bash
if [ ! $# -eq 3 ];then
echo "Must Input Three number: p1 p2 p3"
exit fi
fun() {
echo $[$1*$2*$3]
}
fun $1 $2 $3
6. 数组
普通数组:只能用整数作为数组的索引
关联数组:可以使用字符串作为数组的索引
普通数组定义:
[root@newrain shell]# books=( linux shell awk sed )
引用:
[root@newrain shell]# echo ${books[0]}
linux
[root@newrain shell]# echo ${books[1]}
shell
[root@newrain shell]# echo ${books[2]}
访问数组:
[root@newrain shell]# aa=(haha heihei baibai)
[root@newrain shell]# echo ${aa[0]} //访问数组中的第一个元素
[root@newrain shell]# echo ${aa[@]} //访问数组中所有的元素,等同与echo ${aa[*]}
[root@newrain shell]# echo ${#aa[@]} //统计元素的个数
[root@newrain shell]# echo ${!aa[@]} //统计索引