2 Shell脚本相关
| 名称 | 相关知识点 |
|---|---|
| 2.1 Bash | pipe |
| 2.2 Linux三剑客 | grep、awk、sed |
shell是一个程序,可以称之为壳程序,用于用户与操作系统进行交互,相当于是一个命令解析器
2.1 Bash
执行shell脚本
./test.sh: ./表示当前目录,执行./test.sh会说明权限不够,不能执行。需要改变文件的权限:chmod 777 test.sh,就能执行
. ./test.sh: 在不想改变权限的时候,测试脚本是不是能够正常使用。 临时增加权限。
获取字符串长度
#!/bin/bash
#获取字符串长度
str="123456"
echo "${#str}"
创建文件,将命令写入bash_test文件中,bash可以读取文件中的命令
bash命令行展开
alias起别名 unalias 移除别名
shell变量
- 在bash shell中,每一个变量的值都是字符串, 当然也可以用declare 关键字显式定义变量的类型,在赋值的时候等号两边不能有空格,变量名必须有字母、下划线、数字组成,开头必须字母或者下划线。
- 局部变量:shell也有自定义函数,函数里面的变量为局部变量,但是它也是相当于全局变量,函数中的变量,在函数外调用也是可以的,如果要仅限函数使用,需要在函数变量前加个关键字:local
- 全局变量:每打开一个终端就是一个shell会话,在这个shell会话(终端)定义的变量就是全局变量,它在这个shell会话有效,当你打开另一个终端就是另一个shell会话,这个变量在另一个终端就失效了。
- 环境变量:在全局变量前加 export ,如:export a=1 那么这个变量就是环境变量了。创建这个变量的shell成为父shell,这个shell中,在创建一个shell叫做子shell,环境变量可以由父shell往下一级一级传,而不能逆转往上传递。当shell会话销毁时,这个环境变量也会随之销毁。想要永久保存就得环境变量写到启动文件中去。
引用shell变量
#!/bin/bash
#引用shell变量
str="abc"

echo "$str" //输出abc
echo "the str vaile is: $str1" //输出the str vaile is:
#后面增加一个1,就不能正确的识别变量
echo "the str vaile is: ${str}1" //输出the str vaile is:abc1
#所以我们引用变量,最好统一用 ${} 的形式
shell变量的赋值、修改、删除:
a、shell变量的赋值
#!/bin/bash
#变量的赋值
n=1
v1=${n}
v2='${n}'
v3="${n}"
echo "${v1}" //1
echo "${v2}" //${n}
echo "${v3}" //1
可以从结果看出不加引号和加双引号的结果是相同的,而单引号是原样输出变量后面赋值的内容。
b、shell变量的修改、删除:
#!/bin/bash
#变量值的修改
a=1
echo "a: ${a}"
a=2
echo "a: ${a}"
#只读变量是不可以修改的,在变量前加readonly,就是只读变量
c=1
echo "c: ${c}"
readonly c
c=2
echo "c: ${c}"
#只要在变量前面加一个 unset,如: unset a 就可以删除变量。
unset a
echo "a: ${a}"
shell特殊变量:
shell中字符串的拼接:
#!/bin/bash
#shell字符串的拼接
n1=ab
n2=cd
temp1=${n1}${n2} #中间不能有空格
temp2="${n1}${n2}"
temp3="${n1}cdefg"
echo "${temp1}"
echo "${temp2}"
echo "${temp3}"
字符串的截取
- ${string: start :length}:字符串从左边start开始的位置截取length个字符,如果没有length,就从左边start开始到结束
- ${string: 0-start :length}:字符串从右边start开始的位置截取length个字符,如果没有length,就从右边数start开始到结束
- ${string#*chars}:字符串从左边开始的第一个chars开始的位置截取到右边结束,chars本身不在截取范围内
- ${string##*chars}:字符串从左边开始的最后一个chars开始的位置截取到右边结束,chars本身不在截取范围内
- ${string%*chars}:字符串从右边边开始的第一个chars开始的位置截取到左边结束,chars本身不在截取范围内
- ${string%%*chars}:字符串从右边开始的最后一个chars开始的位置截取到左边结束,chars本身不在截取范围内
#!/bin/bash
#shell截取字符串
str=http//:baidu.com/.c
echo "length: ${str:7:5}" # baidu
echo "no length: ${str:7}" # baidu.com/.c
echo "length: ${str:0-7:5}" # .com/
echo "no length: ${str:0-7}" # .com/.c
echo "#: ${str#*/}" # /:baidu.com/.c
echo "##: ${str##*/}" # .c
echo "%: ${str%/*}" # http//:baidu.com
echo "%%: ${str%%/*}" # http
shell中的数组
- bash shell 中只支持一维,定义的形式:array=(n1 n2 n3)
- 数组名等号两边不能有空格,数组变量的值用空格隔开表示不同的值
- 一个数组变量的值可以用数字或者字符串不同的形式组成:array=(1 2 ab) 。
- Shell 数组的长度不是固定的,定义之后还可以增加元素,如:array[3]=cd,就在最后增加了一个元素。
- 不用逐个赋值;如:array=([2]=ab);但他的长度是1
调用数组:
- ${array[0]}
- a=${array[0]}
- ${array[*]} //表示数组的所有元素
- ${array[@]} //表示数组的所有元素
#!/bin/bash
#shell中的数组
array=( 1 2 ab)
n=${array} #array中的第一个元素赋值给n
echo "array[0]: ${array[0]}"
echo "array[*]: ${array[*]}"
echo "n[*]: ${n[*]}"
array[5]=cd
echo "array[5]: ${array[5]}"
echo "array[@]: ${array[@]}"
shell数组里字符串的长度:
#!/bin/bash
#shell中的数组
array=( 1 2 abc)
echo "#array[*] ${#array[*]}"
array[4]=12345
echo "#array[@] ${#array[*]}" #这边多加了一个元素就是4
echo "#array[4] ${#array[4]}" #这边是计算array[4]中字符串的长度
数组的拼接:
#!/bin/bash
#shell中的数组的拼接
array1=( 1 2 abc)
array2=(cd ef)
array3=(${array1[@]} ${array2[@]})
echo "array3: ${array3[@]}"
echo "array3 length: ${#array3[@]}"
shell数组元素的删除:
#!/bin/bash
#shell中的数组
array1=(1 2 abc)
array2=(1 2 abc)
unset array1[2] #删除array1数组中的一个元素abc
echo "array1[*]: ${array1[*]}"
unset array2 #删除整个数组array2
echo "array2[*]: ${array2[*]}"
shell中条件判断if:
a、if单分支:
- -eq 等于,如:if [ "b" ]
- -ne 不等于,如:if [ "b" ]
- -gt 大于,如:if [ "b" ]
- -ge 大于等于,如:if [ "b" ]
- -lt 小于,如:if [ "b" ]
- -le 小于等于,如:if [ "b" ]
#!/bin/bash
#shell中if:
#if单分支第一中形式:if []
if [ 1 -eq 1 ] #[]里面的数据和中括号必须一个空格
then
echo "first if:真"
fi
#if单分支第二中形式:if []; then
if [ 1 -eq 1 ]; then #then和if写在同一行必须要用;
echo "second if:真"
fi
#if单分支第三中形式:if (())
if ((1==1))
then
echo "third if:真"
fi
b、双分支if:
#!/bin/bash
#shell中if:
#if双分支
if ((1==0)) #判断1和o是不是相等
then
echo "我是真的"
else
echo "我是假的"
fi
#................................
if [ 1 -eq 0 ] #判断1和o是不是相等,
then
echo "我是真的"
else
echo "我是假的"
fi
shell中的 case语句:
#!/bin/bash
#shell中的case
read VAILE #在屏幕中输入一个数,1或者2,如果不是这两个数就代表其他;即 *),
case ${VAILE} in
"1")
echo "我是1"
;;
"2")
echo "我是2"
;;
*)
echo "我不是1,也不是2"
;;
esac
shell中的 for循环:
a)、for循环形式1:
#!/bin/bash
#shell中的 for
for n in 1 3 5 #n是我们自定义的变量,in后面三个数就是循环3次,每次的值从第一个数的值开始
do
echo "我是n,我的值是:${n}"
done
b)、for循环形式2:
#!/bin/bash
#shell中的 for
for ((n=0;n<3;n++))
do
echo "我是n,我的值是:${n}"
done
shell中的 while循环:
#!/bin/bash
#shell中的 while
n=0
while [ ${n} -lt 2 ] #n<2;就循环,否则退出循环
do
n=$((${n}+1))
echo "我是n,我的值是:${n}"
done
echo "我退出循环了"
shell中的 until循环:
#!/bin/bash
#shell中的 until
n=-2
until ((n>1)) #不满足条件就循环,满足条件则退出循环
do
n=$((${n}+1))
echo "我是n,我的值是:${n}"
done
echo "我退出循环了"
shell中的函数:
function 函数名(){
..........
}
function fun(){
if(($1 > 1)); then
echo "条件成立"
fi
if(($2 > 1)); then
echo "条件成立"
else
echo "条件不成立"
fi
}
fun 2 1 #这边传参数给fun()函数
2.2Linux三剑客
正则表达式
grep -E 即可使用正则表达式
grep
从文本文件或管道流中筛选匹配的数据和行
语法:grep 参数 匹配模式 file
grep test *file
//当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件
grep -E "^(root|yu)\>" /etc/passwd
//在/etc/passwd目录下找以root或yu开头并结尾的文件(-E表示复合条件)
grep -r update /etc/acpi
//查找指定目录/etc/acpi 及其子目录下所有文件中包含字符串"update"的文件,并打印出该字符串所在行的内容
grep -v test *test*
//查找文件名中包含 test 的文件中不包含test 的行
sed
主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。
通过sed一行一行读取文件内容到内存,判断是否符合条件,不符合条件输出,符合条件编辑后输出
语法: sed 选项 sed内置命令字符 输入文件
sed -e 4a\newLine testfile
//在 **testfile** 文件的第四行后添加一行
$ nl testfile | sed '2,5d'
//删除2-5行
sed '/^root/,/^ftp/d' pwd2
//删除pwd2文件中root开头的行到ftp开头的行
awk
是一种处理文本文件的语言(格式化处理)
语法:awk 参数 '条件动作' 文件
# 每行按空格或TAB分割,输出文本中的1、4项
$ awk '{print $1,$4}' log.txt
# 使用","分割,-F指定分割符号
$ awk -F, '{print $1,$2}' log.txt
awk -v # 设置变量