1、人类如何与计算机"沟通"?
翻译官:编译器、解释器;
编程语言:机器语言、汇编语言、高级语言
静态语言:编译型语言
强类型语言:变量在使用之前,需要声明定义,甚至需要初始化
事先转换成可执行格式
C、C++、Java、C#
动态语言:解释型语言
弱类型语言:变量在使用之前,不需要声明定义
边解释、边执行
PHP、JSP、Perl、shell编程、Python
面向过程:shell、C
面向对象:C++、JAVA、Python、Perl
变量:就是命名的内存空间;
内存:就是编址的存储单元;
为什么会有变量:想象一下,如果没有变量这个概念的话,让计算机做一个1到10000的加法,这需要10000个内存空间去存放,但如果引入了变量这个概念,则需要两个变量即可。
变量类型的作用及功能:事先确定变量的存储格式及长度。
整型,8bit: 256
0-255, 溢出
字符变量
数值变量:
整型
浮点型:11.23,1.123*10,0.1123*10^2
eg:字符型:2014/9/30 64bit
数值型:99999 24bit
布尔型:真、假
字符:10:16bit
数值:10: 1010, 8bit
shell编程:shell弱类型的编程语言
什么是强?什么是弱?
强类型:变量在使用前,需要声明定义,甚至初始化
弱类型:变量在使用时才声明,甚至不区分类型
变量赋值:VER_NAME=VALUE
bash变量:
本地变量(局部变量)
环境变量
位置变量
特殊变量
本地变量:
set VARNAME=VALUE: 作用域为整个bash进程;
局部变量:
local VARNAME=VALUE:作用域为当前代码段;
环境变量:
export VARNAME=VALUE;
VARNAME=VALUE
export VARNAME
“导出”
位置变量:
$1,$2......
特殊变量:
$?(返回上一个命令的执行状态码),$*(参数列表),$@
程序的执行可以返回两类结果:
1、程序的执行结果;
2、程序的执行状态码:0-255
0:正确执行
1-255:错误代码
输出重定向:
>:覆盖输出重定向
>>:追加输出重定向
2>:错误覆盖输出重定向
2>>:错误追加重定向
&>:标准输出+错误输出重定向
撤销变量:
unset VERNAME
查看变量:(环境变量+本地变量)
set
查看环境变量:
printenv
env
export
脚本:命令的堆砌,按实际需要,结合控制流程机制实现的源程序
shebang:魔数
#!/bin/bash
#注释,不执行
/dev/null:软件设备 ; 位桶(bit bucket) 数据黑洞
脚本在执行时,会启动一个子shell进程:
在命令行运行的脚本,会继承当前shell环境变量
系统自动运行的脚本(非命令行启动),则需要自我定义各个环境变量
练习:写一个脚本,完成以下任务
1、添加5个用户, user1,..., user5
2、每个用户的密码同用户名,而且要求,添加密码完成后不显示passwd命令的执行结果信息;
3、每个用户添加完成后,都要显示用户某某已经成功添加;
useradd user1
echo "user1" | passwd --stdin user1 &> /dev/null
echo "Add user1 successfully."
条件判断:
如果用户不存在
添加用户,给密码并显示添加成功;
否则
显示如果已经没在,没有添加;
bash 中如何实现条件判断:
条件测试的类型:
整数测试
文件测试
字符测试
条件测试的表达式:
[ expression ]
[[ expression ]]
test expression
整数比较:
-gt:大于
-lt:小于
-ge:大于等于
-le:小于等于
-eq:等于
-ne:不等于
命令间的逻辑关系:
&&:与,一假全假,当左边为假时,则不需要执行右边,整个逻辑表达式即为假
||:或,一真全真,当左边为真时,则不需要执行右边,整个逻辑表达式即为真
如果用户user6不存在,就添加用户user6
!id user6 && useradd user6
id user6 || useradd user6
如果/etc/inittab文件的行数大于100,就显示好大的文件;
[ wc -l /etc/inittab | cut -d " " -f 1 -gt 100 ] && echo "Large file"
变量命名规则:
1、只能包含字母,数字,下划线,并且不能以数字开头。
2、不能与系统中已有的环境变量重名
3、最好能够做到见名知意
如果用户存在,就显示用户已存在;否则,就添加此用户;
id user && echo "user exists" || adduser user
!id user || echo "user exists" && adduser user
如果用户不存在,就添加;否则,显示其已经存在;
!id user && useradd user || echo "user exists"
id user || useradd user && echo "user exists"
如果用户不存在,添加并且给密码;否则,显示其已经存在;
!id user && useradd user && echo "user" | passwd --stdin user || echo "user exists"
练习,写一个脚本,完成以下要求:
1、添加3个用户user1, user2, user3;但要先判断用户是否存在,不存在而后再添加;
2、添加完成后,显示一共添加了几个用户;当然,不能包括因为事先存在而没有添加的;
3、最后显示当前系统上共有多少个用户;
USERNUM1=`wc -l /etc/passwd | cut -d ‘ ‘ -f1`#用户为添加之前的事先存在的用户数
id user1 && echo "user1 exists" || adduser user1
id user2 && echo "user2 exists" || adduser user2
id user3 && echo "user3 exists" || adduser user3
USERNUM2=`wc -l /etc/passwd | cut -d ‘ ‘ -f1`
echo "USERADDNUM=$[ $USERNUM2-&USERNUM1 ]"
echo "USERNUM2"
练习,写一个脚本,完成以下要求:
给定一个用户:
1、如果其UID为0,就显示此为管理员;
2、否则,就显示其为普通用户;
如果 UID为0;那么
显示为管理员
否则
显示为普通用户
NAME=user16
USERID=`id -u $NAME`
if [ $USERID -eq 0 ]; then
echo "Admin"
else
echo "common user."
fi
NAME=user16
if [ `id -u $NAME` -eq 0 ]; then
echo "Admin"
else
echo "common user."
fi
if id $NAME; then
练习:写一个脚本
判断当前系统上是否有用户的默认shell为bash;
如果有,就显示有多少个这类用户;否则,就显示没有这类用户;
grep "bash$" /etc/passwd &> /dev/null
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
if grep "bash$" /etc/passwd &> /dev/null; then
提示:“引用”一个命令的执行结果,要使用命令引用;
比如: 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;
如果有,就显示其中一个的用户名;否则,就显示没有这类用户;
练习:写一个脚本
给定一个文件,比如/etc/inittab
判断这个文件中是否有空白行;
如果有,则显示其空白行数;否则,显示没有空白行。
#!/bin/bash
A=`grep ‘^$‘ /etc/inittab | wc -l`
if [ $A -gt 0 ]; then
echo "$A"
else
echo "meiyoukongbaihang"
fi
#!/bin/bash
FILE=/etc/inittab
if [ ! -e $FILE ]; then
echo "No $FILE."
exit 8
fi
if grep "^$" $FILE &> /dev/null; then
echo "Total blank lines: `grep "^$" $FILE | wc -l`."
else
echo "No blank line."
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
W=`grep "student" /etc/shadow | cut -d: -f6`
S=`date +%s`
T=`expr $S/86400`
L=`grep "^student" /etc/shadow | cut -d: -f5`
N=`grep "^student" /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”。
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
测试方法:
[ expression ]
[[ expression ]]
test expression
bash中常用的条件测试有三种:
整数测试:
-gt
-le
-ne
-eq
-ge
-lt
INT1=63
INT2=77
[ $INT1 -eq $INI2 ]
[[ $INT1 -eq $INT2 ]]
test $INT1 -eq $INT2
文件测试:
-e FILE:测试文件是否存在
-f FILE: 测试文件是否为普通文件
-d FILE: 测试指定路径是否为目录
-r FILE: 测试当前用户对指定文件是否有读取权限;
-w
-x
[ -e /etc/inittab ]
[ -x /etc/rc.d/rc.sysinit ]
练习:写一个脚本
给定一个文件:
如果是一个普通文件,就显示之;
如果是一个目录,亦显示之;
否则,此为无法识别之文件;
定义脚本退出状态码
exit: 退出脚本
exit #
如果脚本没有明确定义退出状态码,那么,最后执行的一条命令的退出码即为脚本的退出状态码;
测试脚本是否有语法错误:
bash -n 脚本
bash -x 脚本:单步执行
bash变量的类型:
本地变量(局部变量)
环境变量
位置变量:
$1, $2, ...
shift
特殊变量:
$?
$#:参数的个数
$*: 参数列表
$@:参数列表
./filetest.sh /etc/fstab /etc/inittab
$1: /etc/fstab
$2: /etc/inittab
练习:写一脚本
能接受一个参数(文件路径)
判定:此参数如果是一个存在的文件,就显示“OK.”;否则就显示"No such file."
练习:写一个脚本
给脚本传递两个参数(整数);
显示此两者之和,之乘积;
#!/bin/bash
#
if [ $# -lt 2 ]; then
echo "Usage: cacl.sh ARG1 ARG2"
exit 8
fi
echo "The sum is: $[$1+$2]."
echo "The prod is: $[$1*$2]."
练习:写一个脚本,完成以下任务
1、使用一个变量保存一个用户名;
2、删除此变量中的用户,且一并删除其家目录;
3、显示“用户删除完成”类的信息;
bash:
引用变量:${VARNAME}, 括号有时可省略。
原文:http://xxaqwqm.blog.51cto.com/9368217/1560207