• shell变量与运算


    shell变量与运算

    @(0003 shell编程)

    变量存在于内存中。假设变量str,设置或修改变量属性时,不带$号,只有引用变量的时才使用$号。也就是说在内存中,标记变量的变量名称是str,而不是$str。

    变量数据的存储方式本身是有类型之分的,分为数据(整数、浮点型)和字符,在java等一些语言中,需要提前声明变量是哪种类型。但是,在bash中变量比较宽松,不需要这么做。
    即,变量可以这么分为:

    • 强类型:变量不经过强制转换,它永远是这个数据类型,不允许隐式的类型转换。一般定义变量时必须指定类型、参与运算必须符合类型要求;调用未声明变量会产生错误。如java,c#
    • 弱类型:语言的运行时会隐式做数据类型转换。无须指定类型,默认均为字符型;参与运算会自动进行隐式类型转换;变量无须事先定义可直接调用。
      如:bash 不支持浮点数,php

    变量命名法则:
    1、不能使程序中的保留字:例如if, for
    2、只能使用数字、字母及下划线,且不能以数字开头
    3、见名知义
    4、统一命名规则:驼峰命名法

    驼峰命名法:将变量名首字母大写,可以全部单词的首字母大写,也可以部分单词的首字母大写,方便识别。如:StudentName。

    一、变量类型

    1.1 局部变量

    生效范围为当前shell进程;对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效。

    查看进程编号:

    echo $$     # 当前进程的进程编号
    
    echo $PPID  #父进程的进程编号
    
    也可以通过
    pstree -p  # 查看父子进程树
    
    

    如:NAME=songtai,这个变量只对当前的shell有用,子shell或父shell无法使用。退出当前shell用exit命令

    1、变量赋值:name=‘value’ 。
    注意:注意等号左右没有空格。如果有空格就是进行比较运算符的比较运算了。要想保留空格作为一个整体字符串,用“”括起来。如:STR=“test space”。

    注意:变量赋值也可以直接应用变量或命令:

    1.直接引用字符串:name=“root"
    2.变量:name="$USER"
    3.命令:name=`COMMAND` 或 name=$(COMMAND)

    2、变量引用::${name} 或$name
    如:

    [root@CentOS6 ~]#NAME="hello world"    
    
    [root@CentOS6 ~]#echo "we will say $NAME"   
    we will say hello world
    

    3、释放变量:unset name ,注意变量名前不加前缀$。
    一般赋值完一个变量后,如果后边不在使用该变量的话,直接释放该变量。

    4、查看所有的变量:不接任何参数的set或者declare命令,输出结果中包含了普通变量和环境变量。

    5、临时将普通变量升级为环境(全局)变量: export name 或者赋值时 export name="value" ,这样$name就可以在当前shell和子shell中使用,但是退出脚本或者重新登录shell都会取消export效果。

    6、定义只读变量: readonly name 。这时将无法修改变量值也无法unset变量,只有重新登录shell才能继续使用只读变量。

    1.2环境变量(全局变量)

    生效范围为当前shell进程及其子进程。常用大写字母
    env export printenv可以查看当前用户的环境变量。
    常见的环境变量:HOSTNAME、SHELL、HISTSIZE、USER、PATH、PWD、LANG、HOME、LOGNAME。

    变量声明、赋值:

    export  name=VALUE   
    declare  -x  name=VALUE
    

    注意:局部变量通过export升级为全局变量,并且对子shell产生影响,但是对父shell不产生影响,父shell仍是原来的赋值。

    set查看全部变量,包括局部变量、全局变量。

    1.3只读变量

    只能声明,但不能修改和删除
    声明只读变量:

    • readonly name
    • declare -r name

    查看只读变量:

    • readonly –p

    1.4 补充:()、{ }的用处

    ( list ):一次性执行执行(相当于开了个子进程bash,执行后又回到父进程

    [root@CentOS7 ~]#( umask 666;touch /data/f1 )   #相当于开了一个子shell,umask改为666后创建了一个文件f1,然后再返回到父shell
    [root@CentOS7 ~]#ll -d /data/f1
    ----------. 1 root root 0 Nov 29 14:49 /data/f1
    
    [root@CentOS7 ~]#( name=songtai;echo $name )
    songtai
    

    { list }:大括号直接作用于当前shell

    [root@CentOS7 ~]#name=songtai
    [root@CentOS7 ~]#(  name=sun;echo $name  )
    sun
    [root@CentOS7 ~]#echo $name
    songtai
    
    [root@CentOS7 ~]#{  name=sst;echo $name;  }    # 注意后边跟;号
    sst
    
    [root@CentOS7 ~]#x=1;echo $$;( echo $$;echo $x;x=2;echo $x );echo $x
    13196
    13196    # 注意;两个子进程号相同,说明()开的子进程与重新开个子shell还是有不同
    1
    2
    1
    

    1.5位置变量和特殊变量

    位置变量:在脚本代码中调用通过命令行传递给脚本的参数

    $?:上一条代码执行的回传指令,回传0表示标准输出,即正确执行,否则为标准错误输出。

    对于脚本中的回传指令是0还是其他,看脚本的最后一条命令,如果有标准输出就是0.否则是其他数值;注意语法错误与命令错误的区分。
    exit [n]:自定义退出状态码

    $$:当前shell的PID。除了执行bash命令和shell脚本时,$$不会继承父shell的值,其他类型的子shell都继承。

    $BASHPID:当前shell的PID,这和"$$"是不同的,因为每个shell的$BASHPID是独立的。而"$$"有时候会继承父shell的值。

    $!:最近一次执行的后台进程PID。

    $#:统计参数的个数。

    $@:所有单个参数,如"a""b""c""d"。

    $*:所有参数的整体,如“abcd”。

    $0:脚本名。 注意:对软链接,$0 显示的是软链接的名称

    $1……$n:参数位置。

    示例:

    vim  /bin/args.sh     # 编写脚本 /bin/args.sh   
    #!/bin/bash
    echo "1st arg is $1"
    echo "2st arg is $2"
    echo "3st arg is $3"
    echo "4st arg is $4"
    echo "all args is  $*"
    echo "all args is $@"
    echo "the args number is $#"
    echo "the script is `basename $0`"
    
    [root@CentOS7 ~]#args.sh   aaa nne  ewd  q
    1st arg is aaa
    2st arg is nne
    3st arg is ewd
    4st arg is q
    all args is  aaa nne ewd q
    all args is aaa nne ewd q
    the args numbers is 4
    the script is args.sh
    

    练习:写一脚本,通过命令传递两个文本文件路径给脚本,计算其空白行数之和;

    #!/bin/bash
    
    file1_lines=$(grep ^[[:space:]]$  $1 |wc -l)
    file2_lines=$(grep ^[[:space:]]$  $2 |wc -l)
    echo "the total blank lines: $[$file1_lines+$file2_lines]"
    
    

    shfit 换位置,默认换一个。
    示例:

    vim args.sh     # 编辑脚本
    #!/bin/bash
    echo "1st arg is $1"
    echo "2st arg is $2"
    echo "3st arg is $3"
    echo "4st arg is $4"
    echo "all args is  $*"
    echo "all args is $@"
    echo "the args numbers is $#"
    echo "the script is $0"
    shift
    
    echo "1st arg is $1"
    echo "2st arg is $2"
    echo "3st arg is $3"
    echo "4st arg is $4"
    echo "all args is  $*"
    echo "all args is $@"
    echo "the args numbers is $#"
    echo "the script is $0"
    shift
    
    echo "1st arg is $1"
    echo "2st arg is $2"
    echo "3st arg is $3"
    echo "4st arg is $4"
    echo "all args is  $*"
    echo "all args is $@"
    echo "the args numbers is $#"
    echo "the script is $0"
    shift                                      # 保存退出脚本
    
    
    [root@CentOS7 bin]#args.sh  a b c d       # 执行脚本args.sh  a b c d
    1st arg is a
    2st arg is b
    3st arg is c
    4st arg is d
    all args is  a b c d
    all args is a b c d
    the args numbers is 4          # 4个参数           
    the script is /root/bin/args.sh
    1st arg is b
    2st arg is c
    3st arg is d
    4st arg is 
    all args is  b c d
    all args is b c d
    the args numbers is 3         # 第一个参数去掉,后3个参数依次向前
    the script is /root/bin/args.sh
    1st arg is c
    2st arg is d
    3st arg is 
    4st arg is 
    all args is  c d
    all args is c d
    the args numbers is 2        # 依上一步的参数,第一个仍然去掉,后2个依次向前
    the script is /root/bin/args.sh
    

    注意:当参数达到10以上时,用 ${10} 表示第10个参数 ,否则系统会将10都城
    字符1和0的组合。

    实验:编写脚本/root/bin/sumid.sh,计算/etc/passwd文件中的第10个用户和第20用户的ID之和。

    #!/bin/bash
    UID1="`head -n$1 /etc/passwd | cut -d: -f3 |tail -n1`"
    UID2="`head -n$2 /etc/passwd | cut -d: -f3 |tail -n1`"
    sumid=$[$UID1+$UID2]
    echo $sumid
    

    此脚本有个问题,直接执行sumid.sh不跟参数的话会报错。改良如下:

    #!/bin/bash
    [ $# -ne 2 ] && echo "Args num must be 2" && exit   # 参数数量为2个,则接着运行后边的命令;参数数量不为2,则运行“Args num must be 2”,然后退出!
    UID1="`head -n$1 /etc/passwd | cut -d: -f3 |tail -n1`"
    UID2="`head -n$2 /etc/passwd | cut -d: -f3 |tail -n1`"
    sumid=$[$UID1+$UID2]
    echo $sumid
    

    继续改良:

    #!/bin/bash
    [ $# -ne 2 ] && echo "Args num must be 2" && exit
    [[ ! "$1" =~ ^[0-9]+$ ]] && echo "$1 is not digital" && exit
    [[ ! "$2" =~ ^[0-9]+$ ]] && echo "$2 is not digital" && exit
    UID1="`head -n$1 /etc/passwd | cut -d: -f3 |tail -n1`"
    UID2="`head -n$2 /etc/passwd | cut -d: -f3 |tail -n1`"
    sumid=$[$UID1+$UID2]
    echo $sumid
    

    1.6 条件选择if语句

    • 顺序执行:逐条运行;
    • 选择执行:
      • 代码有一个分支:条件满足时才会执行;
      • 两个或以上的分支:只会执行其中一个满足条件的分支;
    • 循环执行:
      代码片断(循环体)要执行0、1或多个来回;
    选择执行:
    # 单分支的if语句:
    if  测试条件;then
    	条件为真时分支代码
    fi
    
    # 双分支的if语句:
    if 判断条件; then
    	条件为真的分支代码
    else
    	条件为假的分支代码
    fi
    
    示例:通过参数传递一个用户名给脚本,此用户不存时,则添加之;
    #!/bin/bash
    if [ $# -lt 1 ] ;then
    	ehco "at lease one username"
    fi
    
    if id $1 &>/dev/dull ;then
    	echo "user $1 exits"
    else
    	useradd $1
    	echo $1 | passwd  --stdin $1  &>/dev/dell
    	echo "user $1 was finished"
    fi
    
    

    二、运算

    2.1算术预算

    bash中的算术运算:help、let
    +, -,*, /, %取模(取余), **(乘方)

    实现算术运算:
    (1) let var=算术表达式

    x=10
    y=20
    let z=x+y  或  let z=$x+$y
    echo  $z
    30
    
    let x++
    echo $x  
    11
    
    let ++x
    echo $x
    12
    

    (2) var=$[算术表达式]

    n=8
    m=5
    sum=$[n+m]   或   sum=$[$n+$m]
    echo $sum
    13 
    

    (3) var=$((算术表达式))

    (4) var=$(expr arg1 arg2 arg3 ...)
    注意:
    expr 1 + 2 字符之间有空格
    expr 1 * 2 *需要转义符

    (5) declare –i var = 数值

    declare -i x=10
    declare -i y=20
    echo -i z=x+y
    echo $z
    30
    

    (6) echo ‘算术表达式’ | bc

    注意:乘法符号有些场景中需要转义

    (7)bash有内建的随机数生成器:$RANDOM(0-32767)
    echo $[$RANDOM%50] :0-49之间随机数
    示例:

    COLOR=$[RANDOM%7+31]  或  COLOR=$((RANDOM%7+31)) 
    echo $COLOR  一直是一个数值,除非再执行一次上一条命令,就会换一个数值????
    echo -e "e[1;${COLOR}mcolore[0m"
    

    COLOR="$[RANDOM%7+31]";echo -e "e[1;${COLOR}mcolore[0m" color随机变色

    (8) 赋值
    增强型赋值:+=, -=, *=, /=, %=
    例如:
    let x+=2 表示为x+2后自赋值

    自增,自减:
    let var+=1
    let var++ x+1后自赋值
    let var-=1
    let var--

    2.2 逻辑运算

    1.真假表示
    true : 1
    false :0

    非:!
    !0=1
    !1=0

    2.&、| 运算

    &: and,与运算;有一个假就全假,全是真才为真
    0 & 0 = 0
    0 & 1 = 0
    1 & 0 = 0
    1 & 1 = 1

    | : or,或运算;全是假才是假,有一个真就是真
    0 | 0 = 0
    0 | 1 = 1
    1 | 0 = 1
    1 | 1 = 1

    3.&& 短路与;|| 短路或

    && 短路与
    0 && 0 = 0
    0 && 1 = 0
    1 && 0 = 0
    1 && 1 = 1

    cmd1 && cmd2 :

    • cmd1若为假,那么cmd2就不需要执行,因为最终结果都为假
    • cmd1若为真,那么cmd2需要执行,才能判断最终结果。

    || 短路或
    0 || 0 = 0
    0 || 1 = 1
    1 || 0 = 1
    1 || 1 = 1

    cmd1 || cmd2 :

    • cmd1若为假,那么cmd2需要执行,才能判断最终结果。
    • cmd1若为真,那么cmd2不需要执行,因为最终结果都为真。

    cmd1 && cmd2 || cmd3
    cmd1为假,那么cmd1&&cmd2 的结果必为假,所以需要执行cmd3,才能判断最终结果。
    cmd1为真,那么要执行cmd2,才能判断cmd1 && cmd2的结果,若cmd2为真,不执行cmd3,若cmd2为假,执行cmd3.
    x=haha;y=xixi;[ $x = $y ] && echo equal || echo qual
    cmd1 || { cmd2 ; cmd3; } cmd1为假时,运行cmd2和cmd3

    ^ XOR,抑或:
    1 ^ 0 = 1
    1 ^ 1 = 0
    0 ^ 1 = 1
    0 ^ 0 = 0
    ^异或的两个值,相同为假,不同为真
    ^ 的应用示例:两个数互换

    a=4     # 4二进制表示为 100
    b=6    #  6二进制表示为 110
    let c=a^b
    echo  $c
    1
    
    a、b的值互换示例:
    a=4
    b=6
    a=$[a^b];b=$[a^b];a=[a^b];echo $a $b    # 第一个分号左侧a为a^b的值;第二个分号左侧b为第一个a的值与b抑或为4(a);第三个分号的[]中,a为a^b的值,b为4,所以左侧的a为6(b)。
    6 4
    

    2.3 test

    • test EXPRESSION
    • [ EXPRESSION ]
    • [[ EXPRESSION ]]
      注意:EXPRESSION前后必须有空白字符

    (1)比较字符串

    option:
    -z STRING True if string is empty.空为真,不空为假

    -n STRING True if string is not empty.

    STRING1 == STRING2 True if the strings are equal.

    STRING1 != STRING2 True if the strings are not equal. 不等于

    STRING1 < STRING2 True if STRING1 sorts before STRING2 lexicographically. ascii码是否小于ascii码

    STRING1 > STRING2 True if STRING1 sorts after STRING2 lexicographically.

    STRING1 =~ STRING2 左侧字符串是否能够被右侧的PATTERN所匹配,PATTERN可使用扩展正则表达式

    注意: 字符串比较尽量用于[[ ]]中;扩展的正则表达式;字符串尽量加引号引用

    str1=aaa
    str2=bbb
    test $str1  $str2
    echo $?
    1
    注意:
    test $str1  $str2
    [ $str1 = str2 ]
    [[ str1 = str2 ]]    #这个三个表达式的效果相同,注意第二个与第三个里面的空格!
    

    实验:判断一个字符串是否为空的字符串:

    [ -z string ]
    [ x"$string" =  "x" ]
    [ $string =   ]
    

    (2)比较数字

    -eq equal,相等
    -ne not equal,不想等
    -lt less than,小于
    -le less equal,小于等于
    -gt graeter than 大于
    -ge greater equal 大于等于

    实验:写脚本,磁盘利用率大于80报警;

    #!/bin/bash
    DF_USER="`df | grep  "dev/sd" | tr -s " " % | cut -d% -f5 |sort -nr | head -n1`"
    [ "$DF_USER" -ge 80 ] && echo warmming!!   # 注意:[] 内的变量要用“”引起来!!
    

    (3) 文件比较

    存在性测试:
    -a FILE : True if file exists.
    -e FILE : True if file exists.

    是否存在及类型测试:
    -b FILE : True if file is block special.
    -c FILE : True if file is character special.
    -d FILE : True if file is a directory.
    -f FILE : True if file exists and is a regular file.
    -p FILE : True if file is a named pipe.
    -h FILE : True if file is a symbolic link.
    -L FILE : True if file is a symbolic link.
    -S FILE : True if file is a socket.

    文件权限测试:
    -r FILE : True if file is readable by you.
    -w FILE : True if the file is writable by you. 是否有写权限
    -x FILE : True if the file is executable by you.

    特殊权限测试:
    -u FILE:是否存在并且 拥有suid权限
    -g FILE:是否存在并且 拥有sgid权限;
    -k FILE:是否存在并且 拥有sticky权限;

    文件是否有内容:
    -s FILE : True if file exists and is not empty.

    时间戳:
    -N FILE:文件自从上一次读操作后是否被修改过;

    从属关系测试:
    -O FILE:True if the file is effectively owned by you.当前用户是否为文件的属主;
    -G FILE:rue if the file is effectively owned by your group.当前用户是否属于文件的属组;

    双目测试:
    FILE1 -ef FILE2:True if file1 is a hard link to file2;FILE1与FILE2是否指向同一个文件系统的相同inode的硬链接;
    FILE1 -nt FILE2:True if file1 is newer than file2 (according to modification date);FILE1是否新于FILE2;
    FILE1 -ot FILE2: True if file1 is older than file2;FILE1是否旧于FILE2;

    是否被打开:
    -t FD: True if FD is opened on a terminal.文件描述符是否在某终端已经打开

    实验:创建用户,如果该用户存在则不创建,如果不存在创建之,并将“magedu”作为其密码。

    #1/bin/bash
    [ $# -ne 1 ] &&  echo "your args is wrong" && exit
    id $1 &> /dev/null && echo "$1 is exist" && exit  || useradd $1 && echo "magedu" | passwd --stdin  $1
    

    #!/bin/bash
    id $1 &> /dev/null
    [ $? -eq 0 ] && echo "$1 is exist" && exit
    useradd $1 && echo magedu | passwd --stdin $1
    

    (4) bash的组合测试文件
    第一种方式:
    COMMAND1 && COMMAND2 并且
    COMMAND1 || COMMAND2 或者
    ! COMMAND 非
    如:[[ -r FILE ]] && [[ -w FILE ]]

    第二种方式:
    EXPRESSION1 -a EXPRESSION2 并且
    EXPRESSION1 -o EXPRESSION2 或者
    ! EXPRESSION
    必须使用测试命令进行
    示例:

    [ -z “$HOSTNAME” -o $HOSTNAME "=="localhost.localdomain" ] && hostname www.magedu.com
    [ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab
    

    补充:脚本的状态返回值:

    • 默认是脚本中执行的最后一条件命令的状态返回值;
    • 自定义状态退出状态码:
      exit [n]:n为自己指定的状态码;

    注意:shell进程遇到exit时,即会终止,因此,整个脚本执行即为结束;

    三、read

    使用read来把输入值分配给一个或多个shell变量

    -p 指定要显示的提示
    -s 静默输入,一般用于密码
    -n N 指定输入的字符长度N
    -d ‘字符’ 输入结束符
    -t N TIMEOUT为N秒

    echo a b c > file1 
    read x y z <file1
    echo $x
    a
    echo $y
    b
    echo $z
    c
    也可以
    read x y z <<<  "i j k"
    
    #!/bin/bash
    read -p  "please input your name: " name
    echo your name is $name
    
    #!/bin/bash
    read -p  "please input your name: " name
    read -s -p "please input your passwd: " passwd
    echo your name is $name
    echo your passwd is $passwd
    

    实验:鸡兔同笼;输入总的头数和总的脚数,算出鸡、兔分别有几只。

    #!/bin/bash
    read -p "please input heads num: " H
    read -p "please input feets num: " F
    C=$[(4*H-F)/2]
    R=$[(F-2*H)/2]
    echo "the chicken num is $C"
    echo "the rabbir num is $R"
    

    四、$- 变量

    echo $-
    himBH
    

    h:hashall,打开这个选项后,Shell 会将命令所在的路径hash下来,避免每次都要查询。通过set +h将h选项关闭
    i:interactive-comments,包含这个选项说明当前的 shell 是一个交互式的 shell。所谓的交互式shell,在脚本中,i选项是关闭的。
    m:monitor,打开监控模式,就可以通过Job control来控制进程的停止、继续,后台或者前台执行等。
    B:braceexpand,大括号扩展
    H:history,H选项打开,可以展开历史列表中的命令,可以通过!感叹号来完成,例如“!!”返回上最近的一个历史命令,“!n”返回第 n 个历史命令

    五、练习题

    1、编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小

    #!/bin/bash
    echo -e "e[1;35mThis computer is hosted by: e[0m"
    hostname
    echo "    "
    echo -e  "e[1;35mMy ip addr is:e[0m"
    ifconfig  | sed -n '2p'|sed -r  's@.*inet (.*) net.*@1@'
    echo "     "
    #
    echo -e  "e[1;35mMy OS version is:e[0m"
    cat /etc/centos-release
    
    echo "  "
    
    
    echo -e "e[1;35mMy CPU is: e[0m"
    lscpu
    
    echo "   "
    
    echo -e "e[1;35mMy memory is: e[0m"
    free -m
    echo " "
    
    echo -e "e[1;35mMy disk is: e[0m"
    lsblk | sed -n  '2p'
    

    2、编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到/root/etcYYYY-mm-dd中

    #!/bin/bash
    echo -e "e[1;35mbackup ing.... e[0m"
    sleep 3
    cp -av  /etc/  /data/etc`date +%F`
    echo -e  "e[1;35mbackup is done e[0m"
    

    3、编写脚本/root/bin/disk.sh,显示当前硬盘分区中空间利用率最大的值

    #!/bin/bash
    echo -e "e[1;35mThe biggst ratio of your disk's space is e[0m"
    df | grep "/dev/sd"  | tr -s " " %   | cut -d% -f5 | sort -nr |   head -n1
    
    

    4、编写脚本/root/bin/links.sh,显示正连接本主机的每个远程主机的IPv4地址和连接数,并按连接数从大到小排序



    5、编写脚本/root/bin/sumid.sh,计算/etc/passwd文件中的第10个用户和第20用户的ID之和

    
    #!/bin/bash
    [ $# -ne 2 ] && echo "Args num must be 2" && exit
    [[ ! "$1" =~ ^[0-9]+$ ]] && echo "$1 is not digital" && exit
    [[ ! "$2" =~ ^[0-9]+$ ]] && echo "$2 is not digital" && exit
    UID1="`head -n$1 /etc/passwd | cut -d: -f3 |tail -n1`"
    UID2="`head -n$2 /etc/passwd | cut -d: -f3 |tail -n1`"
    sumid=$[$UID1+$UID2]
    echo $sumid
    

    6、编写脚本/root/bin/sumspace.sh,传递两个文件路径作为参数给脚本,计算这两个文件中所有空白行之和

    #!/bin/bash
    echo -e "e[1;35mThe files's blankline is : e[0m"
    grep ^$ $1 $2 | wc -l
    

    7、编写脚本/root/bin/sumfile.sh,统计/etc, /var, /usr目录中共有多少个一级子目录和文件

    #!/bin/bash
    echo -e "e[1;35mThe number of /etc /var /usr is : e[0m"
    a="`find /etc -maxdepth 1 |wc -l`"
    b="`find /usr -maxdepth 1 |wc -l`"
    c="`find /var -maxdepth 1 |wc -l`"
    sum=$[a+b+c]
    echo $sum
    


    8、编写脚本/root/bin/argsnum.sh,接受一个文件路径作为参数;如果参数个数小于1,则提示用户“至少应该给一个参数”,并立即退出;如果参数个数不小于1,则显示第一个参数所指向的文件中的空白行数

    #!/bin/bash
    [ $# -lt 1 ] && echo -e "e[1;33m至少应该有一个参数 e[0m"  && exit
    [ $# -ge 1 ] && grep ^$ $1 $2 $3 |wc -l
    

    9、编写脚本/root/bin/hostping.sh,接受一个主机的IPv4地址做为参数,测试是否可连通。如果能ping通,则提示用户“该IP地址可访问”;如果不可ping通,则提示用户“该IP地址不可访问”

    10、编写脚本/root/bin/checkdisk.sh,检查磁盘分区空间和inode使用率,如果超过80%,就发广播警告空间将满

    #!/bin/bash
    a="`df | grep "/dev/sd.*" | tr -s " " % |cut -d% -f5 | sort -nr | head -n1`"
    b="`df -i | grep "/dev/sd.*" | tr -s " " % |cut -d% -f5 | sort -nr | head -n1`"
    [ $a -ge 80 ] && echo -e "e[1;35mYour disk space is warmming!! e[0m"
    [ $b -ge 80 ] && echo -e "e[1;35mYour inode numbers is warmming!! e[0m"
    


    11、编写脚本/bin/per.sh,判断当前用户对指定的参数文件,是否不可读并且不可写

    #!/bin/bash
    [ -r $1 -a -w $1 ] ||  echo -e "e[1;35m您对此文件无读写权限 e[0m"
    

    12、编写脚本/root/bin/excute.sh ,判断参数文件是否为sh后缀的普通文件,如果是,添加所有人可执行权限,否则提示用户非脚本文件

    #!/bin/bash
    [[ $1 =~  .sh$   ]] && [[ -f $1 ]] || { echo -e "e[1;35m该文件非脚本文件 e[0m" ; exit;  }
    chmod +x $1
    echo -e "e[1;35m该文件已添加X权限 e[0m"
    

    13、编写脚本/root/bin/nologin.sh和login.sh,实现禁止和充许普通用户登录系统
    nologin.sh

    #!/bin/bash
    echo -e "e[1;35mYOU WILL OPEN NOLOGIN,PLEASE WAIT e[0m"
    [ -a /etc/nologin ] && exit  || touch /etc/nologin
    echo -e "e[1;35mdone!!!e[0m"
    

    login.sh

    #!/bin/bash
    [ -e /etc/nologin ] && `rm -f /etc/nologin` || echo -e "e[1;35mnow,you can login e[0m"
    

    14.通过命令行参数给定两个数字,输出其中较大的数值;

    #!/bin/bash
    # which num is the max of two
    if [ $# -ne 2 ] ;then
        echo "please input two num"
        exit
    fi
    
    if [ $1 -gt $2 ] ;then
        echo "the max num is $1"
    else
        echo "the max num is $2"
    fi
    
    
    # 或者
    
    #!/bin/bash
    if [ $# -lt 2 ]; then
    	echo "Two integers."
    	exit 2
    fi
    
    declare -i max=$1
    
    if [ $1 -lt $2 ]; then
    	max=$2
    fi
    
    echo "Max number: $max."
    

    15.通过命令行参数给定一个用户名,判断其ID号是偶数还是奇数;

    #!/bin/bash
    if [ $# -ne 1 ] ;then
        echo "please input one args"
        exit
    fi
    
    if ! id $1 &>/dev/dull ;then
        useradd $1
    fi
    
    idnum=$(id -u $1)
    idnum_yu=$[idnum%2]
    
    if [ "$idnum_yu" -eq 1 ];then
        echo "用户$1的id是奇数"
    else
        echo "用户$1的id是偶数"
    fi
    

    16.通过命令行参数给定两个文本文件名,如果某文件不存在,则结束脚本执行;都存在时返回每个文件的行数,并说明其中行数较多的文件;

    #!/bin/bash
    #
    if [ $# -ne 2 ] ;then
        echo "please input two fileadd"
        exit
    fi
    
    if [ -a $1 -a -a $2 ];then
        echo "the two files are exits "
    else
        echo "the file $1 or $2 is not exits;please input again"
        exit
    fi
    
    file1_lines=$(cat $1 |wc -l)
    file2_lines=$(cat $2 |wc -l)
    
    if [ "$file1_lines" -gt "$file2_lines" ];then
        echo "the $1's lines is more then $2"
    else
        echo "the $2's lines is more then $1"
    fi
    
    
  • 相关阅读:
    SharePoint 2010 Managed Metadata Columns and Metadata Navigation Settings
    SharePoint 知识整理1
    印度HCL揭秘云计算五大盈利模式
    云计算盈利模式都有什么?
    IaaS
    Salesforce
    走近云计算:解密IaaS PaaS SaaS的关系
    sasdas
    解析salesforce
    Salesforce成功的秘密
  • 原文地址:https://www.cnblogs.com/sstjustdoit/p/10043486.html
Copyright © 2020-2023  润新知