#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell

shell 变量:

name=”hauzai007”

echo $name

注意事项:

变量名和等号之间不能有空格

不能使用标点符号

不能使用bash里的关键字

只读变量:

name=”huazai007”

关键字:readonly name

删除变量:

unset name

变量类型:

1 局部变量:

局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量

2 环境变量:

所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。

系统环境变量:

查看所有环境变量:env

删除环境变量:unset HAHA

举个例子:

PPID:是当前进程的父进程的PID

PWD:当前工作目录。

RANDO:随机数变量。每次引用这个变量会得到一个0~32767的随机数。

查看所有环境变量:env

删除环境变量:unset

用vim在/etc/profile文件中添加我们想要的环境变量

设置新的环境变量
export 新环境变量名=内容
例:export MYNAME=”LLZZ”

生效:source /etc/profile

shell 字符串

单引号和双引号的区别:

单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;

双引号的优点:

  • 双引号里可以有变量
  • 双引号里可以出现转义字符

获取字符串的长度:

str=”abcd”

echo ${#str}

 

测试字符串

var=1234567890abcedef1203

1、使用#截取0以后的内容

echo ${var#*0}

结果:abcedef1203

#表示操作符,*0表示从左往右找到第一个0,截取0之后的所有字符

echo ${var##*0}

 结果:3

#表示操作符,*0表示从右往左找到第一个0,截取0之后的所有字符

2、使用%截取

echo ${var%0*}

 结果:1234567890abcedef12

%表示操作符,0*表示从右往左找到第一个0,截取0之前的所有字符

echo ${var%%0*}

结果:123456789

%表示操作符,0*表示从左往右找到第一个0,截取0之前的所有字符

3 根据索引来截取

提取字符串:

str=”abcd”

#表示从字符串第二个字符开始截取 ,取 4个字符

echo ${str:1:4}

echo ${var:0-2} 取后两个

 

shell 数组

定义数组

arr=(aa bb cc)

读取数组

echo ${arr[0]}

获取数组的所有元素

echo ${arr[@]}

echo ${arr[*]}

获取数组的长度

echo ${#arr[@]}

 

shell 多行注释:

:<<EOF

      xxxx

         xxxxx

EOF

shell 基本运算符

算数运算符

+ 加法

- 减法

* 乘法

/  除法

% 取余

= 赋值

==  比较(相等)

!= 不相等

 关于计算:

[root@k8s-node1 ~]# a=`echo "scale=2;3/10"|bc|awk -F '.' '{print $2}'`
[root@k8s-node1 ~]# echo $a%
30%

 

[root@k8s-node1 ~]# echo $[10*20]
200

 

[root@localhost ~]# expr 10 + 20
30
[root@localhost ~]# echo $((10+30))
40
[root@localhost ~]# n=10
[root@localhost ~]# let n++
[root@localhost ~]# echo $n
11
[]和[[]]区别
[[]]更强大,支持字符串的模式匹配(使用=~操作符时甚至支持shell的正则表达式)
[root@localhost ~]# sh t.sh 
包含
[root@localhost ~]# cat t.sh 
#!/bin/bash
a="xxoo"
if [[ $a =~ "x" ]]; then
    echo "包含"
else
    echo "不包含"
fi

 

关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字

-eq  是否相等

-ne  是否不相等

-gt  表示大于

-lt  表示小于

-ge  大于等于

-le 小于等于

布尔运算符

-o 或运算 两个表达式只要有一个是true 就返回true

[ $a -lt 20 -o $b -gt 100 ] 返回 true

-a 与运算 两个表达式都为true才返回true

[ $a -lt 20 -a $b -gt 100 ] 返回 false

逻辑运算符

&& 等同于 –a

|| 等同于-o

if [[ $a –lt $b  && $b –gt 100 ]]; then

      echo “”

else

      echo “”

fi

字符串运算符

=: 检测两个字符是否相等

!=: 检测两个字符不相等

-z : 是否为空

-n :字符串的长度是否为0

 

文件测试运算符

 

-b 检测文件是否为块设备: /dev/cdrom

-c 检测文件是否是字符设备文件 /dev/pts/0 (伪终端)

-d  是否为目录

-f 是否为普通文件

-r 是否可读

-w 是否可写

-x 是否可执行

=====================

  • 4 为SUID
  • 2 为SGID
  • 1 为SBIT

-u 检测文件是否设置了SUID位

[root@localhost tmp]# chmod  6444 aa.txt
[root@localhost tmp]# ll aa.txt 
-r-Sr-Sr--. 1 root root 0 2月  11 06:44 aa.txt

 

-g 检测文件是否设置了 SGID 位

 

=====================

shell echo 命令

name=”huazai007”

echo –e “$name \n”

-e 开启转义

\n 换行

printf

%s 将参数按字面意思解释为字符串

字符是单个字符,而字符串包含一个或者多个字符

%c 字符

printf "%-10s\n"  huazai007

-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。

%f 将参数按浮点数打印

 

%-4.2 小数点后面保留两位小数 

左对齐看不出效果

shell 流程控制

#!/bin/bash

a=30

b=50

if [ $a == $b ]; then

      echo "a等于b"

elif [ $a -gt $b ]; then

      echo "a大于b"

elif [ $a -lt $b ]; then

      echo "a小于b"

else

      echo "没有符合的条件"

fi

 

#!/bin/bash

:<<EOF

for i in {1..100}

do

      echo $i

done

EOF

for i in `seq 1 100`

do

      echo $i

done

===========while=======

#!/bin/bash

int=0

while (($int<=5))

do

        echo $int

        #let "int++"

        let int=int+1

done

[root@master ~]# cat while_true.sh

#!/bin/bash

:<<EOF

while :

do

      echo "xx"

done

EOF

while true

do

      echo "oo"

done

[root@master ~]# cat  until.sh

#!/bin/bash

a=0

until [ $a -gt 10 ]

do

      echo $a

      a=`expr $a + 1`

done

[root@master ~]# cat case.sh

#!/bin/bash

echo "输入一个1到4之间的数字"

echo "你输入的数字为:"

read num

case $num in

      1)

      echo "1"

      ;;

      2)

      echo "2"

      ;;

      3)

      echo "3"

      ;;

      *)

      echo "你输入的数字有误!请重新输入"

      ;;

esac

break命令

break命令允许跳出所有循环(终止执行后面的所有循环)。下面的例子中,脚本进入死循环直至用户输入数字大于5。要跳出这个循环

continue

continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环

for i in `seq 10`
do
        if [ $i -eq 5 ]; then
                #continue
                break
        fi
        echo $i
done

 

int=0
while true
do
        let int++
        if [ $int -lt 10 ]; then
                echo $int
        else
                break
        fi
done

 

#!/bin/bash
for ((a=1;a<10;a++))
do
        echo "Outer loop: $a"
        for ((b=1;b<10;b++))
        do
                if [ $b -eq 4 ]
                then
                        #break 
                        #break 2
                        #continue
                        continue 2
                else
                        echo "Inner loop: $b"
                fi
        done
done

 continue N 将会把N层循环剩余代码都去掉

 

 

Shell编程中Shift的用法

 

位置参数可以用shift命令左移。比如shift 3表示原来的$4现在变成$1,原来的$5现在变成$2等等,原来的$1$2$3丢弃,$0不移动。

不带参数的shift命令相当于shift 1

当 Shell 程序不知道参数个数时,可以把所有参数一起赋值给变量$*。若用户要求 Shell 在不知道位置变量个数的情况下,还能逐个的把参数一一处理,也就是在 $1 后为 $2,在 $2 后面为 $3 等。在 shift 命令执行前变量 $1 的值在 shift 命令执行后就不可用了。

示例如下:

#测试 shift 命令(x_shift.sh)
until [ $# -eq 0 ]
do
echo "第一个参数为: $1 参数个数为: $#"
shift
done
执行以上程序x_shift.sh:
$./x_shift.sh 1 2 3 4

结果显示如下:

第一个参数为: 1 参数个数为: 4
第一个参数为: 2 参数个数为: 3
第一个参数为: 3 参数个数为: 2
第一个参数为: 4 参数个数为: 1

 


从上可知 shift 命令每执行一次,变量的个数($#)减一,而变量值提前一位,下面代码用 until 和 shift 命令计算所有命令行参数的和。

++++++++++++++++++++++++++++++++++++++

shell里的local

作用:一般用于shell内局部变量的定义,多使用在函数内部

关于局部变量和全局变量:
(1)shell 脚本中定义的变量是global的,作用域从被定义的地方开始,一直到shell结束或者被显示删除的地方为止。
(2)shell函数定义的变量也是global的,其作用域从 函数被调用执行变量的地方 开始,到shell或结束或者显示删除为止。函数定义的变量可以是local的,其作用域局限于函数内部。但是函数的参数是local的。
(3)如果局部变量和全局变量名字相同,那么在这个函数内部,会使用局部变量。

 

#!/bin/bash
func1(){
        local str
        str=$1
        echo "$str,func1"
}
func1 huazai
echo $str