zoukankan      html  css  js  c++  java
  • Linux04 shell编程1

    编程语言

    shell编程:
    	编译器或者解释器
    编程语言:机器语言、汇编语言、高级语言
    
    静态语言:编译型语言
    	强类型(变量):变量在使用前,必须事先声明,甚至还需要初始化;
    	在执行之前就需要完全转换成可执行格式,然后在执行。
    	C、C++、JAVA、C#
    
    动态语言:解释性语言
    	弱类型语言(通常):变量用时声明,甚至不区分类型;
    	边解释边执行(运行过程中,转换一条,执行一条)
    	asp.net、PHP、SHELL、Python、perl
    
    面向过程:Shell,C
    面向对象:Java,Python,Perl(既有面向过程,也有面向对象),C++(面向对象)
    
    变量:内存空间,命名
    内存:编址的存储单元
    进程:
    
    变量类型:事先确定数据的存储格式和长度
    	字符
    	数值
    		整型
    		浮点型
    
    bash变量类型:
    	环境变量
    	本地变量(局部变量)
    	位置变量
    	特殊变量
    	
    1. 本地变量:
    	VARNAME=VALUE:作用域为整个bash进程;
    	
    2. 局部变量:
    	local VARNAME=VALUE:作用域为当前代码段;
    
    3. 环境变量:作用域为当前shell进程及其子进程;
    	export VARNAME=VALUE
    	VARNAME=VALUE
    	export VARNAME
    	
    4. 位置变量:
    	$1,$2,...
    	shift:当引用一个参数之后,我们可以使用shift将已引用的参数踢出,让其他参数依次向前补1个位置
    	shift n :一次踢掉n个参数
    5. 特殊变量:
    	$?:保存上一个命令的执行状态返回值;
        程序执行,可能有两类返回值:
            程序执行结果
            程序状态返回代码 (0~255):
                0:正确执行
                1-255:错误执行(1,2,127系统预留的)
    
    	$#:执行脚本时,向脚本内部携带的参数的个数
    	$*:参数列表
    	$@:参数列表
    
    
    设置变量:
    	set VARNAME=VALUE  # set可以省略
    撤销变量:
    	unset VARNAME
    查看当前shell中所有变量(包括本地变量):
    	set
    查看当前shell中的环境变量:
    	printenv
    	env
    	export
    
    脚本:命令的堆砌,按实际需要,结合命令流程控制机制是心啊的源程序;
    
    shebang:魔数,
    	#!/bin/bash
    	# 注释行,不执行
    
    /dev/null:软件设备,bit bucket,数据黑洞
    
    脚本在执行时会启动一个子shell进程:
    	命令行中启动的脚本会继承当前shell环境变量;
    	系统自动执行的脚本(非命令行启动)就需要自我定义需要的各种环境变量
    
    	
    引用变量:$(VARNAME),括号又是可以省略(变量后面没有紧跟字符,可省略)
    
    编程能力:
    	脚本编程
    

    "":弱引用,如果内部有变量替换,使用双引号;
    '':强引用,如果内部有变量不会做替换
    

    程序执行返回的状态:

    撤销变量:

    bash之条件判断

    1. bash中如何事先条件判断?
    	整数测试
    	字符测试
    	文件测试
    
    2. 条件测试的表达式(数字=值比较):
    	[ expression ]  # [ $INT1 -eq $INT2 ]
    	[[ expression ]] # 与单括号作用相同,但是双中括号是bash的   [[ $INT1 -eq $INT2 ]]
    	test expression  # test $INT1 -eq $INT2
    	
    	if [ grep "^$USERNAME>" /etc/passwd ];then # 错误的书写方式
    	if grep "^$USERNAME>" /etc/passwd;then  # 正确的书写方式
    																	
    3. 命令间的逻辑关系:
    	逻辑与:&&
    		第一个条件为假时,第二个条件不用判断,最终结果已经显现,第二个条件就不会执行;
    	逻辑或:||
    		第一个条件为真时,第二个条件得判断;
    
    4. 变量命名:
    	1.只能包含字母、数字和下划线,并且不能以数字开头;
    	2.不应该与已有的系统变量重名;
    	3. 最好做到见名知义;
    
    5. shell中如何进行算输运算:
    	A=3
    	B=6
    	1. let 算术运算表达式
    		let C=$A+$B
    	2. $[算术运算表达式]
    		C=$[$A+$B]
    	3. $((算术运算表达式))
    		C=$(($A+$B))
    	4. expr 算术运算表达式 # 表达式中各操作数及运算符之间要有空格,而且要使用命令引用
    		C=`expr $A + $B`
    	5. 
    	
    	如果:C=$A+$B   echo $C  结果是 3+6
        此时我们可以使用 let C=$A+$B   echo $C  结果是 9
    
    如果用户user6不存在,就添加用户user6:
       方式一: ! id user6 && useradd user6
       方式二: id user6 || useradd user6
    
    如果/etc/inittab文件的行数大于100,就显示大文件;
    	[ `wc -l /etc/inittab | cut -d' ' -f1` -gt 100 ] && echo "big file!"
    
    如果用户存在,就显示用户已存在;否则就添加此用户;
    	id user1 && echo "user1 exists." || useradd user1
    如果用户不存在,就添加;否则,就显示其已经存在;
    	! id user1 && useradd user1 || echo "user1 exists."
    如果用户不存在,添加并且给密码;否则,显示其已经存在;
    	! id user1 &> /dev/null && useradd user1 && echo "user1" | passwd --stdin user1 &> /dev/null || echo "user1 exists"
    

    整数测试

    整数比较:
    	-eq : 测试两个整数是否相等; 比如 $A -eq $B 
    	-ne: 测试两个整数是否不等; 不等,为真;相等,为假;
    	-gt: 测试一个属是否大于另一个数; 大于,为真;否则,为假;
    	-lt: 测试一个属是否小于另一个数; 小于,为真;否则,为假;
    	-ge: 大于或等于;
    	-le: 小于或等于;
    

    字符测试

    字符测试:
    ==:测试是否相等,相等为真,不等为假
    !=:测试是否不等,不等为真,等为假
    >:判断一个字符串是否大于另一个字符串
    <:
    -n string:测试指定的那个字符串是否为空,空则真,不空则假
    -z string:测试指定字符串是否不空,不空为真,空则假
    

    组合测试条件

    组合测试条件:
    	-a: 与关系
    	-o: 或关系
    	 !: 非关系
    if [ $# -gt 1 -a $# -le 3 ]  # -a 表示所有条件都要成立
    if [ $# -gt 1 ] && [ $# -le 3 ] # 和上面这个条件等价
    
    let i+=1 相当于 i++ 相当于 let i=i+1
    let i-=1 相当于 i-- 相当于 let i=i-1
    ++i,--i
    *=
    /=
    %=
    
    
    
    #!/bin/bash
    #
    if [ $1 == 'q' -o $1 == 'Q' -o $1 == 'quit' -o $1 == 'Quit' ];then
      echo "Quiting..."
      exit 0
    else
      echo "Unknown Argument"
      exit 1
    fi
    

    小练习:

    1. 添加5个用户,user1,...,user5;每个用户的密码同用户名,而且要求,添加密码完成后不显示passwd命令的执行结果信息;每个用户添加完成后,都要显示用户某某已经成功添加;
    2. 使用一个变量保存一个用户名;删除此变量中的用户,且一并删除其家目录;显示“用户删除完成”类的信息;
    
    1. 添加3个用户user1,user2,user3:但要先判断用户是否存在,不存在而后添加;添加完成后,显示一共添加了几个用户;当然,不能包括因为事先存在而没有添加的;最后显示当前系统上共有多少个用户;
    # createuser.sh
    
    #!/bin/bash
    ! id user1 &> /dev/null && useradd user1 && echo "user1" | passwd --stdin user1 &> /dev/null || echo "user1 exists."
    ! id user2 &> /dev/null && useradd user2 && echo "user2" | passwd --stdin user2 &> /dev/null || echo "user2 exists."
    ! id user3 &> /dev/null && useradd user3 && echo "user3" | passwd --stdin user3 &> /dev/null || echo "user3 exists."
    
    USER_COUNT=`wc -l /etc/passwd | cut -d' ' -f1`
    echo "$USER_COUNT users"
    
    1. 给定一个用户:如果其UID为0,就显示此为管理员;否则,就显示为普通用户;
    # is_admin.sh
    #!/bin/bash
    NAME=user1
    USER_ID=`id -u $NAME`
    
    

    文件测试

    -e FILE: 测试文件是否存在
    -f FILE: 测试文件是否为普通文件
    -d FILE: 测试指定路径是否为目录
    -r FILE: 测试指定文件对当前用户来讲是否可读
    -w FILE: 测试指定文件对当前用户来讲是否可写
    -x FILE: 测试指定文件对当前用户来讲是否可执行
    
    [ -e /etc/inittab ]
    [ -x /etc/rc.d/rc.sysinit ]
    
    
    bash -n 文件名(.sh) # 测试脚本是否有语法错误
    bash -x 脚本:# 单步执行,并显示要执行的命令和执行这个命令的结果。
    
    
    

    #!/bin/bash
    #
    FILE=/etc/inittab
    if [ ! -e $FILE ];then
    	echo "No such $FILE ."
    	exit 8
    fi
    
    if grep "^$" $FILE &> /dev/null;then
    	echo "Total blank lines: `grep "^$" $FILE | wc -l`."
    else
    	echo "No blank line."
    fi
    

    给定一个文件:如果是一个普通文件,就显示之;如果是一个目录,亦显示之;否则,此为无法识别文件;

    # is_file.sh文件   ./is_file.sh 参数
    
    #!/bin/bash
    # 
    if [ $# -lt 1 ];then
    	echo "Usage ./filetest3.sh ARG1 [ARG2...]."
    	exit 7
    if [ ! -e $1 ];then
    	echo "No such file."
    	exit 6
    fi
    
    if [ -f $1 ];then
    	echo "Common file."
    elif [ -d $1 ];then
    	echo "Directory."
    else
    	echo "Unkown."
    fi
    

    给脚本传递两个参数(整数);显示此两者之和,之乘积;

    #!/bin/bash
    # 
    if [ $# -lt 2 ];then
    	echo "Usage:cacl.sh ARG1 ARG2"
    	exit 8
    fi
    
    echo "The sum is:$[$1+$2],The multiply is $[$1*$2]"
    

    条件判断

    条件判断,控制结构:
    
    单分支的if语句:
    
    	if 判断条件;then
    		statement1
    		statement2
    		...
    	fi
    	
    	
    双分支的if语句:
    
    	if 判断条件;then
    		statement1
    		statement2
    		...
        else
            statement1
            statement2
            ...
    	fi
    
    多分支的if语句:
    	if 判断条件1;then
    		statement1
    		...
    	elif 判断条件2;then
    		statement2
    		...
    	elif 判断条件3;then
    		statement3
    		...
    	else
    		statement4
    	fi
    
    		
    
    # createuser.sh
    
    #!/bin/bash
    NAME=user1111
    
    if id $NAME &> /dev/null;then
    	echo "$NAME exist."
    else
    	useradd $NAME
    	echo $NAME | passwd --stdin $NAME &> /dev/null
    	echo "Add $NAME finished."	
    fi
    
    # is_admin.sh
    
    #!/bin/bash
    
    NAME=user17
    USERID=`id -u $NAME`
    if [ $USERID -eq 0 ];then
    # if [`id -u $NAME` -eq 0 ];then
    	echo "Admin."
    else
    	echo "common user."
    fi
    
    # bash_user.sh
    
    #!/bin/bash
    #
    grep "/<bash$" /etc/passwd &> /dev/null
    RETVAL=$?
    if [ $RETVAL -eq 0 ];then
    	USERS=`grep "<bash$" /etc/passwd | wc -l`
    	echo "The shells of $USERS users is bash."
    else
    	echo "No such user."
    fi
    
    
    
    # display_one_bash_user.sh 
    
    #!/bin/bash
    #
    grep "/<bash$" /etc/passwd &> /dev/null
    RETVAL=$?
    if [ $RETVAL -eq 0 ];then
    	AUSERS=`grep "<bash$" /etc/passwd | head -1 | cut -d: -f1`
    	echo "$AUSERS is one of such users."
    else
    	echo "No such user."
    fi
    

    给定一个文件,比如: /etc/inittab 判断这个文件中是否有空白行;如果有,则显示其空白行数;否则,显示没有空白行;

    #!/bin/bash
    #
    NOT_WORD_LINE=`grep "^$" /etc/inittab | wc -l`
    if [ $NOT_WORD_LINE -nq 0 ];then
    	echo " Not word line is $NOT_WORD_LINE ."
    else
    	echo "Not word line is $NOT_WORD_LINE"
    fi
    
    

    给定一个用户,判断其UID与GID是否一样;如果一样,就显示此用户为“good guy.”;否则,就显示此用户为“bad guy.”。

    #!/bin/bash
    #
    USER=user1
    USERID= `id -u $USER`
    GROUPID=`id -g $USER`
    if [ $USERID -eq $GROUPID ];then
    	echo "$USER is good guy."
    else
    	echo "$USER is bad guy."
    fi
    
    
    #!/bin/bash
    #
    USER=user1
    USERID= `grep "^$USER" /etc/passwd | cut -d: -f3`
    GROUPID=`grep "^$USER" /etc/passwd | cut -d: -f4`
    if [ $USERID -eq $GROUPID ];then
    	echo "$USER is good guy."
    else
    	echo "$USER is bad guy."
    fi
    

    给定一个用户,获取其密码警告期限;而后判断用户最近一次修改密码时间距今天是否已经小于警告期限;
    提示:算数运算的方法 $[ $A-$B ] ; 表示变量A的值减去变量B的值的结果;
    如果小于,则显示“Warning”;否则,就显示“OK”

    #!/bin/bash
    W=grep "user1" /etc/shadow | cut -d:-f6
    S=`date +%s`
    T= `expr $S/86400`
    L=`grep "user1" /etc/shadow | cut -d: -f5`
    N=`grep "user1" /etc/shadow | cut -d: -f3`
    SY=$[$L-$[$T-$N]]
    
    if [ $SY -lt $W ];then
    	echo "Warning."
    else
    	echo "OK."
    fi
    

    判定命令历史中历史命令的总条目是否大于1000;如果大于,则显示“Some command will gone.”;否则显示“OK.”。

    #!/bin/bash
    #
    HIS_COUNT="history | tail -1 | cut -d' ' -f3"  # history 的每行命令的数字行数前都有空格,所以不是-f1
    if [ HIS_COUNT -gt 1000 ];then
    	echo "Some command will gone."
    else
    	echo "OK."
    fi
    

    exit:退出脚本

    exit $
    
    #!/bin/bash
    #
    USERNAME=user1
    if ! grep "^$USERNAME>" /etc/passwd &> /etc/null;then
    	echo "No such user: $USERNAME."
    	exit 1
    fi
     
    '''
    如果脚本没有明确定义退出状态码,那么,最后执行的一条命令的退出码即为脚本的退出状态码。
    '''
    
  • 相关阅读:
    Linux下安装JDK
    Flink源码阅读(五)——Flink中任务相关的核心类简析
    使用CloudFlare Worker 来免费部署 JSProxy 服务
    Nginx:进程调度
    Javassist基本用法汇总
    IO
    IO
    springcloud3(五) spring cloud gateway动态路由的四类实现方式
    架构设计(二) 互联网网关平台对比
    Python 的协程
  • 原文地址:https://www.cnblogs.com/zhangchaocoming/p/14551724.html
Copyright © 2011-2022 走看看