shell 总结
1.变量
用一个固定的字符串(也可能是字符、数字等组合)代替更多、更复杂的内容、改内容里客人能还包含变量、路径、字符串等其它的内容。 变量时暂时存储数据的地方及数据标记,所存储的数据存在于内存空间中,通过正确的调用内存空间中变量的名字就可以去除与变量对应的数据。
变量的特性:
默认情况下bash shell中是不会区分变量类型的,整数型、字符串、小数等,也可以使用declare显示定义变量的类型。
变量类型:
环境变量(也可称为全局变量),可以在创建他们的shell及其派生出来的任意进程shell中使用,环境变量又可分为自定义环境变量和bash内置的环境变量。 普通变量(也可以称为局部变量),只能在创建他们的shell函数或shell脚本中使用,普通变量一般由开发者在开发脚本程序时创建。
2.环境变量
一般是指用export内置命令导出的变量,用于定义shell的运行环境,保证shell命令的正确执行。shell通过环境变量来确定登陆用户名、命令路径、终端类型、登录目录等,所有的环境变量都是系统全局变量,可用于所有子进程中,这包括编辑器、shell脚本和各类应用。 环境变量可以在命令行中设置和创建,但用户退出命令行时这些变量值就会丢失,因此,如果想永久保存环境变量,可以在用户的家目录下的.bash_profile或 .bashr(非用户登录模式特有,例如远程SSH)文件中,或者全局配置/etc/bashr(非用户登录模式特有,例如远程SSH)或/etc/profile文件中定义。在将环境变量放入上述文件中,每次用户登录时这些变量都将被初始化。 按照系统规范,所有的环境变量的名字均采用大写形式。 IFS=$'\t\n' 内部字段分隔符,一般是空格符、制表符和换行符,用于划分由命令替换、循环结构中和所读取的输入产生的词的字段。 PS1='[\u@\h \w]\$' 主题是符串,默认是$ PS2='>' 次提示符,默认值是 > 显示变量值的命令: set:输出所有的变量,包括全局变量和局部变量;set -o显示bash shell的所有参数配置信息。 env:只显示全局变量; declare:输出所有的变量、函数、整数和已经导出的变量
变量名通常要大写;
变量可以在自身的shell及子shell中使用;
常用export来定义环境变量;
执行env默认可以显示所有的环境变量名称及对应的值;
输出时间用“$变量名 ”,取消时用“unset变量名”;
书写crond定时任务时要注意,脚本要用到的环境变量里最好先在执行的shell脚本中重新定义;
如果希望环境变量永久生效,则可以将其放在用户环境变量文件或全局环境变量文件里;
如果用户的shell不是登录时启动的(比如手动敲下bash时启动或者其它不需要输入密码的登录及远程连接情况),那么这种非登录shell指挥加载¥HOME/.bashrc(用户环境变量文件),并会去找/etc/bashrc(全局环境变量文件)。因此如希望在非登录shell下也可读到设置的环境变量等内容,就需要将变量设定等写入$HOME/.bashrc 或者/etc/bashrc,而不是$HOME/.bash_profile或/eetc/profile。
shell中特殊且重要的变量
($和$@不加双引号输出内容相同) [root@localhost ~]# for i in $;do echo $i;done i am clever girl. [root@localhost ~]# for i in $@;do echo $i;done i am clever girl.
($和$@加上双引号) [root@localhost ~]# for i in "$@";do echo $i;done(有双引号,每个参数均以独立的内容输出) i am clever girl. [root@localhost ~]# for i in "$";do echo $i;done(有双引号,参数里的内容当作一个参数输出了) i am clever girl.
(如果$不加双引号,会输出所有参数,第一个参数i am也被拆开输出) [root@localhost ~]# for i in $;do echo $i;done i am a girl [root@localhost ~]# for i in "$*";do echo $i;done i am a girl
(用shift将位置参数移位、左移) [root@localhost ~]# set -- "i am" a clever girl [root@localhost ~]# shift [root@localhost ~]# echo $1 a [root@localhost ~]# echo $2 clever [root@localhost ~]# echo $3 girl
2.shell进程中的特殊状态变量
$?:获取执行上一个指令状态返回值(0为成功,非0为 失败),常用 $$:获取当前执行的shell脚本的进程号(PID),不常用 $!:获取上一个在后台工作的进程的进程号(PID),不常用 $_:获取在此之前执行的命令或脚本的最后一个参数,不常用
$:获得上一条命令的最后一个参数值 [root@localhost sh]# ls -ld drwxr-xr-x. 2 root root 172 Sep 17 05:47 . [root@localhost sh]# echo $ -ld
$!:获取上一次执行脚本的pid [root@localhost sh]# ps -ef|grep pid.sh|grep -v grep [root@localhost sh]# sh pid.sh & [1] 8624 [root@localhost sh]# echo $! 8624
(3)exec exec命令能够在不创建新进程的子进程的前提下,转去执行指定的命令,当指定的命令执行完毕后,该进程(也就是最初的shell)就终止了。 当使用exec打开文件后,read命令每次都会将文件指针移动到文件的下一行进行读取,直到文件末尾,利用这个可以实现处理文件内容 。
比较结果: 变量自带的计算长度的方法效率最高,在要求效率的场景中尽量多用。 使用管道统计的方法的效率都比较差,在要求效率的场景中尽量不用。
(()):进行数值运算与数值比较
((i=i+1)):赋值计算 [root@localhost ~]# echo $((1+1)) 2 i=$((i+1)):可以“(())”前加$符,表示将表达式运算后赋值给 i [root@localhost ~]# echo 2=$((2+3)) 2=5 ((8>7&&5==5)):可以进行比较,还可以加入逻辑卷与逻辑或,用于条件判断 echo $(2+1):需要直接输出运算表达式的运算结果时,可以在“(())“前加上$符 [root@localhost ~]# echo $((2+1)) 3 echo $((3<8)):双括号进行比较及判断 ,1为真,0为假 [root@localhost ~]# echo $((a+=1)) 9 [root@localhost ~]# echo $((a**2)) 81 [root@localhost ~]# echo $((a+=1)) 10 [root@localhost ~]# echo $((a**2)) 100
各种”(())“运算的脚本
[root@localhost ~]# cat test.sh #!/bin/bash a=6 b=2 echo "a-b=$(($a-$b))" echo "a+b=$(($a+$b))" echo "a*b=$(($a*$b))" echo "a/b=$(($a/$b))" echo "a**b=$(($a**$b))" echo "a%b=$(($a%$b))" [root@localhost ~]# sh test.sh a-b=4 a+b=8 a*b=12 a/b=3 a**b=36 a%b=0 传参: [root@localhost ~]# sh test.sh 5 2 a-b=3 a+b=7 a*b=10 a/b=2 a**b=25 a%b=1 [root@localhost ~]# cat test.sh #!/bin/bash a=$1 b=$2 echo "a-b=$(($a-$b))" echo "a+b=$(($a+$b))" echo "a*b=$(($a*$b))" echo "a/b=$(($a/$b))" echo "a**b=$(($a**$b))" echo "a%b=$(($a%$b))"
let运算、let赋值表达式:
[root@localhost ~]# i=1 [root@localhost ~]# let i=i+3 [root@localhost ~]# echo $i 4 let i=i+5 相当于 ((i=i+8))
[root@localhost ~]# expr 2 + 2 4 [root@localhost ~]# expr 2 - 2 0 [root@localhost ~]# expr 2 \* 2 4 expr配合变量计算: [root@localhost ~]# i=5 [root@localhost ~]# i=`expr $i + 4` [root@localhost ~]# echo $i 9 expr可以判断某个变量 将一个位置的变量和一个已知的整数相加,看返回值是否为0,如果为0就认为加法的变量为整数,否则就不是整数。 [root@localhost ~]# i=2 [root@localhost ~]# expr $i + 6 &>/dev/null [root@localhost ~]# echo $? 0 [root@localhost ~]# i=dada [root@localhost ~]# expr $i + 6 &>/dev/null [root@localhost ~]# echo $i dada 通过传参判断输出内容是否为整数 [root@localhost ~]# vi 1_expr.sh [root@localhost ~]# cat 1_expr.sh #!/bin/bash expr $1 + 1 >/dev/null 2>&1 [ $? -eq 0 ] && echo int||echo chars [root@localhost ~]# sh 1_expr.sh boy chars [root@localhost ~]# sh 1_expr.sh 2 int 注意: 运算符及用于计算的数字左右都至少要有一个空格,否则会报错。 使用乘号时,必须用反斜线屏蔽其特定含义,因为shell可能会误解星号的含义。
read:通过read读入持续等待输入例子
[root@localhost ~]# cat 1_int.sh #!/bin/bash while true do read -p "Pls input:" a expr $a + 0 >/dev/null 2>&1 [ $? -eq 0 ] && echo int || echo chars done [root@localhost ~]# sh 1_int.sh Pls input:2 int Pls input:dada chars Pls input:2da chars Pls input:^C
[root@localhost ~]# sh t1.sh 2 2 is a num [root@localhost ~]# sh t1.sh da da is not a num [root@localhost ~]# cat t1.sh #!/bin/bash if [[ `expr match "$1" "[0-9][0-9]*$" ` == 0 ]] then echo "$1 is not a num" exit 2 else echo "$1 is a num" fiexpr的特殊用法:(判断文件扩展名是否符合要求)
[root@localhost ~]# cat expr1.sh #!/bin/bash if expr "$1" : ".*\.pub" &>/dev/null then "you are using $1" else echo "pls use *.pub file" fi [root@localhost ~]# sh expr1.sh file pls use *.pub file 利用expr计算字符串长度: [root@localhost ~]# char="i am girl" [root@localhost ~]# expr length "$char" 9 [root@localhost ~]# echo ${#char} 9 [root@localhost ~]# echo ${char}|wc -L 9 [root@localhost ~]# echo ${char}|awk '{print length ($0)}' 95 .编写shell脚本,打印下面语句中字符数不大于6的单词
[root@localhost ~]# cat word_length.sh #!/bin/bash for n in I am good child linux welcome to our training do if [ `expr length $n` -le 6 ] then echo $n fi done [root@localhost ~]# sh word_length.sh I am good child linux to ourbc命令的用法:
bc是unix/linux下的计算器,因此,除了可以作为计算器来使用,还可以作为命令行工具来使用。 [root@localhost ~]# bc bc 1.06.95 Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty'. 1+1 2 4*77 308 2-1 1 bc用在命令行下面 [root@localhost ~]# echo 3+5|bc 8 [root@localhost ~]# echo 3*4+5*1|bc 17 [root@localhost ~]# echo "scale=2;355/113"|bc(scale=2:保留两位小数) 3.14 [root@localhost ~]# echo "scale=6;355/113"|bc(scale=6:保留6位小数) 3.141592 利用bc配合变量运算: [root@localhost ~]# i=5 [root@localhost ~]# i=`echo $i+4|bc` [root@localhost ~]# echo $i 9 例:通过一条命令计算输出1+2+3+~~~+10的表达式,并计算出结果: 使用bc计算: [root@localhost ~]# echo "`seq -s '+' 10`=`seq -s "+" 10|bc`" 1+2+3+4+5+6+7+8+9+10=55 [root@localhost ~]# echo `seq -s '+' 10`=`seq -s "+" 10|bc` 1+2+3+4+5+6+7+8+9+10=55 [root@localhost ~]# echo `seq -s "+" 10|bc` 55 使用expr计算: [root@localhost ~]# echo `seq -s '+' 10`=`seq -s " + " 10|xargs expr`(+两边要有空格) 1+2+3+4+5+6+7+8+9+10=55 使用 $[] 计算: [root@localhost ~]# echo `seq -s "+" 10`=$(echo $[`seq -s "+" 10`]) 1+2+3+4+5+6+7+8+9+10=55 使用(())计算: echo `seq -s '+' 10`="$((`seq -s "+" 10`))" (4-2=2) [root@localhost ~]# echo "4 2"|awk '{print ($1-$2)}' 2 (17-2)/3 [root@localhost ~]# echo "17 3"|awk '{print ($1-2)/$2}' 5 (4-2)/2 [root@localhost ~]# echo "4 2"|awk '{print ($1-2)/$2}' 1
$[]符号运算:
[root@localhost ~]# i=5 [root@localhost ~]# i=$[i+6] [root@localhost ~]# echo $i 11 [root@localhost ~]# echo $[2*4] 8 [root@localhost ~]# echo $[2/4] 06.基于shell变量输入read命令的运算
shell变量除了可以直接赋值或脚本传参外,还可以使用read命令从标准输入中获得 ,read为bash内置命令。 read [参数] [变量名] 参数: -p prompt:设置提示信息。 -t timeout:设置输入等待的时间,单位默认为秒。
read的基本读入:
[root@localhost ~]# read -p "shu ru shuzi:" num(输入一个数字,赋值给num变量,num前面需要有空格) shu ru shuzi:2 [root@localhost ~]# echo $num(输出变量值) 2 [root@localhost ~]# read -p "please input two number:" a1 a2(读入两个输入,以空格分开,分别赋值给a1和a2变量,a1和a2之间要有空格) please input two number:1 2 [root@localhost ~]# echo $a1 1 [root@localhost ~]# echo $a2 2 read的读入功能相当于交互式接受用户输入,然后给变量赋值。 read -p 的功能可以用echo和read来实现。 [root@localhost ~]# read -t 6 -p "please input two number:"(在6秒内输入两个数) please input two number:1 3 [root@localhost ~]# read -t 6 -p "please input two number:"(超过6秒自动退出) please input two number:[root@localhost ~]# 用read方式读入整数变量进行加减乘除运算: [root@localhost ~]# cat test.sh #!/bin/bash read -t 5 -p "please input two numbers:" a b echo "a-b=$(($a-$b))" echo "a+b=$(($a+$b))" echo "a*b=$(($a*$b))" echo "a/b=$(($a/$b))" echo "a**b=$(($a**$b))" echo "a%b=$(($a%$b))" [root@localhost ~]# sh test.sh please input two numbers:1 3 a-b=-2 a+b=4 a*b=3 a/b=0 a**b=1 a%b=1 注意:脚本传参和read读入只用一种就好。 接受read的变量,不该带$符号。