Shell编程:
编译器,解释器
编程语言: 机器语言、汇编语言、高级语言
静态语言: 编译型语言
强类型(变量)
事先转换成可执行格式
c\c++\JAVA\c#
动态语言: 解释性语言
弱类型
边解释边执行
asp/asp.net/php/shell/python/perl
Shell: 弱类型编程语言
强类型: 变量在使用前,必须事先声明,甚至还需要初始:
弱类型: 变量用时声明,甚至不区分类型:
面向过程: Shell C
面向对象: JAVA Python, perl, c++
变量:内存空间,命名
内存:编址的存储单元
进程:
变量类型: 事先确定数据的存储格式和长度
字符
数值
整形
浮点型
编程能力:
脚本编程
变量赋值: VAR_NAME=VALUE
bash变量类型:
环境变量
本地变量(局部变量)
位置变量
特殊变量
本地变量:
VAR_NAME=VALUE: 作用域为整个脚本进程:
局部变量:
local VARNAME=VALUE 作用域为当前代码段
环境变量: 作用域为当前shell进程及其子进程
export VARNAME=value
"导出"
两种方式:
1. export VARNAME=VALUE
2. VARNAME=VALUE
export VARNAME
位置变量
$1,$2,...
shift n: 踢掉第1-n个参数,第n+1变成第一个
./filetest.sh /etc/fstab /etc/inittab ...
$1: /etc/fstab
$2: /etc/inittab
...
特殊变量:
$? 上一条命令的执行状态返回值:
程序执行结果
程序状态返回代码(0-255)
0: 正确执行
1-255: 错误执行, 1,2,127 系统预留
$#: 参数的个数
$*: 参数列表
$@: 参数列表
输出重定向:
>
>>
2>
2>>
&> 重定向标准输出或错误输出至同一个文件
/dev/null: 软件设备, bit bucket 数据黑洞
秩序执行, 可能有两类返回值:
脚本在执行时,会启动一个子shell进程:
命令行中启动的脚本,会继承当前shell环境变量
系统自动执行的脚本(非命令行启动),就需要自我定义需要各环境变量
撤销变量:
unset VARNAME (千万不要加$)
查看当前shell中的变量
set(包括环境变量和本地变量)
查看当前shell中的环境变量:
printenv
env
export
脚本: 命令的堆砌,按照实际需要,结合命令流程控制机制实现的源程序
shebang: 魔数
#!/bin/bash
练习:写一个脚本,完成以下任务
1. 添加5个用户,user1,user2,...user5
2. 每个用户的密码同用户名,而且要求,添加密码完成后不显示passwd命令的执行结果信息
3. 每个用户添加完成后,都要显示用户xx已经成功添加
useradd user1echo "user1" | passwd --stdin user1 &> /dev/null
条件判断:
如果用户不存在
添加用户, 给密码并显示添加成功
否则
显示如果已经存在,不添加
bash中如何实现条件判断
条件测试类型:
整数测试
字符测试
文件测试
条件测试的表达式:
[ expression ] ‘[]’两侧必须带空格
[[ expression ]] 关键字
test expression
整数比较:
-eq 测试两个整数是否相等: 如何 $A -eq $B, 相等为真(0),不等为假(1)
-ne 测试两个整数是否不相等: 不等为真,相等为假
-gt 测试一个数是否大于另一个数: 大于,为真;否则为假
-lt 测试一个数是否小于另一个数: 小与,为真
-ge 大于或等于
-le 小于或等于
命令间的逻辑关系:
逻辑与: && :第一个条件为假时, 第二条件不用再判断(也不会再执行第二条件), 最终结果已经有
第一个条件为真时, 第二条件必须得判断:
eg: id user2 &> /dev/null && echo "hello,student"
逻辑或: || 第一表达式为真,则不会执行第二个表达式
eg:
如果用户user6不存在,就添加用户user6
id user6 || useradd user6
!id user6 && useradd user6
如果/etc/inittab文件得行数大于100, 就显示好大的文件
[ ‘wc -l /etc/inittab | cut -d‘‘ -f1 ‘ -gt 100 ] && echo "large file"
变量名称:
1、只能包含字符、数字和下划线,并且不能以数字开头:
2、不应该跟系统中已有的环境变量重名:
3、 最好做到见名知义
如果用户已存在, 就显示用户已经存在, 否则就添加此用户
id user1 && echo "user1 existed" || useradd user1
如果用户不存在, 就添加; 否则,显示其已经存在:
!id user1 && useradd user1 || echo "user1 existed"
如果用户不存在, 就添加: 并且设定密码; 否则,显示其已经存在
!id user1 && useradd user1 && echo “user1" | passwd --stdin || echo "user1 exsited"
练习:写一个脚本,完成以下要求:
1、 添加3个用户user1, user2, user3 但要先判断用户是否存在,不存在而后再添加
2、 添加完成后, 显示一共添加了几个用户, 当然, 不能包括因为事先存在而没有添加的
3、 最后显示当前系统上共有多少个用户
! id user1 &> /dev/null && useradd user1 && echo "password" | passwd --stdin &> /dev/null || echo "existed"
USERS=‘wc -l /etc/passwd | cut -f‘ ‘ -f1‘
echo "$USERS users"
练习:写一个脚本,完成以下要求:
给定一个用户:
1、 如果其UID为0, 就显示此为管理员
2、 否则, 就显示其为普通用户
NAME=user1
USERID=`id -u $NAME`
[ $USERID -eq 0] && echo ‘Admin‘ || echo "normal user"
条件判断, 控制结构:
单分支的if语句
if 判断条件; then
statement1
statement2
...
fi
双分支的if语句:
if 判断条件; then
statement1
statement2
...
else
statement1
statement2
...
fi
多分枝的if语句:
if 判断条件1; then
statement1
...
elif 判断条件2
statement2
....
elif 判断条件3
statement3
...
else
statement4
fi
#if id $USER; then 这里的(id $USER) 是命令执行状态,执行成功与否(0-255),除了0,都是执行错误
bash -n 脚本名称 : 测试脚本语法错误
bash -x 脚本名称: 单步执行
文件测试:
-e FILE: 测试文件是否存在
-f FILE: 测试文件是否为普通文件
-d FILE: 测试指定路径是否为目录
#测试当前用户对指定文件是否有读、写、执行权限
-r FILE
-w FILE
-x FILE
eg:
[ -e /etc/inittab ] : 测试文件是否存在
[ -x /etc/rc.d/rc.sysinit ] 测试当前用户是否对此文件有执行权限, []内两侧必须有空格
练习:写一个脚本,完成以下任务
1. 使用一个变量保存一个用户名:
2. 删除此变量中的用户,且一并删除其家目录
3. 显示“用户删除完成”类的信息
练习:写一个脚本
判断当前系统哈桑是否有用户的默认shell为bash:
如果有,就显示有多少个这类用户: 否则,就显示没有这类用户:
grep "bash$" /etc/passwd &> /dev/null
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
grep "\<bash$" /etc/passwd | wc -l
else
echo "No such a user"
fi
A=3
B=6
shell中如何进行算术运算:
1. let 算术运算表达式
let C=$A+$B
2. $[$A+$B]
3. $((算是运算表达式))
C=(($A+$B))
4. expr 算数运算表达式,表达式中各操作数及运算符之间要有空格, 而且要使用命令引用
C=`expr $A + $B`
定义脚本退出状态码
exit: 退出脚本
exit #错误码 只要不是0就可
如果脚本没有明确定义退出状态码, 那么, 最后执行的一条命令的退出码即为脚本的退出状态码:
本文出自 “Richier” 博客,请务必保留此出处http://richier.blog.51cto.com/1447532/1631552
bash脚本编程之(3/4)条件判断、算符运算、整数测试、文件测试、特殊变量等笔记
原文地址:http://richier.blog.51cto.com/1447532/1631552