楼赛

这几天登录了下实验楼,看到有个楼赛,然后就参加了,这里记录一下。
虽然一直用Linux,但是基本没专门去上过之类的课,最早还是智能信息课的实验机房里搭Hadoop用到的,然后还挺喜欢的,以至于后来卸了Win把笔记本装了Ubuntu,用的开源软件,也没有盗版的困扰了。

呐,就是这样说的,当然没打算拿奖,里面高手估计多得是,所以也是求个体验。




楼赛一共有三题,虽然比较简单,不过比较实用,太难的屠龙之术也就没啥必要丢出来以论轩轾了。

第一题 备份日志文件

描述如下:

这个就是写个每天自动备份打包完成任务的脚本,不过里面不让写脚本,这个里面虽然说了,但是还是花了很多时间才放弃写脚本。

时间输出

首先是要获得当前时间,以确定两点开始备份。通常是使用date命令。
首先查看一下date的参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ ▶ 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.
Mandatory arguments to long options are mandatory for short options too.
-d, --date=STRING display time described by STRING, not 'now'
-f, --file=DATEFILE like --date; once for each line of DATEFILE
-I[FMT], --iso-8601[=FMT] output date/time in ISO 8601 format.
FMT='date' for date only (the default),
'hours', 'minutes', 'seconds', or 'ns'
for date and time to the indicated precision.
Example: 2006-08-14T02:34:56-0600
-R, --rfc-2822 output date and time in RFC 2822 format.
Example: Mon, 14 Aug 2006 02:34:56 -0600
--rfc-3339=FMT output date/time in RFC 3339 format.
FMT='date', 'seconds', or 'ns'
for date and time to the indicated precision.
Example: 2006-08-14 02:34:56-06:00
-r, --reference=FILE display the last modification time of FILE
-s, --set=STRING set time described by STRING
-u, --utc, --universal print or set Coordinated Universal Time (UTC)
--help display this help and exit
--version output version information and exit

后面比较多就不贴了,主要是获取年月日,好给打包文件命名。

1
2
date +%y%m%d
171029

能获取出来这一步基本就OK了。

自动化任务

使用cron命令实现自动化。
首先编辑crontab文件,在其中加入执行时间和执行命令,即备份并打包文件。
比较简单,就直接贴代码了:

1
2
crontab -e
0 2 * * * mkdir /home/shiyanlou/backup && tar -cvf /home/shiyanlou/backup/"$(date +%y-%m-%d)".tar /var/log/dpkg.log /var/log/mysql.log /var/log/fontconfig.log

然后启动一下cron服务:

1
sudo service cron start

或者

1
sudo cron start

第二题 批量创建删除用户和组

描述如下:


批量创建删除用户和组,按照里面的要求,大概是创建一个脚本,可以实现创建和删除用户的功能,输入为四个参数,对于已经创建的用户显示星号。

确保输入正确

输入正确包括

  • 学生数量正确
1
2
3
4
5
if [ $# -ne 4 ]
then
echo "parameter"
exit
fi
  • 参数数目正确
1
2
3
4
5
if [ $4 -lt 1 ] || [ $4 -gt 10 ]
then
echo "parameter error"
exit
fi
  • 功能参数正确
    即必须是del或者add参数,即删除或者添加用户组。可以最后加个else处理这个部分。

随机数的生成

一共要生成六位随机数,虽说linux自带RANDOM,但是都是小于等于五位数的,且不能确保多少位,所以使用urandom来获取随机数。

1
tr -cd 0-9 </dev/urandom | head -c 6

大致思路是这样,然后贴代码了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
if [ $# -ne 4 ]
then
echo "parameter"
exit
fi
if [ $4 -lt 1 ] || [ $4 -gt 10 ]
then
echo "parameter error"
exit
elif [ $1 == "add" ]
then
id $2 >& /dev/null
if [ $? -ne 0 ]
then
pw=`tr -cd 0-9 </dev/urandom | head -c 6`
sudo useradd -s /bin/zsh $2 -p $pw
ss="#$2 ALL=(ALL:ALL) ALL"
echo $ss
sudo sh -c "echo $ss >> /etc/sudoers"
sudo usermod -aG sudo $2
echo $2:$pw
else
echo $2:******
fi
for stu in `seq 1 $4`
do
id $3$stu >& /dev/null
if [ $? -ne 0 ]
then
pw=`tr -cd 0-9 </dev/urandom | head -c 6`
echo $3$stu:$pw
sudo useradd -s /bin/zsh -p $pw $3$stu
else
echo $3$stu:******
fi
done
elif [ $1 == "del" ]
then
sudo userdel $2
for stu in `seq 1 $4`
do
sudo userdel $3$stu
done
else
echo "parameter error"
exit
fi

第三题 获取系统信息

描述如下:

获取系统信息,包括系统各部分硬件信息和软件信息。

CPU信息

CPU信息可以通过查看Linux的cpuinfo获取,不过并没有直接给出CPU数量,虽然可以直接看出。
这里通过把processor的数量加1得到

1
echo "cpu num: "$(grep processor /proc/cpuinfo | wc -l)

内存信息

内存信息可以通过很多方式查看,比如top,还有就是Linux的meminfo,还有就是free命令。但是要求自定义单位,所以这里用free。

1
2
echo $(free -g |grep Mem |awk '{print "memory total: " $2"G"}')
echo $(free -m |grep Mem |awk '{print "memory free: " $4"M"}')

磁盘信息

磁盘信息一般使用df命令,这里要获取根目录的磁盘大小,根目录一般在输出中第一行,所以需要获取其位置:

1
echo "disk size: "$(df -h|awk '{print $2}'|sed -n 2p)

不过这个只是碰运气,有的不在第一行,就会出错了,但是grep直接过滤掉根目录是没用的,这里需要精确匹配根目录/,所以需要用到grep -w

1
echo "disk size: "$(df -h|grep -w '/' |awk '{print $2}'|sed -n 2p)

系统信息

获取系统位数,直接:

1
echo "system bit:" $(getconf LONG_BIT)

进程数

查看当前所有进程可以用ps命令实现,但是没有计数的功能,也不必为此单独创建一个命令,可以结合wc命令实现该功能:

1
echo "process: "$(ps -A |wc -l)

软件数目

和上面一样,可以通过dpkg命令查询所有安装的软件,再结合wc命令实现计数:

1
echo "software num: "$(dpkg -l|wc -l)

网卡信息

查询IP很简单,一句ifconfig可以解决,但是输出格式不满足要求,需要删掉输出信息中多余的字符,可以用awk命令。

1
echo "ip: "$(ifconfig eth0 |awk '/inet/ { split($2,x,":");print x[2]}')

最后这题全部代码如下:

1
2
3
4
5
6
7
8
9
10
echo "cpu num: "$(grep processor /proc/cpuinfo | wc -l)
echo $(free -g |grep Mem |awk '{print "memory total: " $2"G"}')
echo $(free -m |grep Mem |awk '{print "memory free: " $4"M"}')
#echo $(grep MemTotal /proc/meminfo | awk '{print "memory total: " $2}')
#echo $(grep MemFree /proc/meminfo | awk '{print "memory free: "$2}')
echo "disk size: "$(df -h|grep -w "/" |awk '{print $2}'|sed -n 2p)
echo "system bit:" $(getconf LONG_BIT)
echo "process: "$(ps -A |wc -l)
echo "software num: "$(dpkg -l|wc -l)
echo "ip: "$(ifconfig eth0 |awk '/inet/ { split($2,x,":");print x[2]}')

孤芳自赏,不必捧场。
分享