本来是汇总成一篇的,后来发现太多了,分开分析;
二、
练习一:写一个脚本
1.设定变量FILE的值为/etc/passwd
2.依次向/etc/passwd中的每个用户问好,并且说出对方的ID是什么
形如:(提示:LINE=`wc -l /etc/passwd | cut -d" " -f1`)
Hello,root,your UID is 0.
3.统计一共有多少个用户
解析:
passwd 文件内容格式:
1 root:x:0:0:root:/root:/bin/bash
2 daemon:x:1:1:daemon:/usr/sbin:/bin/sh
3 bin:x:2:2:bin:/bin:/bin/sh
4 sys:x:3:3:sys:/dev:/bin/sh
5 sync:x:4:65534:sync:/bin:/bin/sync
6 games:x:5:60:games:/usr/games:/bin/sh
7 man:x:6:12:man:/var/cache/man:/bin/sh
8 lp:x:7:7:lp:/var/spool/lpd:/bin/sh
9 mail:x:8:8:mail:/var/mail:/bin/sh
在该文件中,每一行用户记录的各个数据段用“:”分隔,分别定义了用户的各方面属性。各个字段的顺序和含义如下:
注册名:口令:用户标识号:组标识号:用户名:用户主目录:命令解释程序
(1)注册名(login_name):用于区分不同的用户。在同一系统中注册名是惟一的。在很多系统上,该字段被限制在8个字符(字母或数字)的长度之内;并且要注意,通常在Linux系统中对字母大小写是敏感的。这与MSDOS/Windows是不一样的。
(2)口令(passwd):系统用口令来验证用户的合法性。超级用户root或某些高级用户可以使用系统命令passwd来更改系统中所有用户的口令,普通用户也可以在登录系统后使用passwd命令来更改自己的口令。
现在的Unix/Linux系统中,口令不再直接保存在passwd文件中,通常将passwd文件中的口令字段使用一个“x”来代替,将/etc /shadow作为真正的口令文件,用于保存包括个人口令在内的数据。当然shadow文件是不能被普通用户读取的,只有超级用户才有权读取。
此外,需要注意的是,如果passwd字段中的第一个字符是“*”的话,那么,就表示该账号被查封了,系统不允许持有该账号的用户登录。
(3)用户标识号(UID):UID是一个数值,是Linux系统中惟一的用户标识,用于区别不同的用户。在系统内部管理进程和文件保护时使用 UID字段。在Linux系统中,注册名和UID都可以用于标识用户,只不过对于系统来说UID更为重要;而对于用户来说注册名使用起来更方便。在某些特 定目的下,系统中可以存在多个拥有不同注册名、但UID相同的用户,事实上,这些使用不同注册名的用户实际上是同一个用户。
(4)组标识号(GID):这是当前用户的缺省工作组标识。具有相似属性的多个用户可以被分配到同一个组内,每个组都有自己的组名,且以自己的组标 识号相区分。像UID一样,用户的组标识号也存放在passwd文件中。在现代的Unix/Linux中,每个用户可以同时属于多个组。除了在 passwd文件中指定其归属的基本组之外,还在/etc/group文件中指明一个组所包含用户。
(5)用户名(user_name):包含有关用户的一些信息,如用户的真实姓名、办公室地址、联系电话等。在Linux系统中,mail和finger等程序利用这些信息来标识系统的用户。
(6)用户主目录(home_directory):该字段定义了个人用户的主目录,当用户登录后,他的Shell将把该目录作为用户的工作目录。 在Unix/Linux系统中,超级用户root的工作目录为/root;而其它个人用户在/home目录下均有自己独立的工作环境,系统在该目录下为每 个用户配置了自己的主目录。个人用户的文件都放置在各自的主目录下。
(7)命令解释程序(Shell):Shell是当用户登录系统时运行的程序名称,通常是一个Shell程序的全路径名,
如/bin/bash。
注意的问题:(1)使用 awk
使用awk的话,中间文件需要生产两个,一个存放用户ID,一个存放用户名,到最后输出时会出现一个问题:利用一次for line in无法进行输出,因为需要同时读取两个文件的每行作为变量用echo输出;这是很少用的,也不知道如何使用,除非将两个文件合并到一起;或者awk一次直接生成一个文件;
另外使用awk也不能按下面答案将每行值依次作赋值处理,因为awk处理的是文件,否则报错
++ awk -F : '{print $5}' daemon,,,:/var/run/pulse:/bin/false
awk: cannot open daemon,,,:/var/run/pulse:/bin/false (No such file or directory),它是处理文件的,怎能去处理行呢?!处理行还是sed或者cut 吧!
(2)拷贝的代码出错
'.sh: line 5: syntax error near unexpected token `do
'.sh: line 5: `do
主要是由于windows上的所处理的文件换行符是dos格式的"\r\n"可以使用cat -v 文件名 来查看换行符是否是,如果是上述的,则行结尾会是^m需要转换成linux/unix格式的"\n"具体转换办法就是转换换行符可以用sed命令处理一下文件,命令如下:sed 's/\r//' 原文件 >转换后文件
(3)答案的输出并不完全正确,如:
Hello,mDNS,your UID is mDNS
Hello,daemon,,,,your UID is /bin/false
Hello,saned,your UID is 107
Hello,polkituser,your UID is 108
Hello,pulse,your UID is 109
Hello,daemon,,,,your UID is /bin/false
Hello,ftp,your UID is 110
Hello,daemon,,,,your UID is /bin/false
there are 43 users
UID一栏并不是数字,而是/ .../;
yee@Loong:~/shell$ cat pass
Debian-exim:x:104:110::/var/spool/exim4:/bin/false
hplip:x:105:7:HPLIP system user,,,:/var/run/hplip:/bin/false
polkituser:x:108:115:PolicyKit,,,:/var/run/PolicyKit:/bin/false
ftp:x:110:120:ftp daemon,,,:/srv/ftp:/bin/false
yee@Loong:~/shell$
只有4行,而实际读取时认为有7行
Loong:/home/yee/shell# sh b.sh
Hello,Debian-exim,your UID is 104
Hello,hplip,your UID is 105
Hello,system,your UID is system
Hello,user,,,,your UID is /bin/false
Hello,polkituser,your UID is 108
Hello,ftp,your UID is 110
Hello,daemon,,,,your UID is /bin/false
there are 7 users
为啥呢?
我们看下for line读取的过程:
1 #!/bin/bash
2 file=pass
3 num=0
4 for line in `cat $file`
5 do
6 echo "the $num line is $line"
7 num=$(($num+1))
8 done
yee@Loong:~/shell$ sh b.sh
the 0 line is Debian-exim:x:104:110::/var/spool/exim4:/bin/false
the 1 line is hplip:x:105:7:HPLIP
the 2 line is system
the 3 line is user,,,:/var/run/hplip:/bin/false
the 4 line is polkituser:x:108:115:PolicyKit,,,:/var/run/PolicyKit:/bin/false
the 5 line is ftp:x:110:120:ftp
the 6 line is daemon,,,:/srv/ftp:/bin/fal