第二十章 指令应用
20.1 基本 UNIX 指令
20.1.1 概论
在 UNIX 系统中,英文字母的大小写会被视为不同的东西,因此在输入指令或文件名时,大小写的差异要特别注意。一般指定用法的格式大概如下:
command [option(s)] [filename(s)]
command 是我们要执行的指令。[option] 是我们可以加的参数,用 [ ] 包起来的意思是可以有参数,也可以不加参数。而参数之后,有可能是档名 [filename],并不是所有指令都要加参数或文件名称,不过格式大部份都是依照这种顺序。另外,如果要在命令列中以一行输入多个指令,每个指令间可以用分号 ";" 分开。
20.1.2 man
查看指令的使用说明。例如我们要看指令 man 的使用说明:
$ man man
如果我们只知道一个关键词,却不知要使用哪一个指令,我们可以使用参数 k 来查询。例如我们要查询 firewall 相关的指令:
$ man -k firewall
man 在查询指令说明时,预设会去找 /usr/share/man 目录下的档案,如果我们要查询的指令说明文件并不位于该目录,我们可以使用参数 M 来指定目录名称。例如我们要查询指定 ab 的用法,该指令的说明文件放在 /usr/local/apache/man ,我们可以使用下列指定:
$ man -M /usr/local/apache/man ab
我们看 man 档案时,常会看到像 man(1) 的格式,其中 (1) 表示该指令的分类。依不同的类别,说明档会存在 /usr/share/man/ 不同的目录下。例如 (1) 的档案是在 man1 的目录中。如果同一个名称有二个不同的 man file,分别放在不同目录,我们也可以加上参数来看不同的档案。例如 crontab 有二个档案,一个是 crontab(1),另一个是 crontab(5)。当我们要看 crontab(5) 时,使用下列指令即可:
$ man 5 crontab
以下为 man 的类别:
类别 | 说明 |
1 | 一般指令。 |
2 | 系统呼叫 (System Calls)。 |
3 | 函式使用说明 (Library Functions)。 |
4 | 核心界面 (Kernel Interface)。 |
5 | 档案格式说明。 |
6 | 游戏使用说明。 |
7 | 杂项。 |
8 | 系统管理相关指令说明。 |
9 | 核心开发相关说明。 |
当您使用 man 指令时,所输出的结果大约如下:
LS(1) FreeBSD General Commands Manual LS(1) NAME ls -- list directory contents SYNOPSIS ls [-ABCFGHLPRTWZabcdfghiklmnopqrstuwx1] [file ...] DESCRIPTION For each operand that names a file of a type other than directory, ls displays its name as well as any requested, associated information. For each operand that names a file of type directory, ls displays the names of files contained within that directory, as well as any requested, asso- ciated information. ...... EXAMPLES The following is how to do an ls listing sorted by size (and shows why ls does not need a separate option for this): ls -l | sort -n +4 Additionally, the -r flag to sort(1) may be used to get the results sorted from largest to smallest (a reverse sort). SEE ALSO chflags(1), chmod(1), getfacl(1), sort(1), xterm(1), termcap(5), maclabel(7), symlink(7), getfmac(8), sticky(8) |
20.1.3 ls
查看目录信息。
在 UNIX 系统中,/ 代表根目录。当要使用某个目录下的目录时,每个目录之间要以 / 隔开。例如 /usr/bin 表示根目录下的 usr 目录下的 bin 这个目录。
另外,"." 和 ".." 也有特殊意义。"." 代表目前所在的目录,而 ".." 表示目前目录的上一层目录。 例如,../etc 表示上一层目录下的 etc 这个目录。
假设我们要查看根目录下有哪些档案:
$ ls /
在 shell 中,有些符号代表者特殊的意义,例如 * 表示万用字符,可以代表零个或多个字符,而 ? 代表一个字符。举例而言,当我们下达 ls 指令来例出档案时:
$ ls myfile* myfile myfile.exe myfile.txt myfile.txab myfile.abap
$ ls myfile.tx? myfile.txt
我们可以看到使用符号 * 时,会列出所有开头是 myfile 的档案;而使用 ? 时,只会例出 myfile.txt。
但是当我们使用万用字符来取代文件名称时,例如 ls /m*,它不仅例出符合目录,还会列出该目录下所有档案。这时候我们可以使用参数 d 来让 ls 只列出目录而不列出其目录下的档案:
$ ls -d /m*
ls 还有一些常用的参数如下,我们也可以同时使用多个参数,如 ls -lad:
参数 | 说明 |
a | 列出所有档案及目录,包含文件名开头为 "." 的隐藏档。 |
l | 列出档案的完整信息。 |
F | 依档案及目录的格式不同加上符号以供区格,例如目录则在目录名称后加上 / 符号;如果是可执行档则加上 *;如果是链接文件则加上 @。 |
20.1.4 cd
所在目录的切换。例如要切换目录到根目录:
$ cd /
切换目录的方式可以使用绝对路径或相对路径名称。绝对路径是指从根目录开始,该目录所在位置。例如 /usr/bin 就是一个绝对路径。而相对路径是指相对于目前所在路径而言,该目录的位置。例如 ../usr/bin 表示在上一层目录下的 usr/bin 这个目录。另外,符号 "~" 表示使用者的家目录,如果要回到自己的家目录,可以使用:
$ cd ~
如果只输入 cd 和 cd ~ 所代表的意义相同,都是回到自己的家目录。我们也可以符号 "~" 之后加上使用者名称,来代表该使用者的家目录。例如要切换到使用者 jack 的家目录:
$ cd ~jack
另外,如果您使用 tcsh 或 bash,您还可以使用 "-" 来切换二个目录:
$ cd /usr/local $ cd /etc $ cd - $ pwd /usr/local $ cd - $ pwd /etc
20.1.5 pwd
查看目前所在目录名称。例如:
$ pwd /root
20.1.6 cat
列出文字文件内容。假设我们要查看 /etc/rc.firewall 这个档案的内容,我们可以使用下列指令来列出:
$ cat /etc/rc.firewall
在 UNIX 系统中有一个转向输出的观念。我们可以把指令输出的结果转向到其它地方 (如档案)。一般内定的标准输出是屏幕,标准输入是键盘。我们可以使用 ">" 符号来将输出转到别的地方。例如,我们要将 ls 的输出结果存成档案 result.txt:
$ ls > result.txt
上面的指令会建立一个文件名为 result.txt 的档案,并将 ls 的结果置于该档中。如果所在目录本来就有一个文件名为 result.txt, 该档案原本的内容会被清除。如果我们不想清楚该档原本的内容,只是要把结果附加在原本的内容之后,可以使用 ">>" 。例如:
$ ls >> result.txt
我们可以使用 cat 指定来做简单的文字文件复制,例如将 /etc/rc.firewall 复制一份到自己根目录下的 firewall.txt:
$ cat /etc/rc.firewall > ~/firewall.txt
另外,我们也可以用 cat 来建立一个文字文件并手动编辑其内容:
$ cat >test.txt 在此输入文字 输入完后同时按 Ctrl+D 离开
20.1.7 more
以分页模式来列出文字文件内容。当使用 cat 时,如果档案超过一页,画面一闪而过,看都看不清楚。这时候我们可以使用 more 这个指令来将它分页输出。
$ more /etc/rc.firewall
输出后,我们可以按空格键来看下一页,或按 Q 来离开。
在 UNIX 系统中还有一个观念是 pipe 管道,就是将一个指令的输出结果作为另一个指令的输入。例如,我们要查看 /etc/ 下的所有档案完整信息,使用 ls -la /etc 时,发现信息超过一页,我们可以使用下列指令:
$ ls -la /etc | more
"|" 是位于键盘右上角退格键附近,和 "\" 同一个键的符号。
20.1.8 less
less 也是以分页来输出档案内容,和 more 不同的是它在输出档案全部内容后并不会离开。我们可以使用 page down 及 page up 键来查看,要离开时只要按 Q 键即可。
20.1.9 head
列出档案开头几行,预设是输出档案开头的十行:
$ head /etc/rc.firewall
我们也可以加上参数 n 来指定要输出多少行。例如,如果要输出前二十行:
$ head -n 20 /etc/rc.firewall
参数 c 让我们可以指定要输出档案开头多少 bytes(通常就是多少字符)。例如,如果要输出档案开头前十个字:
$ head -c 10 /etc/rc.firewall
20.1.10 tail
列出档案结尾几行,预设是十行:
$ tail /etc/rc.firewall
我们一样可以使用 -n 或 -c 来指定要输出多少行。
20.1.11 w
列出目前在在线的使用者信息、时间、正在执行的动作等。以下为 w 这个指令的输出范例:
# w 4:32下午 up 20 days, 23:54, 2 users, load averages: 0.00, 0.00, 0.00 USER TTY FROM LOGIN@ IDLE WHAT root v1 - 4:31下 - top alex p0 192.168.0.2 1:20下 - w
我们可以看到目前系统中有二个使用者登入,分别为 root 及 alex,并分别执行指令 top 及 w。使用者 alex 是使用 telnet 联机,所以我们可以看到他的来源 ip,但 root 从 console 登入,所以在 FROM 字段中并没有任何信息。除了在线使用者信息外,我们也可以看到系统已开机时间 (这个范例中是 20 天) 及系统负荷等。
20.1.12 who
列出目前在在线使用者的信息,输出的字段和 w 略有不同。其输出结果如下所示:
# who root ttyv1 5 2 16:31 alex ttyp0 5 2 13:20 (192.168.0.2)
20.1.13 date
列出及设定系统时间。如果我们要查看目前时间:
$ date 2004年 5月 2日 周日 16时37分12秒 CST
date 的输出结果可能是中文或英文,它会依照您在 .login 或 /etc/csh.login 对于 Locale 的设定而自动调整。
如果我们要设定时间为 2002 年 3 月 12 日 11 点 56 分,我们可以使用下列指令:
$ date 200203121156
20.1.14 cal
列出月历。如果要列出当月月历:
$ cal
我们也可以指定月份,例如列出 2002 年 3 月:
$ cal 3 2002
或是列出整年的月历,例如 2002 年:
$ cal 2002
20.1.15 echo
输出一个字符串到标准输出 (通常是屏幕)。例如:
$ echo string
我们也可以将输出结果转向到档案:
$ echo 'this is a test' > test.txt
这样在 test.txt 中就会有一行字符串 "this is a test"。
20.1.16 clear
清除屏幕。
20.2 系统管理
20.2.1 ps
在 UNIX 系统中,每个执行中的程序我们称之为程序 (Process),而 ps 这个指令就是用来看目前系统中正在执行的程序状态。
$ ps PID TT STAT TIME COMMAND 45836 p0 S 0:00.18 -tcsh (tcsh) 46104 p0 R+ 0:00.00 ps
PID 字段指的是 Process ID,就是这个程序的编号,每个程序的编号都是独一无二的;TT 是指登入的 tty;STAT 是该程序目前的状态;而 COMMAND 就是这个程序是那一个指令所执行。
ps 不加任何参数时,只输出自己在执行的程序,我们可以加上参数 -aux 来列出系统中所有使用者的程序及详细数据。
$ ps -aux USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND root 1 0.0 0.1 552 148 ?? ILs 4 2 0:00.17 int root 23 0.0 0.0 208 8 ?? IWs - 0:00.00 adjk alex 6167 0.0 0.8 1332 988 p0 I 7:46 0:00.21 -csh root 6241 0.0 0.8 1332 976 p0 D 8:03 0:00.17 _su
我们来看看第一行所代表的意义:
我们常的 ps 的参数有 auxww 等,其中 a 表示显示所有的行程,u 表示显示行程拥有者的信息,x 显示 deamon 的信息,ww 则是显示完整的 COMMAND 字段,不要将太长的部份截断。
20.2.2 kill
kill 指令会送出一个讯号 (Signal) 给指定的程序,程序在收到讯号之后,会依其要求来动作。可以使用的讯号如下:
SIG 名称 | 代码 | 意义 |
HUP | 1 | hang up,通常用来叫程序重新加载设定。 |
INT | 2 | interrup,通知程序中止。 |
QUIT | 3 | quit,通知程序离开。 |
ABRT | 6 | abort,中断程序。 |
KILL | 9 | non-catchable, non-ignorable kill,直接通知 kernel 把该程序移除。 |
ALRM | 14 | alarm clock。 |
TERM | 15 | software termination signal,通知程序结束。 |
一般而言,每一个程序都会预设接收到讯号是要执行什么动作,如果我们所送出的讯号在该程序中并没特别去处理它,则程序会自动结束程序。只有 root 可以管理所有程序,一般使用者只能对自己的程序作 kill。
假设我们要叫 PID 为 123 的程序结束:
$ kill -9 123
如果要通知程序重新加载设定文件:
$ kill -1 123
20.2.3 top
top 是一个好用的程序管理程序,我们可以利用它来秀出执行中的程序。进入 top 之后,我们可以按 "h" 来显示在线说明或按 "q" 来离开。
我们可以看到 top 的输出分成二个部份,最上方是目前关于行程的的系统状态。包含最后一个 PID (last pid)、系统负荷 (load average) 、已开机时间 (up)、总共有多少行程正在执行中、及 CPU 和内存的使用量等等。第二个部份和 ps 一样,列出 PID、行程的拥有者、及其它和行程相关的状态。
top 这个指令会每二秒自动更新一次。您可以按 "s" 来更改更新时间。
在 top 中,如果我们想要对某个程序执行 kill 的动作,只要按 "k" 再输入参数及 PID 即可。
20.2.4 systat
用来监看系统资源使用情形。它有几个常用的参数:
参数 | 说明 |
-iostat | 显示目前磁盘使用情形,以了解其存取的负荷。 |
-swap | 显示所有 swap 装置的使用情形。 |
-netstat | 显示目前网络联机情形。 |
-vm | 显示所有系统信息。 |
在上述各参数之后,我们还可以指定画面的更新时间,例如:
$ systat -vm 1
进入 systat 之后,我们可以按 Ctrl+L 来重绘画面,如果要离开 systat 可以先按 : 再打 quit 后离开。
20.2.5 watch
窥视某个 tty 窗口。
当使用者登入系统后,root 可以使用 watch 指令来取得使用者的窗口画面。也就是说当下达指令后,root 所看到的画面就会和该使用者一样。你可以观察该使用者在做些什么事,输出的结果又是什么。
只有超级使用者 root 可以执行 watch,在执行时,系统会自动加载 snp.ko 这个模块,或者您也可以先在 kernel 中加入下列的设定并重新编译核心:
pseudo-device snp |
并新增 snoop device,使用下列指令:
# cd /dev # ./MAKEDEV snp0 snp1 snp2 snp3
接下来就可 watch 指令了。首先,先下指令 w 来看一下站上有哪些使用者。指令结果的第二个字段部份,有使用者的 tty,例如 p0、v0 等,选定要监看的使用者后,使用 watch ttyp0 来监看该使用者,其中 ttyp0 即该使用者的 tty。你可以使用 CTRL+X 来切换不同的 tty,也可以使用 CTRL+G 离开回到自己的画面。
20.2.6 alias
这是 Shell 内建的指令,用来建立别名。例如,我们希望下达指令 abc 时,会执行 ls /etc,我们可以使用下列指令:
$ alias abc 'ls /etc' $ abc
我们可以使用 unalias 来取消所设定的别名,例如:
$ unalias abc
20.2.7 bg
将指定的程序放入背景中执行。当我们下达一个指令后,必须要等待该程序结束后才能输入下一个命令。如果该程序必须执行一段很长的时间,我们不想等程序结束,可以把它放到背景中执行。
在下达指令后,按 Ctrl+Z 来暂停程序,接着再执行 bg 即可将程序放到背景中执行。
$ sleep 1000 ^Z Suspended $ bg [1] sleep 1000 & $
我们也可以在所要执行的指令后面加上符号 "&",就可以将该程序放到背景执行:
$ sleep 1000 & [2] 46461
20.2.8 jobs
jobs 指令可以让我们查询目前有哪些程序在背景执行。如果加入参数 -l 可以得到 PID 的信息。
$ jobs -l [1] + 46459 Running sleep 1000 [2] - 46461 Running sleep 1500
20.2.9 fg
将指定的程序放到前景中执行。我们使用 jobs 看到目前在背景执行的程序之后,可以使用 fg 把它叫回前景。例如要叫回第一个在背景中执行的程序:
$ fg %1 sleep 1000
20.2.10 ntpdate
向时间服务器对时,只有超级使用者才能执行。我们可以使用 ntpdate 这个指令来向时间与频率国家标准实验室的时间服务器对时:
# ntpdate -b clock.stdtime.gov.tw 12 Mar 21:24:28 ntpdate[46494]: step time server 210.59.157.30 offset -8.939412 sec
20.2.11 sync
让系统暂存的数据强制存回硬盘。
20.2.12 shutdown
让系统在指定的时间关机。如果我们要立即关机可以下指令:
# shutdown now
有时候电力公司通知半夜十二点要停电,我们半夜又不想再去使用计算机,这时指定时间关机就发挥作用了。我们可以在白天时先下指令:
# shutdown 0203122359
0203122359 表示 2002 年 3 月 12 日 23:59,格式是 yymmddhhmm。在指定关机前五分钟系统会禁止使用者登入,并且会在 /var/run/ 目录下建立一个文件名为 nologin 的档案,内容为拒绝使用者登入时所要告诉使用者的讯息。如果我们要停止 shutdown ,可以送给它一个 SIGTERM,shutdown 程序在收到讯息后,在离开程序前会先删除 /var/run/nologin 这个档案。
# ps -ax|grep shutdown 46644 ?? S<s 0:00.00 shutdown 0203122359 # kill -15 46644
shutdown 还有一些参数:
参数 | 说明 |
-h | 系统停止服务,出现你现在可以放心关机了,但不关闭电源。 |
-p | 系统停止服务并关闭电源。 |
-r | 重新开机。 |
20.2.13 reboot
立即重新开机。
20.2.14 su
切换使用中的使用者身份。例如,我们要从一般使用者切换成 root:
$ su Password: #
一般使用者如果要具备切换成 root 的权限,必须在 /etc/group 将它加入在 wheel 群组中。例如,我们要该使用者 jack 可以使用 su 变成 root:
wheel:*:0:root,jack |
我们也可以使用 su 来切换成不同的使用者,如果加上参数 -l 表示模拟完全 login 的动作。例如,我们要仿真以使用者 foo 登入系统:
# su -l foo
我们也可以用参数 -c 来以不同使用者的身份执行一个指令,执行完后切换身份为原本的使用者。例如,我们要以 foo 的身份来执行 sleep 1000 这个指令并放到背景中执行:
# su foo -c 'sleep 1000&'
20.2.15 exit
这是 Shell 内建的指令,我们可以使用这个指令来注销系统或注销不同的 Shell。
20.2.16 dmesg
显示系统讯息暂存区 (message buffer) 的内容。如果是刚开机,暂存区的内容通常就是开机过程的记录。随着开机时间越来越长,讯息也会越来越多,开机过程的记录就会被其它讯息所取代。
20.2.17 lastcomm
显示使用者曾经执行过的指令。如果要使用这个指令,必须在 /etc/rc.conf 中加入下面这一行:
accounting_enable="YES" |
系统会在 /var/account 目录下建立记录文件,如果使用者很多的话,档案大小将会十分可观。
如果我们要查看使用者 foo 执行过哪些指令:
$ lastcomm foo
这些记录每天会自动转档,存成 acct.0, acct.1 等档案。如果我们要查询的是前一天的记录,可以使用参数 -f 来指定使用哪一个记录文件:
$ lastcomm foo -f /var/account/acct.0
20.2.18 crontab
安排定时执行工作。使用 crontab 可以让我们安排工作在指定的年、月、日、小时或分的周期来执行。
如果在 /var/cron 目录中有 allow 这个档案的话,只有使用者名称在档案中的人才可以使用 crontab。如果没有 allow 这个档案,但是有 deny 这个档案的话,被列在 deny 档案中的人不可以使用 crontab 来安排工作。如果二个档案都不存在,预设是所有人都可以执行。
我们可以使用 crontab -e 来编辑自己的排程, 使用 crontab -e 的格式,和 /etc/crontab 的格式不太一样,它少了执行者的字段,内定的指令执行者就是执行 crontab -e 的人。其格式如下:
MAILTO="" # 分 小时 天 月 星期几 指令 #minute hour mday month wday command # */5 * * * * setiathome # minute:代表一小时内的第几分,范围 0-59 # hour:代表一天中的第几小时,范围 0-23 # mday:代表一个月中的第几天,范围 1-31 # month:代表一年中第几个月,范围 1-12 # wday:代表星期几,范围 0-7 (0及7都是星期天) # who:要使用什么身份执行该指令 # command:所要执行的指令 # # 时的字段中如果是 *,表示每小时,天的字段中如果是 * 表示每天, # 依此类推字段中可以使用 "-" 来表示范围。 # 例如:在小时的字段中填 8-11,表示执行的时间是8,9,10,11共四次 # 例如:字段也可以用逗点来表示,以分的字段而言, 1,2,5,9 表示 # 将在 1,2,5,9 分时各执行一次。也可以写成像这样 1-2,12-14 # 表示在 1,2,12,13,14 分各执行一次。 # 又如:以 / 后面加数字表示每几分钟要执行一次。如在分的字段 # 填 0-23/2,表示 1-22 分之间,每隔二分钟执行一次 # 也就是 0,2,4,6,8,10,12,14,16,18,20,22 # 又如:在分的字段是 */5,表示每五分钟一次 # # 除此之外,也可以用一个开头为 @ 的字符串来表示各种意义 # 字符串 代表意义 # ------ ------- # @reboot 开机时路一次 # @yearly 每年跑一次,等于 "0 0 1 1 *". # @annually (和 @yearly 一样) # @monthly 每月跑一次,等于 "0 0 1 * *". # @weekly 每周跑一次,等于 "0 0 * * 0". # @daily 每天跑一次,等于 "0 0 * * *". # @midnight (和 @daily 一样) # @hourly 每小时跑一次,等于 "0 * * * *". # # 安排 crontab 时,应该要错开每个程序的执行时间,才不会 # 有一大堆程序同时执行。 |
执行 crontab 预设会将指令输出结果寄 email 给执行的使用者,如果我们不希望收到这些结果,可以在档案开头加上 MAILTO=""。
另外,我们也可以使用参数 -l 来列出目前执行的 crontab table。或使用参数 -r 来删除 table。
20.2.19 uptime
显示系统开机主机状况。例如:
$ uptime 10:51下午 up 8 days, 8:46, 2 users, load averages: 1.01, 1.02, 1.00
出现的信息依序为现在时间、共开机多久、开机时间、目前使用者有多少人、系统每 1 分钟、每 5 分钟、每 15 分钟的平均负荷 (load)。
20.2.20 sysctl
显示或设定核心 (kernel) 状态。使用参数 -a 可以列出目前 kernel 状态值的设定,例如:
$ sysctl -a
我们也可以使用参数 -w name=value 的方式来设定新的值。这些值如下表:
NAME | TYPE | 可否改变 |
kern.ostype | string | no |
kern.osrelease | string | no |
kern.osrevision | integer | no |
kern.version | string | no |
kern.maxvnodes | integer | yes |
kern.maxproc | integer | no |
kern.maxprocperuid | integer | yes |
kern.maxfiles | integer | yes |
kern.maxfilesperproc | integer | yes |
kern.argmax | integer | no |
kern.securelevel | integer | raise only |
kern.hostname | string | yes |
kern.hostid | integer | yes |
kern.clockrate | struct | no |
kern.posix1version | integer | no |
kern.ngroups | integer | no |
kern.job_control | integer | no |
kern.saved_ids | integer | no |
kern.boottime | struct | no |
kern.domainname | string | yes |
kern.filedelay | integer | yes |
kern.dirdelay | integer | yes |
kern.metadelay | integer | yes |
kern.osreldate | string | no |
kern.bootfile | string | yes |
kern.corefile | string | yes |
kern.logsigexit | integer | yes |
vm.loadavg | struct | no |
hw.machine | string | no |
hw.model | string | no |
hw.ncpu | integer | no |
hw.byteorder | integer | no |
hw.physmem | integer | no |
hw.usermem | integer | no |
hw.pagesize | integer | no |
hw.floatingpoint | integer | no |
hw.machine_arch | string | no |
machdep.console_device | dev_t | no |
machdep.adjkerntz | integer | yes |
machdep.disable_rtc_set | integer | yes |
user.cs_path | string | no |
user.bc_base_max | integer | no |
user.bc_dim_max | integer | no |
user.bc_scale_max | integer | no |
user.bc_string_max | integer | no |
user.coll_weights_max | integer | no |
user.expr_nest_max | integer | no |
user.line_max | integer | no |
user.re_dup_max | integer | no |
user.posix2_version | integer | no |
user.posix2_c_bind | integer | no |
user.posix2_c_dev | integer | no |
user.posix2_char_term | integer | no |
user.posix2_fort_dev | integer | no |
user.posix2_fort_run | integer | no |
user.posix2_localedef | integer | no |
user.posix2_sw_dev | integer | no |
user.posix2_upe | integer | no |
user.stream_max | integer | no |
user.tzname_max | integer | no |
假设我们的系统常出现 file: table is full 的讯息,我们可能要重新编译 kernel 并提高 maxuser 的值。或者我们也可以使用 sysctl 来做更动。首先我们看一下 kern.maxfiles 的值:
# sysctl kern.maxfiles kern.maxfiles: 2024
我们可以使用下列指令来提高它:
# sysctl -w kern.maxfiles=16244
如果我们要让这个设定在每次重开机时都自动加载,可以将该指令放到 /etc/rc.local 中,或是在 /etc/sysctl.conf 中加入下面这一行:
kern.maxfiles=16244 |
20.3 使用者管理
20.3.1 vipw
编修使用者密码文件。我们可以使用 vipw 这个指令来编辑使用者密码文件 /etc/master.passwd。如果我们编辑的内容不符合密码文件的格式,vipw 会提出警告。在修改完后,vipw 还会自动执行 pwd_mkdb 来更新系统数据库。
20.3.2 groups
这个指令可以秀出使用者属于哪一个群组。例如秀出使用者 jack 的群组:
$ groups jack wheel jack
20.3.3 adduser
请参考使用者管理一章关于 adduser 指令的介绍。
20.3.4 pwd_mkdb
如果我们直接以文书编辑软件来修改 /etc/master.passwd,在修改完后,必须执行 pwd_mkdb 来将更新的数据做成系统可以读取的数据库文件。pwd_mkdb 还会自动建立 /etc/passwd。
20.3.5 rmuser
删除使用者。使用 rmuser 将会进行下列动作:
必须要注意的是 rmuser 并不能删除 UID 为 0 的使用者 (如 root)。
20.3.6 passwd
变更使用者密码。如果不加使用者名称,则会变更所登入的使用者密码。用法如下:
# passwd jack
20.3.7 chpass
chfn, chsh, chpass 是一样的东西,用来更改使用者数据,如果以 root 来执行的话,其内容其实就是 master.passwd 的东西。如果以一般使用者执行,使用者可以使用这个指令来修改一些个人信息。
20.3.8 mesg
是否要允许其它使用者传送讯息给自己,如果不允许可以使用 mesg n,如果允许则是 mesg y。如果要执行 write 或 talk 必须设为 mesg y。
20.3.9 write
送出讯自给使用者。
用法:
write user [tty]
例如,要送出一段讯息给使用者 jack:
$ write jack
在 jack 的窗口会出现下列讯息:
Message from root@foo.com on ttyp0 at 01:39 ...
之后所打的每一个讯息都会出现在使用者 jack 的窗口。
20.3.10 last
显示使用者登入记录。例如:
$ last mary ttyp0 alex.alexwang 三 3/13 04:01 still logged in foo ttyp1 alex.alexwang 三 3/13 03:54 - 04:01 (00:06) jack ftp alex.alexwang 三 3/13 03:53 still logged in ben ttyp2 alex.alexwang 三 3/13 03:41 - 03:41 (00:00)
如果我们只要显示某位使用者的登入记录,我们可以在指令后面加上使用者登入账号。如果要显示某一个时间有哪些人在在线,我们可以使用参数 -d。例如,2002 年 3 月 10 日 23:45 时有哪些人在在线:
$ last -d 0203102345
last 预设会去找 /var/log/wtmp 这个记录文件,如果你想要使用其它记录文件可以加上参数 -f:
$ last -f /var/log/wtmp.0
20.4 档案系统管理
20.4.1 touch
改变档案存取的时间。例如:
$ ls -l -rw-r--r-- 1 jack staff 1520505 2/25 20:12 myfile.txt $ touch myfile.txt $ ls -l -rw-r--r-- 1 jack staff 1520505 3/13 15:21 myfile.txt
在上面的例子中,原本 myfile.txt 的存取日期是 2/25,我们使用 touch 之后,时间变成目前的时间了。如果使用 touch 时有加文件名称,但该档案不存在,touch 会建立一个空的档案。
我们也可以使用参数 -t 来指定要将存取时间设定为什么时候。例如,我们要设定为 2002 年 3 月 13 日 23:49:
$ touch -t 0203132349 myfile.txt
20.4.2 cp
复制档案或目录。
用法:
cp 来源 目的
我们可以使用 cp 来复制档案。例如,将 /etc/services 复制到 ~/services.txt:
$ cp /etc/services ~/services.txt
在上面的指令中,如果我们不指定目地档名,将 ~/services.txt 改成 ~/ 的话,预设会使用原来的档名,也就是将 /etc/services 复制到 ~/services。我们也可以同时复制多个档案到一个目录下,例如复制 /etc/services 及 /etc/rc.conf 到 ~/:
$ cp /etc/services /etc/rc.conf ~/
如果要复制目录,我们可以使用参数 -R 来将来源目录及其所有子目录复制到目的地:
$ cp -R sourdir tardir
20.4.3 ln
建立链接文件,所谓的链接文件就像在 Windows 下的快捷方式。如果我们希望同样一个档案或目录可以放在许多地方,我们可以使用 ln 来建立链接文件,这样一来实际存在的档案只有一个,但在许多地方都有链接。例如我们要将 /etc/services 链接到 ~/services:
$ ln /etc/services ~/services
当我们删除链接文件时并不会影响原本的档案。链接的方式可以分为 Hard link 及 Symbolic link,预设是使用 Hard link。二者的差别在于 Hard link 只能在相同的档案系统中建立链接,而且不能链接目录。我们在分割磁盘时,将不同的目录建立在不同的分割区上,假设 /etc/services 位于 ad0s1a 而使用者的家目录 ~/ 位于 ad0s1e,那么上面指定就不会生效。我们必需使用参数 -s 来建立 Symbolic link:
$ ln /etc/services ~/services ln: shit.txt: Cross-device link <---出现错误 $ ln -s /etc/services ~/services
我们也可以建立目录的链接:
$ ln -s /etc
在上面这个指令中,我们没有指定目的地,预设会在所在目录建立链接。
20.4.4 mkdir
建立目录。假设我们要在现行目录下建立一个目录 temp:
$ mkdir temp
如果我们要建立一个目录 /tmp/abc/tmp,在是在 /tmp 下并没有 abc 这个目录,我们就必须使用参数 -p 来自动建立:
$ mkdir /tmp/abc/tmp mkdir: /tmp/abc: No such file or directory $ $ mkdir -p /tmp/abc/tmp
20.4.5 rm
删除档案或目录。例如,我们要删除 temp 这个档案:
$ rm temp
如果要删除一个目录,必须使用参数 -r:
$ rm -r /tmp/abc
在删除档案或目录时,如果该档案是只读的,rm 会询问使用者是否真的要删除,我们可以使用参数 -f 让 rm 不要询问直接删除。或者我们也可以使用参数 -i 来让 rm 在删除档案时不管是否只读都要询问。
20.4.6 mv
搬移档案或目录。例如,我们要将 abc 这个档案搬到 /tmp/test:
$ mv abc /tmp/test
如果在 /tmp/test 存在,而且是一个目录的话,那么 abc 会被放在 /tmp/test/abc。 如果 /tmp/test 存在,而且是一个档案的话,则原来的 test 这个档案会被删除,改由 abc 取代之。
我们也可以利用 mv 来更改档案或目录名称。例如,我们要将 abc 改名为 cde:
$ mv abc cde
20.4.7 df
显示磁盘使用情形。
$ df Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/ad0s1a 201518 106212 79186 57% / /dev/ad1s1f 2595662 738200 1649810 31% /home /dev/ad0s1e 2761230 1615176 925156 64% /usr /dev/ad1s1e 503966 11546 452104 2% /var procfs 4 4 0 100% /proc
如果你觉得这样的输出结果不容易了解,可以使用参数 -h。我们也可以使用参数 -i 来看 i-node 的使用状况。
20.4.8 du
磁盘使用情形统计。如果我们要看所在目录使用多少磁盘空间,可以使用 du 这个指令。和 df 指定一样,我们可以加参数 -h 来显示较易阅读的统计格式:
$ du -h /etc
上述指令中,如果不加目录名称 /etc,预设是显示所在目录的使用统计。我们可以使用 du 这个指定来看系统中所有使用者的家目录使用情形:
# du -sh /home/* 750M /home/jack 60M /home/mary 2M /home/john
如果我们要查出目前系统中使用磁盘空间最大的前5名使用者,我们可以利用 du 搭配 sort 指令:
# du -s /home/* | sort -rn | head -5
20.4.9 chmod
改变档案目录权限。当我们使用 ls -l 时:
$ $ ls -l drwx------ 2 jack staff 512 2/27 02:14 mail/ drwxr-xr-x 2 jack staff 77824 2/22 05:37 txts/ -rw-r--r-- 1 jack staff 1520505 3/11 23:39 myfile.txt drwxr-xr-x 10 jack staff 512 3/11 05:28 software/
第一个字段代表的是档案的权限。该字段中共有十个字符,第一个字符是档案的类型,其后每三个字符为一组,分别代表使用者 (User)、所属群组 (Group)、其它人 (Other) 对于该档案的存取权限。
在使用 chmod 时,我们可以使用不同的字母来代表使用者 (User)、所属群组 (Group)、其它人 (Other):
举例而言,如果我们要让 myfile.txt 可以让所有人读取:
$ chmod a+r myfile.txt
如果我们要设定和 myfile.txt 拥有者同一个群组的人可以读取及写入该档:
$ chmod g=rw myfile.txt
如果要设定移除群组对 myfile.txt 写入的权限:
$ chmod g-w myfile.txt
另外,我们也可以使用数字来设定档案权限。r, w, x 都有其对映的数字,以每个使用不同对象为单位,将所对映的数字相加后所得到的数字就是该对象的权限。
图 20-1
例如,使用者的权限是 rwx,则其权限为 4+2+1=7。而群组的权限是 rx,其权限为 4+1=5。其它人的权限是 r,则以数字表示为 4。我们要设定 myfile.txt 这个档案的权限:
$ chmod 754 myfile.txt
我们来看一下关于目录的权限,目录的权限中,如果有 x 表示可以进入该目录,r 表示可以读取目录内容,而 w 则是可以对该目录写入。我们用下列的例子来说明目录权限的应用:
$ chmod 500 mydir $ cd mydir $ ls file.txt doc/ mp3/ <--- 权限为 500,没问题 $ cd .. $ chmod 400 mydir $ cd mydir mydir: Permission denied. <--- 权限为 400,只可以读不能进入 $ ls mydir file.txt doc/ mp3/ <--- 权限为 400,只可以读不能进入 $ chmod 100 mydir $ ls ls: .: Permission denied <--- 权限为 100,只能进入,不能看内容
我们上面提及的权限都是以三位数字来表示,另外我们也可以使用四位数字表示。所谓的四位数字是指在原本的三位数之前加上一个关于档案形态的设定。
假设我们要设定档案 myfile 可以被所有人读、写、执行,并设定 sticky:
$ chmod 1777 myfile
20.4.10 chown
改变档案的拥有人及群组。例如,我们要将目录 temp 的拥有人设为 jack,并设定群组为 staff:
# chown jack:staff temp
如果我们要将目录 temp 及其下所有档案及子目录的拥有人改变成 jack,可以使用参数 -R。
20.4.11 chflags
在 FreeBSD 还有一种特别的权限控制,称之为「flags」,这些 flags 的设定可以让我们用来保护特殊的档案。例如 /kernel 就是一个有设定 flag 的档案,我们可以使用 ls 加参数 -o 来显示:
# ls -ol /kernel -r-xr-xr-x 1 root wheel schg 2208222 2/26 02:09 kernel
flags 的设定凌驾于一般的权限设定,我们可以设定的主要 flags 及其所代表的意义如下:
flags | 意义 |
nodump | 档案不可以被 dump。(只有档案拥有者和 root 可以设定) |
sappnd | 档案只可以往后附加,不能删除。(只有 root 可以设定) |
schg | 档案不可以被更动,连 root 都不能删除。(只有 root 可以设定) |
uappnd | 档案只可以往后附加,不能删除。(档案拥有者和 root 才可设定) |
uchg | 档案不可以被更动。(档案拥有者和 root 才可设定) |
如果我们要解除所设定的 flags 只要在上述的 flgs 之前加上 no 即可,例如 nouchg。
用法:
chflags flags file
flags 的设定只有在 kernel security level 为 -1 或 0 时才可以被更改。如果 security level 为 1 或 2 时就不能更动 flags 了。
20.4.12 umask
当我们新增一个文字文件时,预设的档案权限是 644,而新增一个可执行档时,预设的权限是 755,也就是除了档案的拥有人外,其它人都可以读取或执行。这种预设权限是由 umask 来控制。
我们看一下 ~/.cshrc 的内容:
alias h history 25 alias ls ls -F # A righteous umask umask 22 |
这里的设定是 umask 22,也可以表示为 umask 022。022 这三个数字分别代表拥有者、群组、其它人的权限,建立档案是,将档案所有权限减去这些数字后,所得到的值就是档案的预设权限。
例如,一般档案权限的全部权限是 666,分别减去 022 后,得到的预设权限就是 644。而可执行档的权限是 777,分别减去 022 后,就是 755。
知道了 umask 之后,或许我们会希望将它设为 077。当然,设为 077 可能会产生一些问题,例如建立一个网页后,可能没有办法让它在使用者的浏览器中出现 (因为执行 apache 通常是以 nobody 的身份来执行)。
我们可以使用 umask 来显示目前的设定,或使用 umask num 来设定 umask:
$ umask 22 $ umask 77 $ umask 77
20.4.13 diff
比较二个档案的差异。例如:
$ diff file1 file2
20.4.14 wc
计算行数(lines)、字数(words)、位数(bytes)。我们可以使用这个指令来计算档案中的字数:
$ wc file.txt 77 103 1076 file.txt
输出结果分别代表行数、字数、位数,我们也可以使用参数 -l, -w, -c 来指定要输的是行数、字数、位数。我们可以将 wc 和 ls 一起使用来计算档案数:
$ ls /etc | wc -l 100
UNIX 指令的好处就在于我们可以自行组合指令创造出新的用法。
20.4.15 whereis
找寻程序的所在。whereis 预设会去寻找标准的二进制文件、说明文件、及原始程序代码档名符合的档案。所以我们不能用它来找一般文字文件。
$ whereis netstat netstat: /usr/bin/netstat /usr/share/man/man1/netstat.1.gz
20.4.16 which
在使用者的路径设定中寻找该程序。
$ which perl /usr/bin/perl
20.4.17 find
在指定目录下寻找档案。find 可以用的参数很多:
参数 | 说明 |
-name file | 寻找档名为 file 的档案。 |
-perm mode | 寻找权限为 mode 的档案。 |
-size n[c] | 寻找档案大小为 n block 的档案。c 表示字符数。 |
-atime n | 寻找在 n 天之前曾被存取的档案。 |
-mtime n | 寻找在 n 天之前曾被更改时间的档案。 |
-ctime n | 寻找在 n 天之前曾被更改内容的档案。 |
-newer file | 寻找修改时间比 file 新的档案。 |
找到之后,列出档名。 | |
-exec cmd {} \; | 找到之后执行 cmd 指令,在 cmd 最后一定要加上 \; 指令才会执行。如果 cmd 后有加 {} 表示执行的目录在该档案的目录。 |
-user name | 寻找拥有者为 name 的档案。 |
-group name | 寻找群组为 name 的档案。 |
-nouser | 寻找使用者名称不在 /etc/passwd 中的档案。 |
-nogroup | 寻找群组不在 /etc/group 中的档案。 |
例如,我们要从根目录开始,找出 services 这个档案所在位置:
$ find / -name service -print
如果我们要找出档案大小大于 10M 的档案:
$ find / -size +10485760c -print
如果我们要从所在目录开始,找出所有扩展名为 bak 的档案,并将它删除:
$ find . -name '*.bak' -exec rm {} \;
20.4.18 grep
找寻某一个字符串。例如,我们要找 /etc/ 下所有档案内容有 192.168 这个字符串的档案:
$ grep '192.168' /etc/*
我们也可以将 grep 和其它指令一起使用,例如要找出现在执行的程序中 inetd 的 PID:
$ ps -aux | grep inetd
20.4.19 tar
tape archiver。可以用来压缩备份文件。tar 的用法很多,我们仅介绍简单的压缩与解压缩。旧版的 tar 并不具有压缩功能,只是把档案包装成一个磁带文件。现在的 tar 都可以加上参数 -z 来顺便将档案压缩。
参数 | 说明 |
z | 压缩档案。 |
x | 取出档案。 |
c | 建立档案。 |
f file | 指定要处理的档案。 |
v | 观看过程。 |
u | 更新档案,新的档案会取代较旧的档案。 |
r | 将档案附加在原本的 tar 档之后。 |
t | 列出 tar 档的内容,但不真的解开。 |
例如,我们要将目录 temp 包装并压缩成 temp.tgz 这个档案:
$ tar zcvf temp.tgz temp
要解开 temp.tgz:
$ tar zxvf temp.tgz
20.4.20 fsck
检查并修复档案系统。我们可以指定要修复的档案系统,或不加任何参数来检查所有档案系统。fsck 当检查发现有问题时,预设会询问使用者是否要修复,我们也可以加参数 -y 来对于所有问题都回答 y。
# fsck /dev/ad0s1e
20.4.21 mount
挂入档案系统。如果要挂入的档案系统在 /etc/fstab 中有记录,则可以不必指定来源:
# mount /usr
参数 | 说明 |
-a | 挂入所在在 /etc/fstab 文件中记录的档案系统,有参数 noauto 者除外。 |
-o option | 设定档案系统参数。options 参数如下:
|
-t type | 设定要挂入的档案系统格式。如果要挂入的格式不是内定的格式,mount 会去呼叫 /sbin/mount_XXX 的程序来使用。例如要挂入 msdos 系统时,会去使用 /sbin/mount_msdos 这个程序。常用的格式如下:
|
例如我们要挂入一个 MS-DOS 的磁盘到 /mnt 的目录中:
# mount -t msdos /dev/fd0 /mnt
也可以使用 mount_msdos 指令:
# muont_msdos /dev/fd0 /mnt
我们在使用 CD-ROM 之前要先将它挂入,如果是使用光盘安装 FreeBSD,在 /etc/fstab 中有 CD-ROM 的设定,我们只要执行下列指令:
# mount /cdrom
如果没有,我们要知道光驱的代号,可以使用 dmesg 来查看开机记录文件中关于 CD-ROM 的讯息。假设我们的光盘代号是 cd0c,要将它挂入 /cdrom:
# mount -t cd9660 /dev/cd0c /cdrom
或是:
# mount_cd9660 /dev/cd0c /cdrom
20.4.22 umount
移除挂入的档案系统。只要输入 umount mount_point 即可。
CD-ROM 在挂入之后,每法取出光盘片。我们必须使用 umount 来移除才可以将光盘退出:
# umount /cdrom
20.5 网络相关指令
20.5.1 ping
检查远程系统的联机状态。ping 指令会送出 ICMP 封包到指定的主机,我们可以藉此来检查网络联机品质。
常用参数如下:
参数 | 说明 |
-c count | 指定要计算 count 次。 |
-s size | 指定每个封包大小为 size。 |
-t timeout | 指定 time out 时间。 |
-I interface | 如果目标主机地址是广播地址,而且我们有多个网接口,可以指定要使用哪一个接口。 |
例如我们要看 www.freebsd.org 的联机品质:
$ ping www.freebsd.org PING freefall.freebsd.org (216.136.204.21): 56 data bytes 64 bytes from 216.136.204.21: icmp_seq=0 ttl=54 time=458.986 ms 64 bytes from 216.136.204.21: icmp_seq=1 ttl=54 time=502.258 ms 64 bytes from 216.136.204.21: icmp_seq=2 ttl=54 time=491.489 ms ^C --- freefall.freebsd.org ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max/stddev = 458.986/484.244/502.258/18.393 ms
20.5.2 ifconfig
设定或检查网络接口。我们可以使用 ifconfig 来显示所有的网络接口,如果使用参数 -u 表示显示使用中的网络接口,而 -d 则是非运作中的接口。
我们也可以使用 ifconfig 来让网络接口运作或停用。
用法:
ifconfig [down|up] interface
假设我们要让网络卡 vr0 停用:
# ifconfig vr0 down
我们也可以使用 ifconfig 来设定网络上的 IP 地址。假设要设定 IP 为 192.168.0.1,而子网掩码为 255.255.255.0:
# ifconfig vr0 192.168.0.1 netmask 255.255.255.0
接着再使用 ifconfig 将 vr0 启用:
# ifconfig vr0 up
20.5.3 arp
显示 arp 地址。例如我们要显示 192.168.0.2 这台机器的网络卡号:
$ arp 192.168.0.1
20.5.4 traceroute
追踪由本机到某台主机所使用的路径。当我们使用 ping 来检查网络联机状况时,如果发现无法联机,我们可以使用 traceroute 来检查到底是网络上的哪一台主机有问题。
$ traceroute www.freebsd.org
20.5.5 netstat
显示网络状况。我们可以使用 netstat 来显示目前的联机状况。例如:
$ netstat -a Active Internet connections (including servers) Proto Recv-Q Send-Q Local Address Foreign Address (state) tcp4 0 20 www.ssh 198.z27z4z49.1780 ESTABLISHED tcp4 0 0 *.http *.* LISTEN tcp4 0 0 *.https *.* LISTEN tcp4 0 0 *.smtp *.* LISTEN tcp4 0 0 *.ssh *.* LISTEN tcp4 0 0 *.pop3 *.* LISTEN udp4 0 0 *.syslog *.* udp6 0 0 *.syslog *.* Active UNIX domain sockets Address Type Recv-Q Send-Q Inode Conn Refs Nextref Addr cd864e00 dgram 0 0 0 cd84ef0 0 cd864fc0 cd864fc0 dgram 0 0 0 cd84ef0 0 0
我们可以由上面的结果看到目前有一个使用者正使用 ssh 连到我们的网站。经由上表,我们可以看出我们所提供的服务有哪些,目前的使用情形如何。如果我们希望 Foreign Address 直接显示 IP ,可以使用参数 -n。
我们也可以使用参数 -i 来查看网络接口的使用情形:
$ netstat -ai Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Coll dc0 1500 00:80:c8:f6:b2:66 68890922 15997 8370716 1256 60296 33:33:c0:f6:78:e9 dc0 1500 fe80:1::280 fe80:1::281:c8ff: 0 - 0 - - ff02:1::2:c1f7:78e9(refs: 1) ff02:1::1 (refs: 1) ff02:1::1:ffe7:b266(refs: 1) lp0* 1500 0 0 0 0 0 lo0 16384 34050 0 34050 0 0
我们简单说明一下各字段所代表的意义:
20.5.6 sockstat
列出开启中的 socket。
$ sockstat USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS root telnetd 52897 0 tcp4 192.168.0.1:23 192.168.0.2:1969 root sshd 34063 4 tcp4 *:22 *:* nobody httpd 11670 16 tcp4 *:443 *:* nobody httpd 11670 17 tcp4 *:80 *:* root sendmail 117 4 tcp4 *:25 *:* root sendmail 117 5 tcp4 *:587 *:* root inetd 109 4 tcp4 *:21 *:* USER COMMAND PID FD PROTO ADDRESS mysql mysqld 170 6 stream /tmp/mysql.sock root sendmail 117 3 dgram syslogd[100]:3 root syslogd 100 3 dgram /var/run/log
每个字段所代表的意义如下:
20.5.7 mail
邮件处理程序。古老的 UNIX 邮件处理程序,这个程序对于不熟悉的人使用起来可能有点困难。但是这是在每个 UNIX 系统中都会有的程序,有时在没有其它选择的状况下,我们还是要使用它,至少要知道如何用它来收发信件。
假设我们要寄信给本机的 root:
$ mail root
如果我们要寄信给非本机的使用者,可以使用的收件人格式如下:
执行了 mail 之后,程序会先要求我们输入邮件主旨,输入后就可以开始打本文了。当完成本文的编辑之后,可以按 Ctrl+D 来将信件送出,或是按二次 Ctrl+C 取消。
我们也可以在执行 mail 时加上参数 -s "subject" 来指定主旨:
$ mail -s"hi, my friend" jack@mymail.com
如果我们想要将一个文字文件的内容当做本文送出,例如,我们可以先编辑一个文字文件 content.txt,接着使用下列方式:
$ mail -s "hi, my friend" jack@mymail.com < content.txt
说完了寄信,我们来了解一下如何收信。我们可以打 mail 来收信,如果是 root 还可以使用 mail -u user 来收使用者 user 的信件。
$ mail "/var/mail/root": 12 messages 10 unread >U 1 jack Fri Feb 22 03:02 42/690 "Hi friend" U 2 jack Fri Feb 22 03:02 74/2620 "see you tomorrow" U 3 mary@abc.com Sat Feb 23 03:06 570/33527 "don't forget" &
最后面出现的 & 为 mail 程序命令列的提示符号,在第一封信件开头有一个符号 ">" 表示目前作用中的信件。我们可以直接输入邮件编号来读取信件。另外,我们也可以输入下列指令:
指令 | 说明 |
h | 列出所有信件。 |
r | 回复目前作用中的信件。 |
n | 读取下一封信件。 |
p | 读取前一封信件。 |
pre [mail number] | 保留编号为 mail number 的信件在系统的 mailbox中 (/var/mail/)。程序 mail 对于己读取的信件,预设会将它搬到使用者家目录下的 mbox 中。我们如果日后还想要使用 pop3 来收该信件,就必须使用 pre 将该信件保留在系统的邮件目录中。 |
d | 删除作用中的信件。 |
z | 显示下一页信件列表。 |
q | 离开 mail。 |
20.5.8 telnnet
使用终端机远程登入网络上的主机。例如:
$ telnet bbs.mgt.ncu.edu.tw
如果在 telnet 时要能输入中文,必须加上参数 -8:
$ telnet -8 bbs.mgt.ncu.edu.tw
20.5.9 ssh
使用 telnet 并未加数据加密,我们很容易在不知不觉中泄露信息。如果要登入的主机有提供 ssh 登入的话,最好使用 ssh。
用法:
ssh username@hostname ssh hostname
例如:
$ ssh mary@140.115.77.11 $ ssh jack@mydomain.com $ ssh mydomain.com
只打 hostname 而没有使用者名称,登入名称会是你目前所用的使用者名称。
如果所联机的主机是第一次联机会出现下列一堆东西,打 "yes" 三个字即可:
The authenticity of host '140.115.77.11' can't be established. RSA key fingerprint is 13:93:8a:61:31:df:41:3f:7a:0a:77:ad:7e:49:e7:3f. Are you sure you want to continue connecting (yes/no)? yes
20.5.10 ftp
档案传输程序。如果要登入的主机允许昵名登入,我们使用参数 -a 来自动登入。
$ ftp -a freebsd.csie.nctu.edu.tw
进入 ftp 之后,会出现命令的提示列。我们可以输入以下的指令:
指令 | 说明 |
help 或 ? | 显示可以使用的指令。 |
ls | 列出远程所在目录的档案。 |
pwd | 显示远程所目录位置。 |
cd dir | 进入远程的 dir 目录。 |
get file | 从远程取回 file 档案。 |
put file | 将本地端的 file 档案上传到远程机器。 |
acsii | 使用文字模式传送档案。 |
binary | 使用二进制模式传送档案。 |
bye | 结束 ftp。 |
mget *.tgz | 取回远程所有名称为 *.tgz 的档案。 |
mput *.tgz | 上传本地所有 *.tgz 的档案。 |
!ls | 显示本地所在目录下的档案。 |
lpwd 或 !pwd | 显示本地所在目录。 |
lcd [dir] | 切换本地所在目录。 |
20.5.11 nslookup
网络主机名称查询。如果我们要查询 www.freebsd.org 所对映的 IP,最简单的用法是:
$ nslookup www.freebsd.org
我们也可以在上述指令最后面加上要查询的 DNS 主机:
$ nslookup www.freebsd.org dns.hinet.net
我们也可以使用 IP 来进入反查:
$ nslookup 216.136.204.21
20.5.12 dig
是另一个功能强大的主机名称查询工具。简单的用法如下:
$ dig -x 216.136.204.21 $ dig www.freebsd.org
20.5.13 tcpdump
显示或记录网络封包。如果要使用 tcpdump,在核心中必须要有 Berkeley packet filter,而且有 /dev/bpf*。如果没有请在核心设定中加入下面这一行,并重新编辑核心:
pseudo-device bpf |
执行 tcpdump 后,它会打开指定接口的 promiscuous mode (接口必须支持才有用)。所谓的 promiscuous mode(杂乱模式) 是指不管是否和本机有关的封包都接收进来,要达到这样的效果,必须藉由 bpf 的支持。
我们可以使用 tcpdump 来观察到达某一个网络接口的封包。例如我们要监看接口 vr0 的封包:
# tcpdump -i vr0
如果要结束直接按 Ctrl+C 即可。 如果限制封包数量,可以使用参数 -c。我们也可以使用参数 -w 来将捕捉到的封包存成档案,在这里我们存成 dump 这个档案:
# tcpdump -c 20 -i vr0 -w dump
使用参数 -r 可以读取储存的封包数据:
# tcpdump -r dump
为了控制 tcpdump 能 dump 我们想要的封包,我们还可以在指令最后加上一些 expression 来控制封包的记录。关于 expression 的用法请 man tcpdump。
另外介绍一个好用的分析工具 tcpshow, 我们可以使用 ports 来安装。
# cd /usr/ports/net/tcpshow # make install clean
接着就可以使用 tcpshow 来分析我们储存的封包内容:
# tcpshow <dump | more --------------------------------------------------------------- Packet 8 TIME: 04:53:10.938750 (0.011744) LINK: 00:80:2D:BB:65:38 -> 00:50:AA:00:DC:DD type=IP IP: tw -> 189 hlen=20 TOS=00 dgramlen=44 id=4353 MF/DF=0/1 frag=0 TTL=52 proto=TCP cksum=C56B TCP: port http -> 2451 seq=3298970558 ack=2899053999 hlen=24 (data=0) UAPRSF=010010 wnd=65535 cksum=8549 urg=0 DATA:---------------------------------------------------------------
我们简单的说明一下这个封包的内容。第一部份是时间 TIME。
第二行是 LINK,显示了来源 -> 目的地的网络卡号,另外经由 type=IP,我们知道这是一个 Ethernet_II 的 frame。
第三部份 IP,tw -> 189 是来源及目的地的地址。hlen 是 header length 大小是 20 bytes,而整个 IP 封包 (dgramlen) 的大小是 44 bytes。
第四部份是 TCP,来源是的 port 是 http (内定是 80),而目的地的 port 是 2451。接下来是 TCP 封包的 sequence number 及 acknowledgement 编号。TCP 的 header length 是 24,加上 IP 的 header 20 长度刚好是 44,和 dgramlen 的长度一样,这个封包应该没有破损。
最后,这个封包并没有包含其它的数据。