linux学习笔记四(shell编程)
前言:最近在学习shell编程,shell编程是一个很强大的编程语言。
目的:方便今后复习。
内容:1.简单的回顾一下编程语言
1)编程语言:机器语言,汇编语言,高级语言。
2)编程语言有静态和动态的区分。
区别:静态语言是一种编译性的语言,要提前知道变量的格式,进过完整的编译之后才能运行,典型的静态语言包括:C、C++、JAVA、C#。
动态的编程语言是一种解释性的语言,是通过一边解释一边执行的方式,变量不需要提前指定格式,而是使用的时候就分配变量的空间,典型的解释性的语言有PHP、SHELL、PYTHON、perl。
3)面向过程的语言有C、Shell
面向对象的语言有:JAVA、Python、Perl、C++
4)浮点型的存储方式。
2.shell编程注意事项说明:
1)shell弱类型的编程语言,在编程时变量的说明不需要进行类型的定义
例如:VAR_NAME=VALUE直接使用VAR_NAME
2)bash变量的类型主要由一下的四种:
环境变量:可以在所有的用户进程中使用。登录进程是父进程,shell进程是子进程。父进程初始化环境变量,子进程就都可以使用了。对应的声明文件是:/etc/profile 、~/wuxiangdong/.bash_profile
变量的声明方式,export JAVA_HOME=‘/usr/local/jdk7‘
本地变量(局部变量) :作用域在一个shell,关闭终端,再开启一个,原来声明的变量不见了;变量设置为只读后不可废弃,不可修改。变量的声明方式:LOCALTEST=‘HELLO,BOY’echo$LOCALTEST。
局部变量:作用域只对当前的代码段有效,local VARNAME=value。
位置变量:$1,$2,$3,$4这样的变量,取参数的位置。
特殊变量:
$?上一个命令的状态返回值。
$#参数的个数
$*参数列表
$@参数列表
$0命令本身 脚本本身
程序状态返回代码(0-255) 0: 正确执行 1-255:错误执行,1,2,127系统预留;
注意:
set命令结果是与shell类型有关。
env查询的是当前用户所有的环境变量的情况。
export 查询的是当前导出成用户变量的shell变量。
撤销变量:unset
变量名称:
1、只能包含字母、数字和下划线,并且不能数字开头;
2、不应该跟系统中已有的环境变量重名;
3、最好做到见名知义;
测试脚本是否有语法错误:
bash -n 脚本
bash -x 脚本:单步执行
3.shell编程基础
1)shebang:魔数
#!/bin/bash
#开头的是注释行,是不执行的。
/dev/null :软件设备,bit bucket,数据黑洞。
注意事项:
脚本在执行时会启动一个子shell进程;
命令行中启动的脚本会继承当前shell环境变量
系统自动执行的脚本(非命令行启动)就需要自我定义需要各环境变量;
练习:写一个脚本,完成以下任务
1、添加5个用户, user1,..., user5
2、每个用户的密码同用户名,而且要求,添加密码完成后不显示passwd命令的执行结果信息;
3、每个用户添加完成后,都要显示用户某某已经成功添加;
答案:
#!/bin/bash
#Adduser by dongzi#
useradd user1
echo "user1"|passwd --stdin user1 &> /dev/null
echo "user1 add successful!"
useradd user2
echo "user2"|passwd --stdin user2 &> /dev/null
echo "user2 add successful!"
useradd user3
echo "user3"|passwd --stdin user3 &> /dev/null
echo "user3 add successful!"
useradd user4
echo "user4"|passwd --stdin user4 &> /dev/null
echo "user4 add successful!"
useradd user5
echo "user5"|passwd --stdin user5 &> /dev/null
echo "user5 add successful!"
2)
bash中如何实现条件判断?
条件测试类型:
整数测试
字符测试
文件测试
条件测试的表达式:
[空格expression空格]
[[空格expression空格]]
test expression
整数比较:
-eq: 测试两个整数是否相等;比如 $A -eq $B
-ne: 测试两个整数是否不等;不等,为真;相等,为假;
-gt: 测试一个数是否大于另一个数;大于,为真;否则,为假;
-lt: 测试一个数是否小于另一个数;小于,为真;否则,为假;
-ge: 大于或等于
-le:小于或等于
命令的间逻辑关系:
逻辑与: &&
第一个条件为假时,第二条件不用再判断,最终结果已经有;
第一个条件为真时,第二条件必须得判断;
逻辑或: ||
第一个条件为真时,第二个条件不用在判断,最终的结果已经有了
第一个条件为假时,第二个条件要判断。
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`
条件判断,控制结构:
单分支if语句
if 判断条件; then
statement1
statement2
...
fi
双分支的if语句
if 判断条件; then
statement1
statement2
...
else
statement3
statement4
...
fi
多分支的if语句:
if 判断条件1; then
statement1
...
elif 判断条件2; then
statement2
...
elif 判断条件3; then
statement3
...
else
statement4
...
fi
文件测试:
-e FILE:测试文件是否存在
-f FILE: 测试文件是否为普通文件
-d FILE: 测试指定路径是否为目录
-r FILE: 测试当前用户对指定文件是否有读取权限;
-w
-x
[ -e /etc/inittab ]
[ -x /etc/rc.d/rc.sysinit ]
定义脚本退出状态码
exit: 退出脚本
exit #
如果脚本没有明确定义退出状态码,那么,最后执行的一条命令的退出码即为脚本的退出状态码;
练习:将上面的练习进行修改,如果存在就不添加用户,如果不存在就添加用户。
#!/bin/bash
#adduser by dongzi#
! id user1 &>/dev/null && useradd user1 && echo "user1"|passwd --stdin user1 &>/dev/null && echo "user1 add successful!"
! id user2 &>/dev/null && useradd user2 && echo "user2"|passwd --stdin user2 &>/dev/null && echo "user2 add successful!"
! id user3 &>/dev/null && useradd user3 && echo "user1"|passwd --stdin user3 &>/dev/null && echo "user3 add successful!"
! id user4 &>/dev/null && useradd user4 && echo "user4"|passwd --stdin user4 &>/dev/null && echo "user4 add successful!"
! id user5 &>/dev/null && useradd user5 && echo "user5"|passwd --stdin user5 &>/dev/null && echo "user5 add successful!"
练习:如果/etc/inittab文件的行数大于100,就显示好大的文件;
[ `wc -l /etc/inittab|cut -d‘ ‘ -f1` -gt 100 ] && echo "big file!"
练习,写一个脚本,完成以下要求:
1、添加3个用户user1, user2, user3;但要先判断用户是否存在,不存在而后再添加;
2、(先不做)添加完成后,显示一共添加了几个用户;当然,不能包括因为事先存在而没有添加的;
3、最后显示当前系统上共有多少个用户;
#!/bin/bash
#######dongzi#######
! id user1 && useradd user1 && echo "user1"| passwd --stdin user1 &>/dev/null
! id user2 && useradd user2 && echo "user2"| passwd --stdin user2 &>/dev/null
! id user3 && useradd user3 && echo "user3"| passwd --stdin user3 &>/dev/null
ALLUSERS=`wc -l /etc/passwd|cut -d‘ ‘ -f1`
echo $ALLUSERS
练习,写一个脚本,完成以下要求:
给定一个用户:
1、如果其UID为0,就显示此为管理员;
2、否则,就显示其为普通用户;
NAME=user16
USERID=`id -u $NAME`
if [ $USERID -eq 0 ]; then
echo "Admin"
else
echo "common user."
fi
练习:写一个脚本
判断当前系统上是否有用户的默认shell为bash;
如果有,就显示有多少个这类用户;否则,就显示没有这类用户;
#!/bin/bash
#########dongzi##########
#COUNT=`grep "bash$" /etc/passwd | wc -l`
#STAT=grep "bash$" /etc/passwd | wc -l
if grep "bash$" /etc/passwd | wc -l
then
echo "$COUNT"
else
echo "NO"
fi
提示:“引用”一个命令的执行结果,要使用命令引用;比如: RESAULTS=`wc -l /etc/passwd | cut -d: -f1`;
使用一个命令的执行状态结果,要直接执行此命令,一定不能引用;比如: if id user1一句中的id命令就一定不能加引号;
如果想把一个命令的执行结果赋值给某变量,要使用命令引用,比如USERID=`id -u user1`;
如果想把一个命令的执行状态结果保存下来,并作为命令执行成功与否的判断条件,则需要先执行此命令,而后引用其状态结果,如
id -u user1
RETVAL=$?
此句绝对不可以写为RETVAL=`id -u user1`;
练习:写一个脚本
判断当前系统上是否有用户的默认shell为bash;
如果有,就显示其中一个的用户名;否则,就显示没有这类用户;
#!/bin/bash
#############dongzi#############
RESULT=`grep "bash$" /etc/passwd|wc -l`
USER=`grep "bash$" /etc/passwd|head -1|cut -d: -f1`
if [ $RESULT -gt 0 ];then
echo "$USER"
else
echo "NO Exit"
fi
练习:写一个脚本
给定一个文件,比如/etc/inittab
判断这个文件中是否有空白行;
如果有,则显示其空白行数;否则,显示没有空白行。
#!/bin/bash
########dongzi#########
COUNT=`grep "^$" /etc/inittab|wc -l`
if [ $COUNT -gt 0 ];then
echo "$COUNT"
else
echo "NO Blank"
fi
练习:写一个脚本
给定一个用户,判断其UID与GID是否一样
如果一样,就显示此用户为“good guy”;否则,就显示此用户为“bad guy”。
#!/bin/bash
USERNAME=user1
USERID=`id -u $USERNAME`
GROUPID=`id -g $USERNAME`
if [ $USERID -eq $GROUPID ]; then
echo "Good guy."
else
echo "Bad guy."
fi
进一步要求:不使用id命令获得其id号
#!/bin/bash
#
USERNAME=user1
if ! grep "^$USERNAME\>" /etc/passwd &> /dev/null; then
echo "No such user: $USERNAME."
exit 1
fi
USERID=`grep "^$USERNAME\>" /etc/passwd | cut -d: -f3`
GROUPID=`grep "^$USERNAME\>" /etc/passwd | cut -d: -f4`
if [ $USERID -eq $GROUPID ]; then
echo "Good guy."
else
echo "Bad guy."
fi
练习:写一个脚本
给定一个用户,获取其密码警告期限;
而后判断用户密码使用期限是否已经小于警告期限;
提示:计算方法,最长使用期限减去已经使用的天数即为剩余使用期限;
如果小于,则显示“Warning”;否则,就显示“OK”。
圆整:丢弃小数点后的所有内容
#!/bin/bash
#####dongzi#######
USERNAME=wuxiangdong
TMP=`date +%s`
TODAY=$[$TMP/86400]
MODIFYDAY=`grep "^wuxiangdong" /etc/shadow|cut -d: -f3`
WARNINGDAY=`grep "^wuxiangdong" /etc/shadow|cut -d: -f6`
if [ $[$TODAY-$MODIFYDAY] -lt $WARNINGDAY ];then
echo "Warning"
else
echo "OK"
fi
练习:写一个脚本
判定命令历史中历史命令的总条目是否大于1000;如果大于,则显示“Some command will gone.”;否则显示“OK”。
#!/bin/bash
#######dongzi########
if [ `cat ~/.bash_history|wc -l` -gt 1000 ];then
echo "Some command will gone."
else
echo "OK"
fi
练习:写一个脚本
给定一个文件:
如果是一个普通文件,就显示之;
如果是一个目录,亦显示之;
否则,此为无法识别之文件;
#!/bin/bash
########dongzi######
FILE=/etc/inittab
if ! [ -e $FILE ];then
exit 6
fi
if [ -d $FILE ];then
echo "Directory!"
elif [ -f $FILE ];then
echo "common file"
else
echo "NO"
fi
练习:写一个脚本
给脚本传递两个参数(整数);
显示此两者之和,之乘积;
#!/bin/bash
##########dongzi###########
if [ $# -lt 2 ];then
echo "Usage:16.sh ARG1 ARG2"
exit 8
fi
echo "The sum is:$[$1+$2]."
echo "The prod is:$[$1*$2]"
练习:写一个脚本,完成以下任务
1、使用一个变量保存一个用户名;
2、删除此变量中的用户,且一并删除其家目录;
3、显示“用户删除完成”类的信息;
#!/bin/bash
#############dongzi#############
USERNAME=user1
if id user1 ;then
userdel -r $USERNAME
else
echo "No such user"
fi
总结:以上是在学习shell脚本学习笔记总结,以后会陆陆续续的增加内容,今天就写到这里吧!
本文出自 “天道酬勤” 博客,谢绝转载!
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。