与本文无关的前言:服务器的防火墙策略还是要慎重,之前一直使用firewalld,这次学习了下iptables,一行代码直接把自己踢出了ssh远程连接。
iptables -P INPUT DROP
iptables命令即时生效,还好重启服务器可以重置策略,否则又得重新安装一遍Linux了。
正文:Linux的脚本没有想象的那么复杂,今天就来练手一下Linux下的for、while、case三种控制流语句,学会了控制流程,基本就可以写一些像模像样的Linux脚本了。三种语句具体的含义和语法就不废话了,直接上测试代码。
利用for语句批量添加Linux用户。
首先新建一个user.txt,里面我写了4个名字,其中xiaofei这个用户已经存在于/etc/passwd
而我要做的就是创建不存在的用户名,代码如下(由于是测试代码就不写注释了):
#!/bin/bash
USERNAMES=`cat /opt/test1/user.txt`
read -p "input password: " pwd
for USER in $USERNAMES
do
id $USER &> /dev/null
if [ $? -eq 0 ]
then
echo "User $USER is already exists!"
else
useradd $USER &> /dev/null
echo $pwd | passwd --stdin $USER &> /dev/null
echo "$USER add"
fi
done
echo "done "
首先定义一个USERNAMES变量(我之前习惯用下划线来建立变量,不过Linux中变量名好像都是大写字母,跟着大佬们走吧)获取`cat /opt/test1/user.txt`命令的结果,这里的`是间隔号(也就是键盘ESC键下面和~符号在一起的),代表执行这个命令,由于这种符号和单引号容易混淆,所以也可以使用$()命令来达到一样的效果,read从标准输入中获取内容,-p(prompt)提示,然后利用for循环,逐步取出文本每行内容,id $USER判断该用户名是否存在,我不需要其返回标准或者错误输出到控制台,所以利用&>将12输出全部重定向到/dev/null空间(类似于windows的回收站,但是不保留直接删除)中,$?返回上一条命令的结果,只要程序正常运行退出就会返回0,也就是说只要$?等于0,那么这个用户肯定是存在的,-eq运算符就是equal(同理,gt=>greater than等等),如果不等于0,那么这个用户不存在,使用useradd添加用户,然后使用管道符,将前面输入的pwd密码以标准输入的形式更新到USER。
成功添加用户。测试完成之后,删除用户及其在home目录下的文件夹:
userdel --remove --force zhang
利用while循环完成一个猜数小游戏。
# !/bin/bash
PRICE=$(expr $RANDOM % 100)
TIMES=1
while true
do
read -p "guess the price: " INT
if [ $INT -eq $PRICE ]
then
echo "you are right, price is $PRICE. times is $TIMES"
exit
elif [ $INT -gt $PRICE ]
then
echo "lower than $INT."
else
echo "bigger than $INT."
fi
let TIMES++
done
expr计算一个表达式,RANDOM变量会返回一个0~32767之间的随机数,除以100取余,也就是PRICE变量会在0~99之间,然后猜就完事了。
利用case判断键盘输入的是数字、字母还是其他。
#!/bin/bash
read -p "enter a key: " KEYNAME
case $KEYNAME in
[a-zA-Z])
echo "is string"
;;
[0-9])
echo "is number"
;;
*)
echo "ohters"
;;
esac
测试如下:
可能唯一需要解释的就是结尾的esac单词吧,记也记不住,其实就是case反着写,不用记,就像上面的if语句结尾是fi一样。
Linux中的命令实在太多,作为凡人,确实不可能完全背熟所有命令,所以高效的利用帮助文档就很重要了,之前在写expect命令时也简单介绍了下手册之类的工具,但是自己也是一知半解,这次整理的详细些。
方法一:--help选项。适合查询曾经用过,但是忘记选项和参数的命令。
date --help
# 输出如下:
Usage: date [OPTION]... [+FORMAT]
or: date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]
Display the current time in the given FORMAT, or set the system date.
可以看到Usage中列出了执行命令的语法,有两种语法,一种是直接执行返回日期,也可增加+FORMAT参数返回指定格式日期,另外一种就是设置日期时间,格式为MMDDhhmm。
继续下翻,里面有各参数含义的释义,继续往下,则是格式的说明:
FORMAT controls the output. Interpreted sequences are:...
方法二:man page。一般完全不了解这个命令的时候使用手册。
注意:内容比较多的时候,可以使用/?来搜索,类似于vim中,输入斜杠或者问号,进入末行模式,再次输入关键词,使用n/N进行前后搜索的切换。
man date
#进入到手册界面
#命令名称及简单介绍
NAME
#概要,介绍基本用法
SYNOPSIS
#用法一
date [OPTION]... [+FORMAT]
#用法二
date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]
#详细说明用法谈到的选项和参数,建议仔细查看
DESCRIPTION
#-d为短参数,--date为完整选项
-d, --date=STRING
display time described by STRING, not 'now'
#示例
EXAMPLES
#上面--date提到的STRING格式说明
DATE STRING
# e.g:date -d "next Monday" 下个周一为3月1号
# Mon Mar 1 00:00:00 CST 2021
#与这个命令相关额环境参数说明
ENVIRONMENT
#作者
AUTHOR
#著作权法额保护
COPYRIGHT # =>GNU GPL
#还可以在哪里查到与date相关额说明文件
SEE ALSO
# 还有些参数这里面没有,也一并写在这里
OPTIONS#针对SYNOPSIS中列举的所有可用的选项说明
COMMANDS#当这个程序在执行的时候,可以在此程序中执行的命令
刚进入到这个手册,我们可以看到DATE(1),这个数字(1)是有含义的,表明是“一般用户可使用的命令”,以下为数字参照表,更具体的内容含义可使用man man查看:
1--User Commands 用户命令,用户在shell环境中可以操作的命令或可执行文件。
2--System Calls 系统内核,系统内核可调用的函数与工具等,即由内核提供的函数。如open,write之类的(通过这个,可以很方便的查到调用这个函数时需要加什么头文件)。
3--C Library Functions,一般常用的函数(funtion)与函数库(library),大部分为C的函数库(libc)。
4--Devices and Special Files 设备文件的说明,通常是/dev下的文件。
5--File Formats and Conventions 配置文件或某些文件的格式 。
6--Games 游戏,给游戏留的,由各个游戏自己定义。
7--Miscellanea 杂项,惯例与协议等,例如linux文件系统,网络协议,ASCII code等说明。
8--System Administration tools and Deamons 系统管理员可以用的管理命令。
9--跟kernel有关的文件。
再来测试一个
man null
#数字4,表示其是一个设备文件
FILES
#这个程序或数据所使用或参考或链接到的某些文件
#可以看到熟悉的/dev/null和/dev/zero文件
man page的数据存放位置,可以使用man man查看,在FILES一项中,可以看到我的手册是在/usr/share/man中,也可以通过/etc/man_db.conf配置文件进行修改。
使用-f参数可以查看更多与命令(该命令必须为完整名称!)相关的信息,如下:
man -f man
# 等价于whatis passwd
#输出
man (7) - macros to format man pages
man (1) - an interface to the on-line reference manuals
man (1p) - display system documentation
可能你使用man -f man参数会提示nothing appropriate,可以尝试使用以root权限使用mandb命令创建或更新手册页索引缓存。
可以看到与man有关的手册有三个,我们可以使用如下命令查看不同的手册,一般来说,man man显示的是序号较小的手册,具体查找顺序定义在man_db.conf配置文件当中。
man 1 man
man 7 man
也许,某个时候突然想查询某个命令,但是却怎么想不起来命令的名称,只记得某个关键词,可以使用-k参数模糊搜索,例如:
man -k passwd
# 等价于 apropos passwd
另外,Linux还提供了info工具用于查询命令,可以使用info info查看。
还可以直接进入到/usr/share/doc目录下查看说明文件,一般这个目录下的说明文件不仅告诉你怎么做,还会有相关的原理说明。