even

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

1、变量声明

# 在声明变量的时候,不用加$, 并且等号的两边不能留有空格
a=1111

# 引用变量的时候需要用$进行修饰
echo $a

# 如果只需要引用变量,那么可以使用$变量名即可,如果需要对变量做处理,那么就需要使用${}, 其他方法可以参看另外一篇内容
echo ${a:1:1} # 表示从变量a中截取顺序为1的且位数为1位

# 通过关键字export 把变量变为全局变量
export a # 注意这里不需要使用 $修饰

# 查询全局是否有该变量
env | grep ^a  # 注意这里使用的是 ^符号

# 删除变量使用关键字,并且前面也不使用$修饰
unset a

变量声明的方法

# 声明数字, 使用关键字 declare
declare -i a=1
declare -i b=2
declare -i c=$a+$b

# 声明只读的变量
declare -r a="test"  # 这个时候即不可以用unset删除,也不能重新赋值,但是退出终端即消失

# 声明全局变量
declare -x even="even" # 相当于export出去

# 声明索引数组  -a


# 声明关联数组 -A

普通数组的定义方式

# 方式一
arr[0]=1
arr[1]=2

# 方式二, 注意该方式中是用空隔隔开的
arr=(1 2 3)  

# 查询数组所有项
echo ${arr[*]}

# 查询数组的长度
echo ${#arr[*]}

# 查询数组里的索引下标
echo ${!arr[*]}

# 获取数组指定的项
echo ${arr[*]:1:1}

# 可以把命令结果赋值给数组
arr=($(ls ./))

# 查看所有的数组
declare -a

 关联数组的定义

# 方式一
declare -A arr
arr[first]=aaa
arr[second]=bbb

# 方式二
declare -a array
array=([aaa]=AAA [bbb]=BBB)

# 其他的操作与普通数组一致

交互式变量定义

交互式变量定义的值   read  主要用于让用户去定义变量值

-p  提示信息

-n  字符数(限制变量的字符数)

-s  不显示

-t   超时(默认单位秒)(限制用户输入变量值的时间)

# 提示用户输入用户名
read -p "please input your name" name

echo $name  # 可以输出用户输入的用户名

# 提示用户输入密码
read -s -p "please input your password" pass

echo $pass  # 可以输出用户输入的密码

# 从文件中读取指定的字段
read  name pass < test.txt   # test.txt的内容是  aaa pass 注意分隔符是空隔

echo $name $pass  #则可以输出指定的字段

# 一次指定多个字段
read name age  #这时用户按次输入的值会被赋值给name与age, 达到一次赋值两个变量, 注意用空格隔开

 2、变量的处理

1、${VAR:-DEFAULT},VAR没有定义或者为空则输出$DEFAULT的值(VAR不变)
echo ${test:-test}  # 没有定义test的前提下,会使用 -后面的值,但是test的值还是空

2、${VAR:=DEFAULT},VAR没有定义或空则为$DEFAULT的值
echo ${test:=test} # 与上面不一样的是,test会被赋值为test

3、${#test} # 返回test这个变量值的长度

4、${test^^},把test中的所有小写字母转换为大写输出(不改变值)

5、${STR:POSITON},从$POSITON位置提取子串

6、${STR:POSITON:LENGTH},从$POSITON位置提取长度为$LENGTH子串

7、
${STR%SUBSTR},从$STR尾部查找匹配,删除最短匹配$SUBSTR的子串(正常顺序)
${STR%%SUBSTR},从$STR尾部查找匹配,删除最长匹配$SUBSTR的子串(正常顺序)
temp
=/etc/nginx/conf.d/default.conf echo ${temp%.*} # 输出 /etc/nginx/conf.d/default echo ${temp%%.*} # 输出 /etc/nginx/conf 8、 ${STR#SUBSTR},从$STR头查找匹配,删除最短匹配$SUBSTR的子串(非正常顺序) ${STR##SUBSTR},从$STR头部查找匹配,删除最长匹配$SUBSTR的子串(非正常顺序)
temp
=/etc/nginx/conf.d/default.conf echo ${temp#*.} # 输出 d/default.conf echo ${temp##*.} # 输出 conf (可以利用该方法来获取extname)

 3、简单的四则运算

 默认情况下,shell就只能支持简单的==整数==运算

shell支持下面几种运算符
+ - * /  %(取模,求余数) 

Bash shell 的算术运算有四种方式:
1. 使用 $(( ))
2. 使用 $[ ]
3. 使用 expr 外部程式
4. 使用 let 命令(一般使用该语句进行再赋值操作)

(注意使用以下的运算符的时候,不需要使用$对值进行引用 如: a=1;b=2 echo $(( a+b )) )
注意: n=1 let n+=1 等价于let n=n+1 

# 如果需要进行小数运算, 需要借助bc工具, 如果未安装,使用yum y
install bc
[root@server shell01]#
echo 1+1.5|bc

注意: i++ 与 ++i的区别在于前者是先赋值后计算,后者是先计算再赋值
a=1;b=1; let $c=a++ 与 let $d=++b 那么$c与$d的值是不一样的

 4、条件判断

  • 格式1: test  条件表达式

  • 格式2: [ 条件表达式 ]

  • 格式3: [[ 条件表达式 ]] 支持正则 

-e    是否存在   不管是文件还是目录,只要存在,条件就成立
-f    是否为普通文件
-d    是否为目录
-S    socket
-p    pipe
-c    character
-b    block
-L    软link

三种语法格式:
test -e file                    只要文件存在条件为真
[ -d /shell01/dir1 ]             判断目录是否存在,存在条件为真
[ ! -d /shell01/dir1 ]        判断目录是否存在,不存在条件为真
[[ -f /shell01/1.sh ]]        判断文件是否存在,并且是一个普通的文件

-s 判断文件是否有内容(大小),非空文件条件满足
说明:-s表示非空,! -s 表示空文件
说明:1.sh文件里有内容的。
[root@server shell01]# test -s 1.sh
[root@server shell01]# echo $?
0
[root@server shell01]# touch aaa
[root@server shell01]# cat aaa
[root@server shell01]# test -s aaa
[root@server shell01]# echo $?
1
[root@server shell01]# test ! -s aaa;echo $?
0
[root@server shell01]# test ! -s 1.sh
[root@server shell01]# echo $?
1

 文件权限相关的判断

-r    当前用户对其是否可读
-w    当前用户对其是否可写
-x    当前用户对其是否可执行
-u    是否有suid
-g    是否sgid
-k    是否有t位

两个文件的比较判断

file1 -nt  file2    比较file1是否比file2新    
file1 -ot  file2    比较file1是否比file2旧
file1 -ef  file2    比较是否为同一个文件,或者用于判断硬连接,是否指向同一个inode

test file1 -nt file2    
[ file1 -ot file2 ]

整数之间的判断

-eq    相等
-ne    不等
-gt    大于
-lt    小于
-ge   大于等于
-le    小于等于

字符串之间的判断

-z  是否为空字符串           字符串长度为0,就成立
-n  是否为非空字符串        只要字符串非空,就是成立
string1 = string2         是否相等
string1 != string2         不等

[root@server shell01]# AAA=hello
[root@server shell01]# BBB=world
[root@server shell01]# test -z $AAA
[root@server shell01]# echo $?
1
[root@server shell01]# test -n $AAA
[root@server shell01]# echo $?
0

[root@server shell01]# [ $AAA = $BBB ]
[root@server shell01]# echo $?
1
[root@server shell01]# [ $AAA != $BBB ]
[root@server shell01]# echo $?
0

多重条件判断

逻辑判断符号:
 -a     和 &&      (and 逻辑与)         两个条件同时满足,整个大条件为真
 -o     和 ||    (or 逻辑或)              两个条件满足任意一个,整个大条件为真

 
[ 1 -eq 1 -a 1 -ne 0 ]                整个表达式为真
[ 1 -eq 1 ] && [ 1 -ne 0 ]            


[ 1 -eq 1 -o 1 -ne 1 ]                整个表达式为真
[ 1 -eq 1 ] || [ 1 -ne 1 ]

[root@server shell01]# [ 1 -eq 0 ] && echo true || echo false
false
[root@server shell01]# [ 1 -eq 1 ] && echo true || echo false
true

&&:前面的表达式为真
||:前面的表达式为假



总结:
1、; && ||都可以用来分割命令或者表达式
2、; 完全不考虑前面的语句是否正确执行,都会执行;号后面的内容
3、&& 需要考虑&&前面的语句的正确性,前面语句正确执行才会执行&&后的内容;反之亦然
make && make install
4、|| 需要考虑||前面的语句的非正确性,前面语句执行错误才会执行||后的内容;反之亦然
5、如果&&和||一起出现,从左往右依次看,按照以上原则

 数值比较示例

示例:
数值比较:
[root@server ~]# [ $(id -u) -eq 0 ] && echo "the user is admin"   # $(id -u) 表示获取用户id
[root@server ~]$ [ $(id -u) -ne 0 ] && echo "the user is not admin"
[root@server ~]$ [ $(id -u) -eq 0 ] && echo "the user is admin" || echo "the user is not admin"

[root@server ~]# uid=`id -u`
[root@server ~]# test $uid -eq 0 && echo this is admin
this is admin
[root@server ~]# [ $(id -u) -ne 0 ]  || echo this is admin
this is admin
[root@server ~]# [ $(id -u) -eq 0 ]  && echo this is admin || echo this is not admin
this is admin
[root@server ~]# su - stu1
[stu1@server ~]$ [ $(id -u) -eq 0 ]  && echo this is admin || echo this is not admin
this is not admin
[stu1@server ~]$ 


类C风格的数值比较:
注意:在(( ))中,=表示赋值;==表示判断
 1159  ((1==2));echo $?
 1160  ((1<2));echo $?
 1161  ((2>=1));echo $?
 1162  ((2!=1));echo $?
 1163  ((`id -u`==0));echo $?
 
 1209  ((a=123));echo $a
 1210  unset a
 1211  ((a==123));echo $?
 


字符串比较:
注意:双引号引起来,看作一个整体;= 和 == 在 [ 字符串 ] 比较中都表示判断
 1196  a='hello world';b=world
 1197  [ $a = $b ];echo $?
 1198  [ "$a" = "$b" ];echo $?
 1199  [ "$a" != "$b" ];echo $?
 1200  [ "$a" !== "$b" ];echo $?        错误
 1201  [ "$a" == "$b" ];echo $?
 1202  test "$a" != "$b";echo $?



思考:[ ] 和 [[ ]] 有什么区别?

 1213  a=
 1214  test -z $a;echo $?
 1215  a=hello
 1216  test -z $a;echo $?
 1217  test -n $a;echo $?
 1217  test -n "$a";echo $?

# [ '' = $a ];echo $?
-bash: [: : unary operator expected
2
# [[ '' = $a ]];echo $?
0


 1278  [ 1 -eq 0 -a 1 -ne 0 ];echo $?
 1279  [ 1 -eq 0 && 1 -ne 0 ];echo $?
 1280  [[ 1 -eq 0 && 1 -ne 0 ]];echo $?

注意:获取参数的个数是 $# 获取所有的参数 $* ,获取上一个语句的执行状态是 $?  0表示正常 非0表示不正常 

5、流程控制语句

if语句

if [ command ];then
     符合该条件执行的语句
elif [ command ];then
     符合该条件执行的语句
else
     符合该条件执行的语句
fi

常用参数

常用的:
[ -a FILE ] 如果 FILE 存在则为真。
[ -d FILE ] 如果 FILE 存在且是一个目录则返回为真。
[ -e FILE ] 如果 指定的文件或目录存在时返回为真。
[ -f FILE ] 如果 FILE 存在且是一个普通文件则返回为真。
[ -r FILE ] 如果 FILE 存在且是可读的则返回为真。
[ -w FILE ] 如果 FILE 存在且是可写的则返回为真。(一个目录为了它的内容被访问必然是可执行的)
[ -x FILE ] 如果 FILE 存在且是可执行的则返回为真。
 
不常用的:
[ -b FILE ] 如果 FILE 存在且是一个块文件则返回为真。
[ -c FILE ] 如果 FILE 存在且是一个字符文件则返回为真。
[ -g FILE ] 如果 FILE 存在且设置了SGID则返回为真。
[ -h FILE ] 如果 FILE 存在且是一个符号符号链接文件则返回为真。(该选项在一些老系统上无效)
[ -k FILE ] 如果 FILE 存在且已经设置了冒险位则返回为真。
[ -p FILE ] 如果 FILE 存并且是命令管道时返回为真。
[ -s FILE ] 如果 FILE 存在且大小非0时为真则返回为真。
[ -u FILE ] 如果 FILE 存在且设置了SUID位时返回为真。
[ -O FILE ] 如果 FILE 存在且属有效用户ID则返回为真。
[ -G FILE ] 如果 FILE 存在且默认组为当前组则返回为真。(只检查系统默认组)
[ -L FILE ] 如果 FILE 存在且是一个符号连接则返回为真。
[ -N FILE ] 如果 FILE 存在 and has been mod如果ied since it was last read则返回为真。
[ -S FILE ] 如果 FILE 存在且是一个套接字则返回为真。
[ FILE1 -nt FILE2 ] 如果 FILE1 比 FILE2 新, 或者 FILE1 存在但是 FILE2 不存在则返回为真。
[ FILE1 -ot FILE2 ] 如果 FILE1 比 FILE2 老, 或者 FILE2 存在但是 FILE1 不存在则返回为真。
[ FILE1 -ef FILE2 ] 如果 FILE1 和 FILE2 指向相同的设备和节点号则返回为真。

例子1:判断对一个地址是否通ping通

#! /bin/bash

if [ $# -ne 1 ]
then echo "usage:$0 remote_ip" && exit;
fi

ping -c1 $1 &>/dev/null  # &>/dev/null表示需要执行结果,但是执行不输出过程, 注意在执行的过程中$0表示执行的程序文件名,$1才是参数, $@表示获取所有的参数
[ $? -eq 0 ] && echo "ping通$1" || echo "ping不通$1";

 例子2: 判断指定的进程是否存在

判断进程存在的方法有

  • ps -ef | grep 应用 | grep -v grep
  • pgrep 应用(可以匹配到部份,所以不推荐)
  • pidof (推荐)
#! /bin/bash

read -p "请输入需要查询的应用名称:" content;

pidof $content &>/dev/null;

[ $? -eq 0 ] && echo "该进程 $content 存在" || echo "该进程 $content 不存在";

 例子3:判断指定的地址是否可以正常访问

#!/bin/bash
wget http://10.1.1.2 &>/dev/null
[ $? -eq 0 ] && echo "该web服务是正常的" && rm -f /shell/shell01/index.* || echo "该web服务异常请检查"

 for循环

for variable in {list}
     do
          command 
          command
          …
     done
或者
for variable in a b c
     do
         command
         command
     done

语法结构举例说明:

# 从1到10循环
for var in {1..10};do echo $var;done
# 从1到5循环
for var in 1 2 3 4 5;do echo $var;done
# 从1到10循环
for var in `seq 10`;do echo $var;done
for var in $(seq 10);do echo $var;done
# 从0到10且步长为2
for var in {0..10..2};do echo $var;done
# 从0到10且步长为2
for var in {2..10..2};do echo $var;done
# 从10到1
for var in {10..1};do echo $var;done
# 从10到1步长为2
for var in {10..1..-2};do echo $var;done

for var in `seq 10 -2 1`;do echo $var;done

 计算1-100的奇数之和

#! /bin/bash

declare -i sum;

for var in $(seq 1 2 100);
do
  #sum=$[ var + sum ];
  let sum+=$var
done;

echo $sum;

 延伸

true    真
:       真
false

循环控制:

循环体: ==do....done==之间的内容

  • continue:继续;表示==循环体==内下面的代码不执行,重新开始下一次循环

  • break:打断;马上停止执行本次循环,执行==循环体==后面的代码

  • exit:表示直接跳出程序

 

posted on 2022-05-08 00:05  even_blogs  阅读(77)  评论(0)    收藏  举报