一、shell环境定义
-
临时环境变量
临时环境变量指的是用户在当前环境变量生效的变量,用户登陆系统后,直接在命令行定义的环境变量只能在当前的登陆环境中使用,当退出系统后,临时环境变量则失效
-
将环境变量永久生效
通过将环境变量定义写入到配置文件中,用户每次登陆时系统自动定义,则无需再到命令行重新定义。
定义环境变量的常见配置文件如下:
系统环境变量:/etc/profile 针对系统所有用户生效
用户环境变量:$HOME_name/.bash_profile 针对特定用户生效。当用户登陆系统后,首先继承/etc/profile文件中的定义,
再应用$HOME/.bash_profile文件中的定义。
系统预定义的环境变量:如 $PATH、$HOME、$SHELL、$PWD等等,对所有用户有效
二、shell脚本编程
-
创建shell脚本
一个shell脚本通常包含如下部分:
首行
第一行内容在脚本的首行左侧,表示脚本将要调用的shell解释器,内容如下:
#!/bin/bash
#! 符号能够被内核识别是一个脚本的开始,这一行必须位于脚本的首行,/bin/bash是bash程序的绝对路径,
在这里表示后续的内容将通过bash程序解释执行
创建脚本的三种方式:
第一种:#echo "" >first.sh 第二种: #touch first.sh 第三种: #vi firsh.sh
注释:
带#开头的就是一段注释
-
shell脚本的权限
一般情况下,默认创建的脚本是没有执行权限的,需要自行修改权限
修改权限
-
shell脚本的执行
1、输入脚本的绝对路径或相对路径
绝对路径:/home/hyx/test.sh 相对路径:./test.sh
2、bash或sh+脚本
bash test.sh sh test.sh
注意:当脚本没有x权限时,root和文件所有者可以通过该方式正常执行。
3、在脚本的路径前再加“.”,或source
source test1.sh ./test1.sh
区别:
第一种和第二种会新开一个bash,不同bash中的变量无法共享
第三种是在同一个shell里面执行的
-
shell变量
变量的分类
Linux Shell中的变量分为用户自定义变量、环境变量、位置参数变量和预定义变量
可以通过set参看系统中存在的变量
-
(1)用户自定义变量
用户自定义变量由字母或下划线开头,由字母,数字或下划线序列组成,并且大小写字母的意义不同,变量名
长度没有限制
设置变量:习惯上用大写字母来命名变量。变量名以字母表示的字符开头,不能用数字。
变量的调用
在使用变量时,要在变量名前加上前缀"$",使用echo查看变量值
echo $A
变量赋值
1、定义时赋值:变量=值(注意等号两边都不能有空格)
A="hello world"
2、将一个命令的执行结果赋值给变量
A=`ls -l` ## 反引号,运行里面的命令,并将结果返回给变量A A=$(ls -l) ## 等价于上面
3、将一个变量赋值给另一个变量
A="hello world" B=$A
变量叠加
AA=123 BB="$AA"456 CC=${AA}789
补充:
单引号和双引号的区别:单引号会将所有特殊字符脱意
列出所有的变量
set
删除变量
unset AA
注意:用户自定义的变量,作用域为当前的shell环境
-
(2)环境变量
环境变量在当前shell和其所有的子shell中生效。如果将环境变量写入相应的配置文件,那么这个环境变量就会在
所有的shell中生效
export 变量名=变量值 申明变量
作用域:当前shell以及所有的子shell
-
(3)位置参数变量
-
(4)预定义变量
-
read命令
格式:read [选项] 值
read -p(提示语句) -n(字符个数) -t(等待时间,单位为秒) -s(隐藏输入)
-
运算符
Num1=11 Num2=22 Sum=$Num1+$Num2 echo Sum
格式:expr m + n(注意运算符前后必须要有空格) 或 $((m+n))
expr 3 + 5 echo `expr 3 * 5`(是转移符)
计算 (2+3)*4
## 第一种方式 S=`expr 2 + 3` expr $S * 4 ## 第二种方式 expr `expr 2 + 3` * 4 ## 第三种方式 echo $(((2+3)*4))
补充:$()和${}的区别
$()的用途和反引号``一样,表示优先执行的命令
${}则是取变量
$((运算内容)) 适用于数值运算
-
条件测试
内置test命令
内置test命令常用操作符号[]表示,将表达式写在[]里面,如下:
[ expression ] ,(注意:表达式首尾都要留空格)
或者 test expression
测试范围:整数、字符串、文件
表达式的结果为真,则test的返回值为0,反之为1
字符串测试:
test str1 == str2 测试字符串是否相等 = test str1 != str2 测试字符串是否不相等 test str1 测试字符串是否不为空 test -n str1 测试字符串是否不为空 注意str1加双引号和不加的区别 test -z str1 测试字符串是否为空
整数测试:
test int1 -eq int2 测试整数是否相等 equals test int1 -ge int2 测试int1是否>=int2 test int1 -gt int2 测试int1是否>int2 test int1 -le int2 测试int1是否<=int2 test int1 -lt int2 测试int1是否<int2 test int1 -ne int2 测试整数是否不相等
文件测试:
test -d file ;echo $? 指定文件是否目录 test –e file ;echo $? 文件是否存在 exists test -f file ;echo $? 指定文件是否常规文件 test –L File ;echo $? 文件存在并且是一个符号链接 test -r file 指定文件是否可读 test -w file 指定文件是否可写 test -x file 指定文件是否可执行
多重条件测试:
条件1 –a 条件2 逻辑与 两个都成立,则为真
条件1 –o 条件2 逻辑或 只要有一个为真,则为真
! 条件 逻辑非 取反
-
流程控制语句
-
if/else 命令
1、单分支if条件语句
if [ 条件判断式 ] then 程序 fi 或者 if [ 条件判断式 ] ; then 程序 fi
单分支条件语句需要注意几个点
if语句使用fi结尾,和一般语言使用大括号结尾不同。
[ 条件判断式 ] 就是使用test命令判断,所以中括号和条件判断式之间必须有空格
then后面跟符号条件之后执行的程序,可以放在[]之后,用“;”分割,也可以换行写入,就不需要";"了。
2、多分支if条件语句
if [ 条件判断式1 ] then 当条件判断式1成立时,执行程序1 elif [ 条件判断式2 ] then 当条件判断式2成立时,执行程序2 ...省略更多条件 else 当所有条件都不成立时,最后执行此程序 fi
case语句
case命令是一个多分支的if/else命令,case变量的值用来匹配value1,value2,value3等等。
case 变量 in PAT1) 执行语句 ;; PAT2) 执行语句 ;; *) 默认执行语句 ;; esac
-
for 循环
第一种:
for N in 1 2 3 do echo $N done 或 for N in 1 2 3; do echo $N; done 或 for N in {1..3}; do echo $N; done
第二种:
for ((i = 0; i <= 5; i++)) do echo "welcome $i times" done 或 for ((i = 0; i <= 5; i++)); do echo "welcome $i times"; done
-
while循环
while [ expression ] do 执行语句 ... done 或者 while ((expression)) do 执行语句 ... done
-
自定义函数
函数的格式如下:
第一种:
函数名()
{
命令1…..
命令2….
return 返回值变量
}
第二种:
[ function ] funname [()] { action; [return int;] }
第三种:
function funname { action; return }
函数的调用: 直接函数名就可以调用函数
注意:
如果函数名后没有(),在函数名和{ 之间,必须要有空格以示区分。
-
脚本调试
sh -x script
这将执行该脚本并显示所有变量的值。
在shell脚本里添加
set -x 对部分脚本调试
sh -n script
不执行脚本只是检查语法的模式,将返回所有语法错误。
sh –v script
执行并显示脚本内容
-
cut
cut命令是用来剪下文本文件里的数据,文本文件可以是字段类型或是字符类型。下面给出应用实例: /> cat /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin ... ... /> cut -d : -f 1,5 /etc/passwd #-d后面的冒号表示字段之间的分隔符,-f表示取分割后的哪些字段 root:root #这里取出的是第一个和第五个字段。 bin:bin daemon:daemon adm:adm ... ... /> cut -d: -f 3- /etc/passwd #从第三个字段开始显示,直到最后一个字段。 0:0:root:/root:/bin/bash 1:1:bin:/bin:/sbin/nologin 2:2:daemon:/sbin:/sbin/nologin 3:4:adm:/var/adm:/sbin/nologin 4:7:lp:/var/spool/lpd:/sbin/nologin ... ... 这里需要进一步说明的是,使用cut命令还可以剪切以字符数量为标量的部分字符,该功能通过-c选项实现,其不能与-d选项共存。 /> cut -c 1-4 /etc/passwd #取每行的前1-4个字符。 /> cut -c-4 /etc/passwd #取每行的前4个字符。 root bin: daem adm: ... ... /> cut -c4- /etc/passwd #取每行的第4个到最后字符。 t:x:0:0:root:/root:/bin/bash :x:1:1:bin:/bin:/sbin/nologin mon:x:2:2:daemon:/sbin:/sbin/nologin :x:3:4:adm:/var/adm:/sbin/nologin ... ... /> cut -c1,4 /etc/passwd #取每行的第一个和第四个字符。 rt b: dm a: ... ... /> cut -c1-4,5 /etc/passwd #取每行的1-4和第5个字符。 root: bin:x daemo adm:x
-
awk和sed
sed
sed是一个很好的文件处理工具,本身是一个管道命令,主要是以行为单位进行处理,可以将数据行进行替换、删除、新增、选取等特定工作,下面先了解一下sed的用法
sed命令行格式为:
sed [-nefri] ‘command’ 输入文本
常用选项:
- -n:使用安静模式。在一般sed用法中,所有的资料一般都会被列出到屏幕上,如果加上-n参数后,只有经过sed特殊处理的那一行才会被列出来。
- -e:值接在指令行模式上进行sed的工作编辑。
- -f:-f filename 可以执行filename内的sed动作。
- -r:支持扩展表达式
- -i:直接修改读取的档案内容。
常用命令:
- a:新增
- c:取代,后面可以接字符串
- d:删除
- i:插入
- p:列印,通常与sed -n一起
- s:取代,可以搭配正规表示法
实例:
删除某行:
sed '1d' test.txt # 删除第一行 sed '$d' test.txt #删除最后一行 sed '1,2d' test.txt # 删除第一行到第二行 sed '2,$d' test.txt # 删除第二行到最后一行
显示某行:
sed -n '1p' test.txt # 显示第一行 sed -n '$p' test.txt #显示最后一行 sed -n '1,2p' test.txt # 显示第一行到第二行 sed -n '2,$p' test.txt # 显示第二行到最后一行
使用模式进行查询
sed -n '/test/p' test.txt # 查询包括test所在的行 sed -n '/$/p' test.txt # 查询包括$所在的行
增加一行或多行字符串
sed '1a hello' test.txt # 在第一行新增一行hello sed '1,3a hello' test.txt # 在第一行到第三行新增一行hello
代替一行或多行
sed '1c hello' test.txt # 第一行替换为hello sed '1,3c hello' test.txt # 第一行和第三行替换为hello
代替一行中的某部分
sed -in '/name=/p' test.txt | sed 's/name=//g' #将name=删除 sed -i 's/name=/name/g' `grep -rl ./` #批量修改目录下的文件的字段
删除匹配行
sed -i '/匹配字符/d' 文件 #删除文件中含有匹配字符的行
替换匹配行中的某个字符串
sed -i '/匹配字符串/s/需要替换的字符串/替换后的字符串/g' 文件
awk
sed常用于一整行数据的处理,awk则更倾向于将一行数据分为多个字段进行处理
选项说明:
awk -F "字符串" 以某个字符串为分隔符进行分割
例子:
文件:test.txt
a=$(cat test.txt | awk -F "=" '{print$1}') #以“=”为分隔符,取每行的第一个字段
结果:
常用的内置变量:
NR #行数
NF #列数