文件系统

pwd

pwd命令显示列出当前所在的目录。

1
$ pwd

cd

cd命令用来改变用户所在的目录。

1
2
3
4
5
6
7
8
# 进入用户的主目录
$ cd

# 进入前一个工作目录
$ cd -

# 进入指定用户的主目录
$ cd ~user_name

ls

ls目录可以显示指定目录的内容。不加参数时,显示当前目录的内容。

1
$ ls

上面命令显示当前目录的内容。

ls命令也可以显示指定文件是否存在。

1
2
$ ls foo.txt
foo.txt

-l参数可以显示文件的详细信息。

1
2
$ ls -l foo.txt
-rw-rw-r-- 1 me me 0 2016-03-06 14:52 foo.txt

上面命令输出结果的第一栏,是文件的类型和权限。

文件类型分为以下几种。

  • - 普通文件
  • d 目录
  • l 符号链接。注意,对于符号链接文件,剩余的文件属性总是”rwxrwxrwx”。
  • c 字符设备文件,指按照字节流处理数据的设备,比如调制解调器。
  • b 块设备文件,指按照数据块处理数据的设备,比如硬盘。

其他参数的用法。

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
# 显示多个目录的内容
$ ls ~ /usr

# -a --all 显示隐藏文件
$ ls -a

# -A 与-a类似,但是不显示当前目录和上一级目录两个点文件
$ ls -A

# -l 显示详细信息
$ ls -l

# -1 单列显示,每行只显示一个文件
$ ls -1

# -d 显示当前目录本身,而不是它的内容
# 通常与-l配合使用,列出一个目录本身的详细信息
$ ls -dl

# -F 目录名之后添加斜杠,可执行文件后面添加星号
$ ls -F

# -h 与-l配合使用,将文件大小显示为人类可读的格式

# -t 按文件修改时间排序,修改晚的排在前面
$ ls -t

# -s 按文件大小排序,

# --reverse 显示结果倒序排列
$ ls -lt --reverse

如果只显示一个目录里面的子目录,不显示文件,可以使用下面这些命令。

1
2
3
4
5
6
7
8
9
10
11
# 只显示常规目录
$ ls -d */
$ ls -F | grep /
$ ls -l | grep ^d
$ tree -dL 1

# 只显示隐藏目录
$ ls -d .*/

# 隐藏目录和非隐藏目录都显示
$ find -maxdepth 1 -type d

另一个简便方法是利用自动补全功能,先键入cd命令,然后连按两下tab键。

stat

stat命令是加强版的ls命令,可以显示一个文件的详细信息。

1
2
3
4
5
6
7
8
$ stat timestamp
File: 'timestamp'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 803h/2051d Inode: 14265061 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1001/ me) Gid: ( 1001/ me)
Access: 2008-10-08 15:15:39.000000000 -0400
Modify: 2008-10-08 15:15:39.000000000 -0400
Change: 2008-10-08 15:15:39.000000000 -0400

touch

touch用来设置或更新文件的访问,更改,和修改时间。然而,如果一个文件名参数是一个 不存在的文件,则会创建一个空文件。

1
$ touch timestamp

上面命令创建了一个名为timestamp空文件。如果该文件已经存在,就会把它的修改时间设置为当前时间。

1
2
$ mkdir -p playground/dir-{00{1..9},0{10..99},100}
$ touch playground/dir-{00{1..9},0{10..99},100}/file-{A..Z}

上面的命令创建了一个包含一百个子目录,每个子目录中包含了26个空文件。

file

file命令显示指定文件的类型。

1
2
$ file picture.jpg
picture.jpg: JPEG image data, JFIF standard 1.01

chmod

chmod命令用于更改文件的权限,是“change mode”的缩写。

1
$ chmod 600 foo.txt

上面命令将foo.txt的权限改成了600。

chmod还可以接受四个缩写,为不同的对象单独设置权限。

  • u 所有者“user”的简写
  • g 用户组“group”的缩写
  • o 其他所有人“others”的简写
  • a 所有人“all”的简写
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 为所有者添加可执行权限
$ chmod u+x foo.txt

# 删除所有者的可执行权限
$ chmod u-x foo.txt

# 为所有人添加可执行权限,等价于 a+x
$ chmod +x foo.txt

# 删除其他人的读权限和写权限。
$ chmod o-rw foo.txt

# 设定用户组和其他人的权限是读权限和写权限
$ chmod go=rw foo.txt

# 为所有者添加执行权限,设定用户组和其他人为读权限和写权限,多种设定用逗号分隔
$ chmod u+x,go=rw foo.txt

添加权限。

  • +x 添加执行权限
  • +r 设置读权限
  • +w 设置写权限
  • +rwx 设置所有读、写和执行权限。

删除权限只需将+更改为-,就可以删除任何已设置的指定权限。可以使用-R(或--recursive)选项来递归地操作目录和文件。

设置精确权限,可以使用=代替+-来实现此操作。如果想为用户、组或其他用户设置不同的权限,可以使用逗号将不同表达式分开(例如ug=rwx,o=rx)。

由于一共有3种可能的权限。也可以使用八进制数代替符号来设置权限。通过这种方式设置的权限最多使用3个八进制数。第1个数定义用户权限,第2个数定义组权限,第3个数定义其他权限。这3个数中的每一个都通过添加想要的权限设置来构造:读 (4)、写 (2) 和执行 (1)。

  • rwx 7
  • rw- 6
  • r-x 5
  • r– 4
  • -wx 3
  • -w- 2
  • –x 1
  • — 0

umask

umask用来查看和设置权限掩码。

1
2
$ umask
0022

上面命令显示当前系统之中,默认的文件掩码是0022,转为二进制就是000 000 010 010

可以看到,这个掩码是一个12位的二进制数,后面的9位分别代表文件三种使用对象的三类权限。只要对应位置上是1,就表示关闭该项权限,所以010就表示关闭读权限。

新建文件时,通常不会带有执行权限,也就是说,新建文件的默认权限是rw-rw-rw-。如果文件掩码是0022,那么用户组和其他人的写权限也会被拿掉。

1
2
3
$ touch new.txt
$ ls -l new.txt
-rw-r--r-- 1 me me 0 2016-03-06 14:52 new.txt

上面代码中,new.txt的用户组和其他人的写权限就没了。

umask后面跟着参数,就表示设置权限掩码。

1
$ umask 0000

上面命令将权限掩码设为0000,实际上就是关闭了权限掩码。

umask命令设置的掩码值只能在当前Shell会话中生效,若当前Shell会话结束后,则必须重新设置。

du

du命令用于查看指定目录的大小。

1
$ du -hs /path/to/directory

显示第一层子目录的大小。

1
$ du -h --max-depth=1 /path/to/folder

参数的含义。

  • -h 表示人类可读的格式
  • -s 表示总结信息,否则会显示该目录内所有文件和子目录的信息。

tree命令也可以显示子目录大小。

1
$ tree --du -h /path/to/directory

md5sum

md5sum命令用来显示一个文件的md5校验码。

1
2
$ md5sum image.iso
34e354760f9bb7fbf85c96f6a3f94ece image.iso

locate

locate程序快速搜索本机的路径名数据库,并且输出每个与给定字符串相匹配的文件名。

1
2
3
4
5
6
7
$ locate bin/zip
/usr/bin/zip
/usr/bin/zipcloak
/usr/bin/zipgrep
/usr/bin/zipinfo
/usr/bin/zipnote
/usr/bin/zipsplit

locate数据库由另一个叫做updatedb的程序创建。大多数装有 locate 的系统会每隔一天运行一回 updatedb 程序。因为数据库不能被持续地更新,所以当使用 locate 时,你会发现 目前最新的文件不会出现。为了克服这个问题,可以手动运行 updatedb 程序, 更改为超级用户身份,在提示符下运行 updatedb 命令。

locate支持正则查找。--regexp参数支持基本的正则表达式,--regex参数支持扩展的正则表达式。

1
$ locate --regex 'bin/(bz|gz|zip)'

find

locate程序只能依据文件名来查找文件,而find程序能基于各种各样的属性,搜索一个给定目录(以及它的子目录),来查找文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 输出当前目录的所有子目录和文件(含子目录)
$ find
$ find .

# 显示当前目录的文件总数
$ find . | wc -l

# 当前目录的子目录总数
$ find . -type d | wc -l

# 当前目录的文件总数(不含子目录)
$ find . -type f | wc -l

# 当前目录的文件名匹配“*.JPG”且大于1M的文件总数
$ find . -type f -name "\*.JPG" -size +1M | wc -l

-type参数支持的文件类型。

  • b 块设备文件
  • c 字符设备文件
  • d 目录
  • f 普通文件
  • l 符号链接

-size参数支持的文件大小类型。

  • b 512 个字节块。如果没有指定单位,则这是默认值。
  • c 字节
  • w 两个字节的字
  • k 千字节
  • M 兆字节
  • G 千兆字节

find程序支持的查询参数。

  • -cmin n 匹配的文件和目录的内容或属性最后修改时间正好在 n 分钟之前。 指定少于 n 分钟之前,使用 -n,指定多于 n 分钟之前,使用 +n。
  • -cnewer file 匹配的文件和目录的内容或属性最后修改时间早于那些文件。
  • -ctime n 匹配的文件和目录的内容和属性最后修改时间在 n*24小时之前。
  • -empty 匹配空文件和目录。
  • -group name 匹配的文件和目录属于一个组。组可以用组名或组 ID 来表示。
  • -iname pattern 就像-name 测试条件,但是不区分大小写。
  • -inum n 匹配的文件的 inode 号是 n。这对于找到某个特殊 inode 的所有硬链接很有帮助。
  • -mmin n 匹配的文件或目录的内容被修改于 n 分钟之前。
  • -mtime n 匹配的文件或目录的内容被修改于 n*24小时之前。
  • -name pattern 用指定的通配符模式匹配的文件和目录。
  • -newer file 匹配的文件和目录的内容早于指定的文件。当编写 shell 脚本,做文件备份时,非常有帮助。 每次你制作一个备份,更新文件(比如说日志),然后使用 find 命令来决定自从上次更新,哪一个文件已经更改了。
  • -nouser 匹配的文件和目录不属于一个有效用户。这可以用来查找 属于删除帐户的文件或监测攻击行为。
  • -nogroup 匹配的文件和目录不属于一个有效的组。
  • -perm mode 匹配的文件和目录的权限已经设置为指定的 mode。mode 可以用 八进制或符号表示法。
  • -samefile name 相似于-inum 测试条件。匹配和文件 name 享有同样 inode 号的文件。
  • -size n 匹配的文件大小为 n。
  • -type c 匹配的文件类型是 c。
  • -user name 匹配的文件或目录属于某个用户。这个用户可以通过用户名或用户 ID 来表示。
  • -depth 指导 find 程序先处理目录中的文件,再处理目录自身。当指定-delete 行为时,会自动 应用这个选项。
  • -maxdepth levels 当执行测试条件和行为的时候,设置 find 程序陷入目录树的最大级别数
  • -mindepth levels 在应用测试条件和行为之前,设置 find 程序陷入目录数的最小级别数。
  • -mount 指导 find 程序不要搜索挂载到其它文件系统上的目录。
  • -regex 指定正则表达式
1
2
# 找出包括空格或其它不规范字符的文件名或路径名
$ find . -regex '.*[^-\_./0-9a-zA-Z].*'

find程序还支持逻辑操作符。

  • -and 如果操作符两边的测试条件都是真,则匹配。可以简写为 -a。 注意若没有使用操作符,则默认使用 -and。
  • -or 若操作符两边的任一个测试条件为真,则匹配。可以简写为 -o。
  • -not 若操作符后面的测试条件是真,则匹配。可以简写为一个感叹号(!)。
  • () 把测试条件和操作符组合起来形成更大的表达式。这用来控制逻辑计算的优先级。注意 因为圆括号字符对于 shell 来说有特殊含义,所以在命令行中使用它们的时候,它们必须 用引号引起来,才能作为实参传递给 find 命令。通常反斜杠字符被用来转义圆括号字符。
1
2
3
4
5
# 或关系
( expression 1 ) -or ( expression 2 )

# 找出不是600权限的文件,或者不是700权限的目录
$ find ~ \( -type f -not -perm 0600 \) -or \( -type d -not -perm 0700 \)

find程序的逻辑表达式,具有“短路运算”的特点,即对于expr1 -operator expr2这个表达式,expr2不一定执行。这是为了提高运行速度。

  • expr1 为真,且操作符为-and,expr2 总是执行
  • expr1 为假,且操作符为-and,expr2 从不执行
  • expr1 为真,且操作符为-or,expr2 从不执行
  • expr1 为假,且操作符为-or,expr2 总是执行

为了方便执行一些常见操作,find程序定义了一些预定义操作。

  • -delete 删除当前匹配的文件。
  • -ls 对匹配的文件执行等同的 ls -dils 命令。并将结果发送到标准输出。
  • -print 把匹配文件的全路径名输送到标准输出。如果没有指定其它操作,这是 默认操作。
  • -quit 一旦找到一个匹配,退出。
1
2
3
4
5
6
7
# 找到匹配的文件,并显示在标准输出
# -print 是默认操作,可以省略
$ find . -print

# 删除后缀名为BAK的文件
# 执行 delete 操作前,最好先执行 print 操作,确认要删除哪些文件
$ find . -type f -name '*.BAK' -delete

预定义操作可以与逻辑表达式,结合使用。

1
$ find ~ -type f -and -name '*.BAK' -and -print

除了预定义操作以外,用户还可以使用-exec参数自定义操作。

1
-exec command {} ;

上面的命令中,command是一个命令行命令,{}用来指代当前路径,分号表示命令结束。

1
2
# 预定义的 -delete 操作,等同于下面的操作
-exec rm '{}' ';'

-exec使用时,每次找到一个匹配的文件,会启动一个新的指定命令的实例。

1
$ find ~ -type f -name 'foo*' -exec ls -l '{}' ';'

执行上面的命令,ls程序可能会被调用多次。

1
2
$ ls -l file1
$ ls -l file2

如果想改成ls程序只调用一次,要把find命令里面的分号,改成加号。

1
2
3
$ ls -l file1 file2
# 相当于
$ find ~ -type f -name 'foo*' -exec ls -l '{}' +

xargs

xargs命令从标准输入接受输入,并把输入转换为一个特定命令的参数列表。

1
$ find ~ -type f -name 'foo\*' -print | xargs ls -l

硬件操作

df

df命令查看硬盘信息。

1
2
3
4
5
$ df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda2 15115452 5012392 9949716 34% /
/dev/sda5 59631908 26545424 30008432 47% /home
/dev/sda1 147764 17370 122765 13% /boot

free

free命令查看内存占用情况。

1
2
3
4
5
$ free
total used free shared buffers cached
Mem: 513712 503976 9736 0 5312 122916
-/+ buffers/cache: 375748 137964
Swap: 1052248 104712 947536

硬盘

文件/etc/fstab配置系统启动时要挂载的设备。

1
2
3
LABEL=/12               /               ext3        defaults        1   1
LABEL=/home /home ext3 defaults 1 2
LABEL=/boot /boot ext3 defaults 1 2

输出结果一共有6个字段,含义依次如下。

  • 设备名:与物理设备相关联的设备文件(或设备标签)的名字,比如说/dev/hda1(第一个 IDE 通道上第一个主设备分区)。
  • 挂载点:设备所连接到的文件系统树的目录。
  • 文件系统类型:Linux 允许挂载许多文件系统类型。
  • 选项:文件系统可以通过各种各样的选项来挂载。
  • 频率:一位数字,指定是否和在什么时间用 dump 命令来备份一个文件系统。
  • 次序:一位数字,指定 fsck 命令按照什么次序来检查文件系统。

mount

mount不带参数时,显示当前挂载的文件系统。

1
2
3
4
5
6
$ mount
/dev/sda2 on / type ext3 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
/dev/sda5 on /home type ext3 (rw)

这个列表的格式是:设备 on 挂载点 type 文件系统类型(可选的)。

mount带参数时,用于将设备文件挂载到挂载点,-t参数用来指定文件系统类型。

1
2
3
4
$ mount -t iso9660 /dev/hdc /mnt/cdrom

# 挂载一个iso文件
$ mount -t iso9660 -o loop image.iso /mnt/iso_image

umount

umount命令用来卸载设备。

1
2
3
$ umount [设备名]

$ umount /dev/hdc

fdisk

fdisk命令用于格式化磁盘。

1
2
$ sudo umount /dev/sdb1
$ sudo fdisk /dev/sdb

mkfs

mkfs命令用于在一个设备上新建文件系统。

1
2
$ sudo mkfs -t ext3 /dev/sdb1
$ sudo mkfs -t vfat /dev/sdb1

fsck

fsck命令用于检查(修复)文件系统。

1
$ sudo fsck /dev/sdb1

dd

dd命令用于将大型数据块,从一个磁盘复制到另一个磁盘。

1
2
3
4
5
6
7
8
9
10
$ dd if=input_file of=output_file [bs=block_size [count=blocks]]

# 将 /dev/sdb 的所有数据复制到 /dev/sdc
$ dd if=/dev/sdb of=/dev/sdc

# 将 /dev/sdb 的所有数据拷贝到一个镜像文件
$ dd if=/dev/sdb of=flash_drive.img

# 从cdrom制作一个iso文件
$ dd if=/dev/cdrom of=ubuntu.iso

dmidecode

dmidecode命令用于输出BIOS信息。

1
$ sudo dmidecode

以上命令会输出全部BIOS信息。为了便于查看,往往需要指定所需信息的类别。

  • 0 BIOS
  • 1 System
  • 2 Base Board
  • 3 Chassis 4 Processor
  • 5 Memory Controller
  • 6 Memory Module
  • 7 Cache
  • 8 Port Connector
  • 9 System Slots
  • 10 On Board Devices
  • 11 OEM Strings
  • 12 System Configuration Options
  • 13 BIOS Language
  • 14 Group Associations
  • 15 System Event Log
  • 16 Physical Memory Array
  • 17 Memory Device
  • 18 32-bit Memory Error
  • 19 Memory Array Mapped Address
  • 20 Memory Device Mapped Address
  • 21 Built-in Pointing Device
  • 22 Portable Battery
  • 23 System Reset
  • 24 Hardware Security
  • 25 System Power Controls
  • 26 Voltage Probe
  • 27 Cooling Device
  • 28 Temperature Probe
  • 29 Electrical Current Probe
  • 30 Out-of-band Remote Access
  • 31 Boot Integrity Services
  • 32 System Boot
  • 33 64-bit Memory Error
  • 34 Management Device
  • 35 Management Device Component
  • 36 Management Device Threshold Data
  • 37 Memory Channel
  • 38 IPMI Device
  • 39 Power Supply

查看内存信息的命令如下。

1
2
3
$ sudo dmidecode -t 17
# 或者
$ dmidecode --type 17

以下是其他一些选项。

1
2
3
4
5
# 查看BIOS信息
$ sudo dmidecode –t 0

# 查看CPU信息
$ sudo dmidecode -t 4

dmidecode也支持关键词查看,关键词与类别的对应关系如下。

  • bios 0, 13
  • system 1, 12, 15, 23, 32
  • baseboard 2, 10
  • chassis 3
  • processor 4
  • memory 5, 6, 16, 17
  • cache 7
  • connector 8
  • slot 9

查看系统信息的命令如下。

1
$ sudo dmidecode -t system

lspci

lspci命令列出本机的所有PCI设备。

1
$ lspci

该命令输出信息的格式如下。

1
03:00.0 Unassigned class [ff00]: Realtek Semiconductor Co., Ltd. RTS5209 PCI Express Card Reader (rev 01)

输出信息一共分成三个字段。

  • Field 1:PCI bus slot 的编号
  • Field 2:PCI slot的名字
  • Field 3:设备名和厂商名

如果想查看更详细信息,可以使用下面的命令。

1
$ lspci -vmm

lsusb

lsusb命令用于操作USB端口。

下面命令列出本机所有USB端口。

1
$ lsusb

它的输出格式如下。

1
Bus 002 Device 003: ID 0781:5567 SanDisk Corp. Cruzer Blade

各个字段的含义如下。

  • Bus 002 : bus编号
  • Device 003:bus 002连接的第三个设备
  • ID 0781:5567:当前设备的编号,冒号前是厂商编号,冒号后是设备编号
  • SanDisk Corp. Cruzer Blade:厂商和设备名

找出本机有多少个USB接口可用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ find /dev/bus/
/dev/bus/
/dev/bus/usb
/dev/bus/usb/002
/dev/bus/usb/002/006
/dev/bus/usb/002/005
/dev/bus/usb/002/004
/dev/bus/usb/002/002
/dev/bus/usb/002/001
/dev/bus/usb/001
/dev/bus/usb/001/007
/dev/bus/usb/001/003
/dev/bus/usb/001/002
/dev/bus/usb/001/001

查看某个USB设备的详细情况。

1
$ lsusb -D /dev/bus/usb/002/005

查看所有设备的详细情况。

1
$ lsusb -v

查看USB端口的版本。

1
$ lsusb -v | grep -i bcdusb

主机管理

hostname命令

hostname命令返回当前服务器的主机名。

1
$ hostname

命名管道

在大多数类似 Unix 的操作系统中,有可能创建一种特殊类型的文件,叫做命名管道。命名管道用来在 两个进程之间建立连接,也可以像其它类型的文件一样使用。

命令管道的行为类似于文件,但实际上形成了先入先出(FIFO)的缓冲。和普通(未命令的)管道一样, 数据从一端进入,然后从另一端出现。通过命令管道,有可能像这样设置一些东西:

1
process1 > named_pipe

1
process2 < named_pipe

表现出来就像这样:

1
process1 | process2

设置一个命名管道

使用 mkfifo 命令能够创建命令管道:

1
2
3
$ mkfifo pipe1
$ ls -l pipe1
prw-r--r-- 1 me me 0 2009-07-17 06:41 pipe1

这里我们使用 mkfifo 创建了一个名为 pipe1 的命名管道。使用 ls 命令,我们查看这个文件, 看到位于属性字段的第一个字母是 “p”,表明它是一个命名管道。

使用命名管道

为了演示命名管道是如何工作的,我们将需要两个终端窗口(或用两个虚拟控制台代替)。 在第一个终端中,我们输入一个简单命令,并把命令的输出重定向到命名管道:

1
$ ls -l > pipe1

我们按下 Enter 按键之后,命令将会挂起。这是因为在管道的另一端没有任何接受数据。当这种现象发生的时候, 据说是管道阻塞了。一旦我们绑定一个进程到管道的另一端,该进程开始从管道中读取输入的时候,这种情况会消失。 使用第二个终端窗口,我们输入这个命令。

1
$ cat < pipe1

然后产自第一个终端窗口的目录列表出现在第二个终端中,并作为来自 cat 命令的输出。在第一个终端 窗口中的 ls 命令一旦它不再阻塞,会成功地结束。

进程管理

ps

ps命令用来列出进程信息。

1
2
3
4
$ ps
PID TTY TIME CMD
5198 pts/1 00:00:00 bash
10129 pts/1 00:00:00 ps

不带任何参数时,ps只列出与当前Session相关的进程。输出结果中,PID是进程ID、TTY是进程的终端号(如果显示?,则表示进程没有终端),TIME是消耗的CPU时间,CMD是触发进程的命令。

x参数列出所有进程的详细信息,包括不在当前Session的信息。

1
2
3
4
$ ps x
PID TTY STAT TIME COMMAND
2799 ? Ssl 0:00 /usr/libexec/bonobo-activation-server –ac
2820 ? Sl 0:01 /usr/libexec/evolution-data-server-1.10 --

这时的输出结果,会多出STAT一栏,表示状态。它的各种值如下。

  • R 正在运行或准备运行
  • S 正在睡眠,即没有运行,正在等待一个事件唤醒
  • D 不可中断睡眠。进程正在等待 I/O,比如磁盘驱动器的I/O
  • T 已停止,即进程停止运行
  • Z “僵尸”进程。即这是一个已经终止的子进程,但父进程还没有清空它(没有把子进程从进程表中删除)
  • < 高优先级进程。这可能会授予一个进程更多重要的资源,给它更多的 CPU 时间。
  • N 低优先级进程。一个低优先级进程(一个“好”进程)只有当其它高优先级进程执行之后,才会得到处理器时间。

aux参数可以显示更多信息。

1
2
3
4
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 2136 644 ? Ss Mar05 0:31 init
root 2 0.0 0.0 0 0 ? S&lt; Mar05 0:00 [kt]

输出结果包含的列的含义如下。

  • USER 用户ID,表示进程的所有者
  • %CPU 百分比表示的 CPU 使用率
  • %MEM 百分比表示的内存使用率
  • VSZ 虚拟内存大小
  • RSS 进程占用的物理内存的大小,以千字节为单位。
  • START 进程运行的起始时间。若超过24小时,则用天表示。

top

top命令可以查看机器的当前状态。

1
$ top

它的输出结果分为两部分,最上面是系统概要,下面是进程列表,以 CPU 的使用率排序。

输出结果是动态更新的,默认每三分钟更新一次。

jobs

jobs命令用来查看后台任务。

1
2
$ jobs
[1]+ Running xlogo &

输出结果之中,每个后台任务会有一个编号。上面结果中,xlogo的编号是1+表示正在运行。

fg

fg命令用于将后台任务切换到前台。

1
$ fg %1

fg命令之后,跟随着一个百分号和工作序号,用来指定切换哪一个后台任务。如果只有一个后台任务,那么fg命令可以不带参数。

bg

bg命令用于将一个暂停的前台任务,转移到后台。只有暂停的任务,才能使用bg命令,因为正在运行的任务,命令行是无法输入的。

1
$ bg %1

Ctrl + z可以暂停正在运行的前台任务。

kill

kill命令用于杀死进程。它的参数是进程ID。

1
$ kill 28401

kill命令的实质是操作系统向进程发送信号。在使用 Ctrl-c 的情况下,会发送一个叫做 INT(中断)的信号;当使用 Ctrl-z 时,则发送一个叫做 TSTP(终端停止)的信号。

kill命令可以用来向进程发送指定信号。

1
$ kill [-signal] PID

下面是常见信号。

  • HUP:编号1,表示挂起。发送这个信号到前台程序,程序会终止。许多守护进程也使用这个信号,来重新初始化。这意味着,当发送这个信号到一个守护进程后, 这个进程会重新启动,并且重新读取它的配置文件。Apache 网络服务器守护进程就是一个例子。
  • INT:编号2,中断。实现和Ctrl-c一样的功能,由终端发送。通常,它会终止一个程序。
  • KILL:编号9,杀死。进程可能选择忽略这个信号。所以,操作系统不发送该信号到目标进程,而是内核立即终止这个进程。当一个进程以这种方式终止的时候,它没有机会去做些“清理”工作,或者是保存劳动成果。因为这个原因,把 KILL 信号看作杀手锏,当其它终止信号失败后,再使用它。
  • TERM:编号15,终止。这是 kill 命令发送的默认信号。如果程序仍然“活着”,可以接受信号,那么这个信号终止。
  • CONT:编号18,继续。在停止一段时间后,进程恢复运行。
  • STOP:编号19,停止。这个信号导致进程停止运行,而没有终止。像 KILL 信号,它不被 发送到目标进程,因此它不能被忽略。
  • QUIT:编号3,退出
  • SEGV:编号11,段错误。如果一个程序非法使用内存,就会发送这个信号。也就是说,程序试图写入内存,而这个内存空间是不允许此程序写入的。
  • TSTP:编号20,终端停止。当按下 Ctrl-z 组合键后,终端发送这个信号。不像 STOP 信号, TSTP 信号由目标进程接收,且可能被忽略。
  • WINCH:编号28,改变窗口大小。当改变窗口大小时,系统会发送这个信号。 一些程序,像 top 和 less 程序会响应这个信号,按照新窗口的尺寸,刷新显示的内容。

-l参数可以列出所有信号。

1
$ kill -l

killall

killall命令用于向指定的程序或用户发送信号。

1
$ killall [-u user] [-signal] name

其他进程相关命令

  • pstree 输出树型结构的进程列表,这个列表展示了进程间父/子关系。
  • vmstat 输出一个系统资源使用快照,包括内存,交换分区和磁盘 I/O。 为了看到连续的显示结果,则在命令名后加上延时的时间(以秒为单位)。例如,“vmstat 5”。 终止输出,按下 Ctrl-c 组合键。
  • xload 一个图形界面程序,可以画出系统负载的图形。
  • tloadxload程序相似,但是在终端中画出图形。使用 Ctrl-c,来终止输出。

重定向

重定向指的是将命令行输出写入指定位置。

  • cmd1 | cmd2:Pipe; take standard output of cmd1 as standard input to cmd2.
  • > file:Direct standard output to file.
  • < file:Take standard input from file.
  • >> file:Direct standard output to file; append to file if it already exists.
  • >| file:Force standard output to file even if noclobber is set.
  • n>| file:Force output to file from file descriptor n even if noclobber is set.
  • <> file:Use file as both standard input and standard output.
  • n<> file:Use file as both input and output for file descriptor n.
  • << label:Here-document; see text.
  • n > file:Direct file descriptor n to file.
  • n < file:Take file descriptor n from file.
  • n >> file:Direct file descriptor n to file; append to file if it already exists.
  • n>&:Duplicate standard output to file descriptor n.
  • n<&:Duplicate standard input from file descriptor n.
  • n>&m:File descriptor  n is made to be a copy of the output file descriptor.
  • n<&m:File descriptor  n is made to be a copy of the input file descriptor.
  • &>file:Directs standard output and standard error to file.
  • <&-:Close the standard input.
  • >&-:Close the standard output.
  • n>&-:Close the output from file descriptor  n.
  • n<&-:Close the input from file descriptor  n.
  • n>&word:If  n is not specified, the standard output (file descriptor 1) is used. If the digits in word do not specify a file descriptor open for output, a redirection error occurs. As a special case, if n is omitted, and word does not expand to one or more digits, the standard output and standard error are redirected as described previously.
  • n<&word:If word expands to one or more digits, the file descriptor denoted by  n is made to be a copy of that file descriptor. If the digits in word do not specify a file descriptor open for input, a redirection error occurs. If word evaluates to -, file descriptor n is closed. If n is not specified, the standard input (file descriptor 0) is used.
  • n>&digit-:Moves the file descriptor digit to file descriptor  n, or the standard output (file descriptor 1) if n is not specified.
  • n<&digit-:Moves the file descriptor digit to file descriptor  n, or the standard input (file descriptor 0) if n is not specified. digit is closed after being duplicated to n.

>用来将标准输出重定向到指定文件。

1
$ ls -l /usr/bin > ls-output.txt

如果重定向后的指定文件已经存在,就会被覆盖,不会有任何提示。

如果命令没有任何输出,那么重定向之后,得到的是一个长度为0的文件。因此,>具有创建新文件或改写现存文件、将其改为长度0的作用。

1
$ > ls-output.txt

>>用来将标准输出重定向追加到指定文件。

1
$ ls -l /usr/bin >> ls-output.txt

2>用来将标准错误重定向到指定文件。

1
$ ls -l /bin/usr 2> ls-error.txt

标准输出和标准错误,可以重定向到同一个文件。

1
2
3
4
5
6
$ ls -l /bin/usr > ls-output.txt 2>&1
# 或者
$ ls -l /bin/usr &> ls-output.txt

# 追加到同一个文件
$ ls -l /bin/usr &>> ls-output.txt

如果不希望输出错误信息,可以将它重定向到一个特殊文件/dev/null

1
$ ls -l /bin/usr 2> /dev/null

|用于将一个命令的标准输出,重定向到另一个命令的标准输入。

1
$ ls -l /usr/bin | less

不要将>|混淆。

1
$ ls > less

上面命令会在当前目录,生成一个名为less的文本文件。

下面是标准错误重定向的一个例子。

1
2
3
4
5
6
invalid_input () {
echo "Invalid input '$REPLY'" >&2
exit 1
}
read -p "Enter a single item > "
[[ -z $REPLY ]] && invalid_input

tee

tee命令用于同时将标准输出重定向到文件,以及另一个命令的标准输入。

1
$ ls /usr/bin | tee ls.txt | grep zip

命令替换

命令替换(command substitution)指的是将一个命令的输出,替换进入另一个命令。$(command)表示命令替换,另一种写法是使用反引号。

1
2
3
4
5
6
7
$ echo $(ls)
# 或者
$ echo `ls`

$ ls -l $(which cp)
# 或者
$ ls -l `which cp`

basename

basename命令清除 一个路径名的开头部分,只留下一个文件的基本名称。

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
# file_info: simple file information program
PROGNAME=$(basename $0)
if [[ -e $1 ]]; then
echo -e "\nFile Type:"
file $1
echo -e "\nFile Status:"
stat $1
else
echo "$PROGNAME: usage: $PROGNAME file" >&2
exit 1
fi

正则表达式

正则表达式是表达文本模式的方法。

  • .:匹配任何单个字符。
  • ?:上一项是可选的,最多匹配一次。
  • *:前一项将被匹配零次或多次。
  • +:前一项将被匹配一次或多次。
  • {N}:上一项完全匹配N次。
  • {N,}:前一项匹配N次或多次。
  • {N,M}:前一项至少匹配N次,但不超过M次。
  • --:表示范围,如果它不是列表中的第一个或最后一个,也不是列表中某个范围的终点。
  • ^:匹配行首的空字符串;也代表不在列表范围内的字符。
  • $:匹配行尾的空字符串。
  • \b:匹配单词边缘的空字符串。
  • \B:匹配空字符串,前提是它不在单词的边缘。
  • \<:匹配单词开头的空字符串。
  • \>:匹配单词末尾的空字符串。

元字符

元字符是表示特殊函数的字符,包括以下这些^ $ . [ ] { } - ? * + ( ) | \\。除了元字符,其他字符在正则表达式中,都表示原来的含义。

  • . 匹配任意字符,但不含空字符
  • ^ 匹配文本行开头
  • $ 匹配文本行结尾
1
$ grep -h '.zip' dirlist*.txt

上面命令在文件中查找包含正则表达式“.zip”的文本行。注意,上面命令不会匹配zip程序,因为zip只有三个字符,而.zip要求四个字符。

1
2
$ grep -h '^zip' dirlist*.txt
$ grep -h 'zip$' dirlist*.txt

上面命令分别在文件列表中搜索行首,行尾以及行首和行尾同时包含字符串“zip”(例如,zip 独占一行)的匹配行。 注意正则表达式‘^$’(行首和行尾之间没有字符)会匹配空行。

方括号

方括号之中的字符,表示可以任意匹配其中的一个。

1
$ grep -h '[bg]zip' dirlist*.txt

上面命令匹配包含字符串“bzip”或者“gzip”的任意行。

注意,元字符放入方括号之中,会失去其特殊含义。但有两种情况除外,^在方括号的开头,表示否定,否则只是一个普通字符,表示原义。

1
$ grep -h '[^bg]zip' dirlist*.txt

上面命令匹配不以bg开头的zip字符串。注意,上面命令不会匹配zip,因为一个否定的字符集仍然要求存在一个字符。

-在方括号之中表示一个字符区域。

1
$ grep -h '^[A-Z]' dirlist*.txt

上面命令匹配所有以大写字母开头的文本行。类似的,^[A-Za-z0-9]表示以大写字母、小写字母、数字开头的文本行。

注意,连字号如果不构成一个字符区域,则表示其本来的含义。

1
$ grep -h '[-AZ]' dirlist*.txt

上面命令匹配包含一个连字符,或一个大写字母“A”,或一个大写字母“Z”的文件名。

预定义字符类

由于locale设置不同,Shell展开正则表达式[A-Z]时,可能不是解释为所有大写字母,而是解释为包括所有字母的字典顺序。

1
$ ls /usr/sbin/[A-Z]*

上面命令在某些发行版里面,会返回所有大写字母或小写字母开头的文件。

为了避免这个问题,可以使用正则表达式的预定义字符类。

  • [:alnum:] 字母数字字符。在 ASCII 中,等价于:[A-Za-z0-9]
  • [:word:][:alnum:]相同, 但增加了下划线字符。
  • [:alpha:] 字母字符。在 ASCII 中,等价于[A-Za-z]
  • [:blank:] 包含空格和 tab 字符。
  • [:cntrl:] ASCII 的控制码。包含了0到31,和127的 ASCII 字符。
  • [:digit:] 数字0到9
  • [:graph:] 可视字符。在 ASCII 中,它包含33到126的字符。
  • [:lower:] 小写字母。
  • [:punct:] 标点符号字符。
  • [:print:] 可打印的字符。等于[:graph:]中的所有字符,再加上空格字符。
  • [:space:] 空白字符,包括空格,tab,回车,换行,vertical tab, 和 form feed.在 ASCII 中, 等价于[ \t\r\n\v\f]
  • [:upper:] 大写字母。
  • [:xdigit:] 用来表示十六进制数字的字符。在 ASCII 中,等价于[0-9A-Fa-f]
1
$ ls /usr/sbin/[[:upper:]]*

上面命令返回所有大写字母开头的文件名。

选择

|表示匹配一系列字符串之中的一个。注意与方括号区分,方括号表示匹配一系列字符之中的一个。

1
2
3
4
5
6
$ echo "AAA" | grep -E 'AAA|BBB'
AAA
$ echo "BBB" | grep -E 'AAA|BBB'
BBB
$ echo "CCC" | grep -E 'AAA|BBB'
$

上面代码中,AAA|BBB表示匹配字符串AAA或者是字符串BBBgrep程序使用-E参数,表示按照正则表达式规则匹配。并且,这个正则表达式放在单引号之中,为的是阻止Shell把|解释为管道操作符。

|可以多个连用,也可以与其他正则规则结合使用。

1
2
3
$ echo "AAA" | grep -E 'AAA|BBB|CCC'

$ grep -Eh '^(bz|gz|zip)' dirlist*.txt

量词操作符

量词操作符表示一个元素被匹配的次数。

  • ? 匹配前面的元素出现0次或1次
  • * 匹配前面的元素出现0次或多次
  • + 匹配前面的元素出现1次或多次
  • {n} 匹配前面的元素出现了n
  • {n,m} 匹配前面的元素它至少出现了n次,但是不多于m
  • {n,} 匹配前面的元素至少出现了n
  • {,m} 匹配前面的元素,如果它出现的次数不多于 m 次。

系统信息

uname

uname命令返回当前机器的信息。

1
2
3
4
5
6
7
# 内核的版本
$ uname -r
3.2.0-24-virtual

# CPU 架构
$ uname -m
x86_64

如果要了解操作系统的版本,可以查看/etc/issue文件。

1
2
$ cat /etc/issue
Debian GNU/Linux 9 \n \l

service

service命令可以查看当前正在运行的服务。

1
2
3
4
$ service --status-all
[ + ] apache2
[ ? ] atd
[ - ] bootlogd

上面代码中,+表示正在运行,-表示已经停止,?表示service命令不了解相关信息。

文本处理

cat

cat可以文件的内容,显示在标准输出。

1
2
3
4
$ cat text1
1 apple
2 pear
3 banana

它也可以同时输出多个文件内容。

1
$ cat text1 text2

它与重定向结合,就可以合并多个文件。

1
2
3
4
5
# 合并文本文件
$ cat text* > text.all

# 合并二进制文件
$ cat movie.mpeg.0* > movie.mpeg

如果调用cat命令时没有任何参数,它将读取标准输入,然后显示到标准输出。按下Ctrl + d,将会结束cat读取标准输入。利用这一点,可以将键盘输入写入指定文件,按下Ctrl + d结束输入。

1
$ cat > lazy_dog.txt

它的参数如下。

  • -n 输出结果显示行号
  • -s 将多个连续的空白行,输出为一行
  • -A 输出结果中显示控制符,比如Tab键显示为^I,行尾显示$

cat支持Here document,显示多行文本。

1
2
3
4
5
6
7
8
9
10
11
cat << _EOF_
<HTML>
<HEAD>
<TITLE>$TITLE</TITLE>
</HEAD>
<BODY>
<H1>$TITLE</H1>
<P>$TIME_STAMP</P>
</BODY>
</HTML>
_EOF_

Here document 常在脚本当中作为输入的手段。

1
2
3
4
5
6
7
8
$ sort -k2 <<END
> 1 apple
> 2 pear
> 3 banana
> END
1 apple
3 banana
2 pear

如果使用<<-代替<<,行首的tab键将被剥离。

nl

nl命令为文本文件添加行号,显示在标准输出。

1
$ nl example.txt

sort

sort命令将文本文件的所有行排序后输出。

1
$ sort file1.txt file2.txt file3.txt > final_sorted_list.txt

它的参数如下。

  • -b --ignore-leading-blanks 默认情况下,排序用的是每行的第一个字符。这个参数忽略每行开头的空格,从第一个非空白字符开始排序。
  • -f --ignore-case 让排序不区分大小写。
  • -n --numeric-sort 按照数值排序,而不是字符值,用于行首是数值的情况。
  • -r --reverse 按相反顺序排序。结果按照降序排列,而不是升序。
  • -k --key=field1[,field2] 指定按照每行的第几个字段(从1开始)排序,而不是按照行首字符排序。该属性可以多个连用,用于指定多重排序标准,还可以指定每个字段指定排序标准,这些值与全局属性一致,比如b(忽略开头的空格),n(数值排序),r(逆向排序)等等。
  • -m --merge 把每个参数看作是一个预先排好序的文件。把多个文件合并成一个排好序的文件,而没有执行额外的排序。
  • -o --output=file 把排好序的输出结果发送到文件,而不是标准输出。
  • -t --field-separator=char 定义字段分隔字符。默认情况下,字段由空格或制表符分隔。
  • -u 输出结果中删除重复行
1
$ sort --key=1,1 --key=2n distros.txt

上面命令中,第一个--key指定第一排序标准是只用第一字段(1,1),也可以指定使用第一字段第一个字符(1.1);第二排序标准是第二字段,按数值排序。

uniq

uniq命令在排序后的行中,删除所有重复的行,保证所有输出没有重复。

1
$ ls /bin /usr/bin | sort | uniq

它的参数如下。

  • -c 输出所有的重复行,并且每行开头显示重复的次数。
  • -d 只输出重复行,而不是不重复的文本行。
  • -f n 忽略每行开头的 n 个字段,字段之间由空格分隔,正如 sort 程序中的空格分隔符;然而, 不同于 sort 程序,uniq 没有选项来设置备用的字段分隔符。
  • -i 在比较文本行的时候忽略大小写。
  • -s n 跳过(忽略)每行开头的 n 个字符。
  • -u 只是输出独有的文本行。这是默认的。
  • -V 按照版本号排序。

-V参数可以按版本号排列(从小到大)。

1
2
3
4
5
$ sort -V input.txt
1.0.15
1.3.0
2.1.2
3.0.0

-rV参数可以按版本号逆序排列。

1
2
3
4
5
$ sort -rV input.txt
3.0.0
2.1.2
1.3.0
1.0.15

cut

cut程序用来从文本行中抽取文本,并把其输出到标准输出。它能够接受多个文件参数或者标准输入。

它的参数如下。

  • -c char_list 抽取指定范围的文本
  • -f field_list 抽取指定字段,字段之间可以tab分隔也可以逗号分隔
  • -d delim_char 指定字段分隔符,默认是tab键
  • --complement 抽取整个文本行,除了那些由-c 和/或-f 选项指定的文本。
1
2
3
4
5
6
7
8
9
10
11
# 抽取每行的第三个字段
$ cut -f 3 distros.txt

# 抽取每行的第7到第10个字符
$ cut -c 7-10 distros.txt

# 抽取每行的第23个到结尾的字符1
$ cut -c 23- distros.txt

# 指定字段分隔符为冒号
$ cut -d ':' -f 1 /etc/passwd

paste

paste程序将多个文本文件按行合并,即每一行都由原来文本文件的每一行组成,显示在标准输出。

1
$ paste distros-dates.txt distros-versions.txt

wc

wc命令输出一个文本文件的统计信息(word count),一共有三个值,分别为行数、词数和字节数。

1
2
$ wc ls-output.txt
7902 64566 503634 ls-output.txt

如果使用-l参数,则只输出行数。

1
2
$ ls /bin /usr/bin | sort | uniq | wc -l
2728

head命令返回文本文件的头部,默认显示10行。

-n参数指定显示的行数。

1
$ head -n 5 ls-output.txt

tail

tail命令返回文本文件的尾部,默认显示10行。

-n参数指定显示的行数。

1
$ tail -n 5 ls-output.txt

-f会实时追加显示新增的内容,常用于实时监控日志,按Ctrl + c停止。

1
$ tail -f /var/log/messages

grep

grep程序用于在指定文件之中,搜索符合某个模式的行,并把搜索结果输出到标准输出。

1
$ grep keyword foo.txt

上面命令输出foo.txt之中匹配keyword的行。

grep程序可以同时搜索多个文件。

1
$ grep keyword f*.txt

上面命令输出多个文件中匹配keyword的行。

-l参数输出匹配的文件名,而不是文件行。

1
$ grep -l bzip dirlist*.txt

如果想搜索文件名,而不是文件内容,可以使用重定向。

1
$ ls /usr/bin | grep zip

上面命令会输出/usr/bin目录中,文件名中包含子字符串zip的所有文件。

参数的含义。

  • -c--count 输出匹配的数量,而不是匹配的文本行。如果使用了-v,则输出不匹配的数量。
  • -h--no-filename 应用于多文件搜索,不在每行匹配的文本前,输出文件名
  • -i--ignore-case 忽略大小写
  • -l--files-with-matches 输出包含匹配项的文件名,而不是文本行本身
  • -L--files-without-match 类似于-l,但输出不包含匹配项的文件名
  • -n--line-number 每个匹配行之前输出其对应的行号
  • -v--invert-match 只返回不符合模式的行

sed

sed是一个强大的文本编辑工具。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 输出前5行
$ sed -n '1,5p' distros.txt

# 输出包含指定内容的行
$ sed -n '/SUSE/p' distros.txt

# 输出不包含指定内容的行
$ sed -n '/SUSE/!p' distros.txt

# 替换内容(只替换第一个)
$ sed 's/regexp/replacement/' distros.txt

# 替换内容(全局替换)
$ sed 's/regexp/replacement/g' distros.txt

时间管理

date 命令

date命令用于输出当前时间

1
2
$ date
2016年 03月 14日 星期一 17:32:35 CST

date命令后面用加号(+)指定显示的格式。

1
2
3
4
5
6
7
8
$ date +%d_%b_%Y
10_Sep_2018

$ date +%D
09/10/18

$ date +%F-%T
2018-09-10-11:09:51

完整的格式参数如下。

  • %a 星期名的缩写(Sun)
  • %A 星期名的全称(Sunday)
  • %b 月份的缩写(Jan)
  • %B 月份的全称(January)
  • %c 日期和时间(Thu Mar 3 23:05:25 2005)
  • %C 世纪,就是年份数省略后两位(20)
  • %d 一个月的第几天(01)
  • %D 日期,等同于%m/%d/%y
  • %e 一个月的第几天,用空格补零,等同于%_d
  • %F 完整的日期,等同于%Y-%m-%d
  • %g last two digits of year of ISO week number (see %G)
  • %G year of ISO week number (see %V); normally useful only with %V
  • %h 等同于%b
  • %H 小时(00..23)
  • %I 小时(01..12)
  • %j day of year (001..366)
  • %k hour ( 0..23)
  • %l hour ( 1..12)
  • %m month (01..12)
  • %M minute (00..59)
  • %N nanoseconds (000000000..999999999)
  • %p locale’s equivalent of either AM or PM; blank if not known
  • %P like %p, but lower case
  • %r locale’s 12-hour clock time (e.g., 11:11:04 PM)
  • %R 24-hour hour and minute; same as %H:%M
  • %s seconds since 1970-01-01 00:00:00 UTC
  • %S second (00..60)
  • %T time; same as %H:%M:%S
  • %u day of week (1..7); 1 is Monday
  • %U week number of year, with Sunday as first day of week (00..53)
  • %V ISO week number, with Monday as first day of week (01..53)
  • %w day of week (0..6); 0 is Sunday
  • %W week number of year, with Monday as first day of week (00..53)
  • %x locale’s date representation (e.g., 12/31/99)
  • %X locale’s time representation (e.g., 23:13:48)
  • %y last two digits of year (00..99)
  • %Y year
  • %z +hhmm numeric timezone (e.g., -0400)
  • %:z +hh:mm numeric timezone (e.g., -04:00)
  • %::z +hh:mm:ss numeric time zone (e.g., -04:00:00)
  • %Z alphabetic time zone abbreviation (e.g., EDT)

cal 命令

cal命令用于显示日历。不带有参数时,显示的是当前月份。

1
2
3
4
5
6
7
8
$ cal
三月 2016
日 一 二 三 四 五 六
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