Linux命令行与shell脚本编程 - 实践

知识点来源:《Linux命令行与shell脚本编程大全》Richard Blum Christine Bresnahan 

持续更新中...

Windows & Linux 常用命令速过

Windows

Linux

初识 Linux shell

shell简述

shell的核心是命令行提示符。命令行提示符是shell负责交互的部分。它允许你输入文本命令,然后解释命令,并在内核中执行。

shell包含了一组内部命令,用这些命令可以完成诸如复制文件、移动文件、重命名文件、显示和终止系统中正运行的程序等操作。shell也允许你在命令行提示符中输入程序的名称,它会将程序名传递给内核以启动它。

你也可以将多个shell命令放入文件中作为程序执行。这些文件被称作shell脚本。你在命令行上执行的任何命令都可放进一个shell脚本中作为一组命令执行。这为创建那种需要把几个命令放在一起来工作的工具提供了便利。

shell的入口

提示符是进入shell世界的大门,是你输入shell命令的地方。

默认bash shell提示符是美元符号($),这个符号表明shell在等待用户输入。不同的Linux发行版采用不同格式的提示符。

Ubuntu Linux系统上,shell提示符看起来是这样的:
christine@server01:~$

CentOS系统上是这样的:
[christine@server01 ~]$

除了作为shell的入口,提示符还能够提供其他的辅助信息。在上面的两个例子中,提示符中显示了当前用户IDchristine。另外还包括系统名server01

Linux文件系统目录

注:你将会发现Linux使用正斜线(/)而不是反斜线(\)在文件路径中划分目录。在Linux中, 反斜线用来标识转义字符,要是用在文件路径中的话会导致各种各样的问题。如果你之前用的是Windows环境,就需要一点时间来适应。

基本的bash shell命令

man命令

man命令用来访问存储在Linux系统上的手册页面。在想要查找的工具的名称前面输入man
令,就可以找到那个工具相应的手册条目。比如 
man pwd

注:如果不记得命令名怎么办?可以使用关键字搜索手册页。语法是:man -k 关键字。例如,要查找与终端相关的命令,可以输入man -k terminal。

cd命令

Linux文件系统上,可以使用切换目录命令cdshell会话切换到另一个目录。cd命令的格式非常简单: cd destination

cd命令可接受单个参数destination,用以指定想切换到的目录名。destination参数可以用两种方式表示:一种是使用绝对文件路径,另一种是使用相对文件路径

绝对文件路径总是以正斜线(/)作为起始,指明虚拟文件系统的根目录。因此,如果要指向usr目录所包含的bin目录下的用户二进制文件,可以使用如下绝对文件路径:
/usr/bin

相对文件路径允许用户指定一个基于当前位置的目标文件路径。相对文件路径不以代表根目录的正斜线(/)开头,而是以目录名(如果用户准备切换到当前工作目录下的一个目录)或是一个特殊字符开始。假如你位于home目录中,并希望切换到Documents子目录,那你可以使用cd命令加上一个相对文件路径:
christine@server01:~$ cd Documents

另外:
有两个特殊字符可用于相对文件路径中:
  • 单点符(.),表示当前目录;
  • 双点符(..),表示当前目录的父目录。

双点符在目录层级中移动时非常便利。比如 cd ../ 可以将用户带到上一级目录

pwd命令

pwd命令可以显示出shell会话的当前目录,这个目录被称为当前工作目录pwd命令的用法如下:
christine@server01:/usr/bin$ pwd 

ls命令

ls命令最基本的形式会显示当前目录下的文件和目录:
$ ls
Desktop Downloads Music Pictures Templates Videos
Documents examples.desktop my_script Public test_file
$

注意:ls命令输出的列表是按字母排序的(按列排序而不是按行排序)

-F参数

也可用带-F参数的ls命令轻松区分文件和目录。使用-F参数可 以得到如下输出:

$ ls -F
Desktop/ Downloads/ Music/ Pictures/ Templates/ Videos/
Documents/ examples.desktop my_script* Public/ test_file
$

注意:基本的ls命令在某种意义上有点容易让人误解。它显示了当前目录下的文件和目录,但并没有将全部都显示出来。Linux经常采用隐藏文件来保存配置信息。在Linux上,隐藏文件通常是文件名以点号开始的文件。这些文件并没有在默认的ls命令输出中显示出来,因此我们称其为隐藏文件。

-a参数
要把隐藏文件和普通文件及目录一起显示出来,就得用到-a参数。下面是一个带有-a参数的ls命令的例子:
$ ls -a
. .compiz examples.desktop Music test_file
.. .config .gconf my_script Videos
.bash_history Desktop .gstreamer-0.10 Pictures .Xauthority
.bash_logout .dmrc .ICEauthority .profile .xsession-errors
.bashrc Documents .local Public .xsession-errors.old
.cache Downloads .mozilla Templates
$

-R参数
-R参数是ls命令可用的另一个参数,叫作递归选项。它列出了当前目录下包含的子目录中的文件。如果目录很多,这个输出就会很长。以下是-R参数输出的简单例子:
$ ls -F -R
.:
Desktop/ Downloads/ Music/ Pictures/ Templates/ Videos/
Documents/ examples.desktop my_script* Public/ test_file
./Desktop:
./Documents:
./Downloads:
./Music:
ILoveLinux.mp3*
./Pictures:
./Public:
./Templates:
./Videos:
$

首先-R参数显示了当前目录下的内容。另外,它还显示出了当前目录下所有子目录及其内容。只有Music子目录中包含了一个可执行文件ILoveLinux.mp3

在这个例子中,子目录中没再包含子目录。如果有更多的子目录,-R参数会继续进行遍历。 正如你所看到的,如果目录结构很庞大,输出内容会变得很长。

注:并一定要像例子中那样分开输入:ls –F –R。它们可以进行如下合并:ls –FR

-l参数
在基本的输出列表中,ls命令并未输出太多每个文件的相关信息。要显示附加信息,另一个常用的参数是-l-l参数会产生长列表格式的输出,包含了目录中每个文件的更多相关信息。
$ ls -l
total 48
drwxr-xr-x 2 christine christine 4096 Apr 22 20:37 Desktop
drwxr-xr-x 2 christine christine 4096 Apr 22 20:37 Documents
drwxr-xr-x 2 christine christine 4096 Apr 22 20:37 Downloads
-rw-r--r-- 1 christine christine 8980 Apr 22 13:36 examples.desktop
-rw-rw-r-- 1 christine christine 0 May 21 13:44 fall
-rw-rw-r-- 1 christine christine 0 May 21 13:44 fell
-rw-rw-r-- 1 christine christine 0 May 21 13:44 fill
-rw-rw-r-- 1 christine christine 0 May 21 13:44 full
drwxr-xr-x 2 christine christine 4096 May 21 11:39 Music
-rw-rw-r-- 1 christine christine 0 May 21 13:25 my_file
-rw-rw-r-- 1 christine christine 0 May 21 13:25 my_scrapt
-rwxrw-r-- 1 christine christine 54 May 21 11:26 my_script
-rw-rw-r-- 1 christine christine 0 May 21 13:42 new_file
drwxr-xr-x 2 christine christine 4096 Apr 22 20:37 Pictures
drwxr-xr-x 2 christine christine 4096 Apr 22 20:37 Public
drwxr-xr-x 2 christine christine 4096 Apr 22 20:37 Templates
-rw-rw-r-- 1 christine christine 0 May 21 11:28 test_file
drwxr-xr-x 2 christine christine 4096 Apr 22 20:37 Videos
$

这种长列表格式的输出在每一行中列出了单个文件或目录。除了文件名,输出中还有其他有用信息。输出的第一行显示了在目录中包含的总块数。在此之后,每一行都包含了关于文件(或目录)的下述信息:
  • 文件类型,比如目录(d)、文件(-)、字符型文件(c)或块设备(b);
  • 文件的权限
  • 文件的硬链接总数;
  • 文件属主的用户名;
  • 文件属组的组名;
  • 文件的大小(以字节为单位);
  • 文件的上次修改时间;
  • 文件名或目录名。

注:ll 是 ls -l 命令的别名(alias),也算是缩写,同样用于以 “长格式” 列出目录内容。两者用法一样。平时可以用 ll 替代ls -l 。

过滤器
过滤器就是一个进行简单文本匹配的字符串。可以在要用的命令行参数之后添加这个过滤器:
$ ls -l my_script
-rwxrw-r-- 1 christine christine 54 May 21 11:26 my_script
$

当用户指定特定文件的名称作为过滤器时,ls命令只会显示该文件的信息。

有时你可能不知 道要找的那个文件的确切名称。ls命令能够识别标准通配符,并在过滤器中用它们进行模式匹配:
  • 问号(?)代表一个字符;
  • 星号(*)代表零个或多个字符。

问号可用于过滤器字符串中替代任意位置的单个字符。例如:
$ ls -l my_scr?pt
-rw-rw-r-- 1 christine christine 0 May 21 13:25 my_scrapt
-rwxrw-r-- 1 christine christine 54 May 21 11:26 my_script
$

类似地,星号可匹配零个或多个字符。例如:

$ ls -l my*
-rw-rw-r-- 1 christine christine 0 May 21 13:25 my_file
-rw-rw-r-- 1 christine christine 0 May 21 13:25 my_scrapt
-rwxrw-r-- 1 christine christine 54 May 21 11:26 my_script
$

touch命令

你总会时不时地遇到要创建空文件的情况。例如,有时应用程序希望在它们写入数据之前, 某个日志文件已经存在。这时,可用touch命令轻松创建空文件。
$ touch test_one
$ ls -l test_one
-rw-rw-r-- 1 christine christine 0 May 21 14:17 test_one
$

cp命令

对系统管理员来说,在文件系统中将文件和目录从一个位置复制到另一个位置可谓家常便饭。cp命令可以完成这个任务。

在最基本的用法里,cp命令需要两个参数——源对象和目标对象:
cp source destination

sourcedestination参数都是文件名时,cp命令将源文件复制成一个新文件,并且以destination命名。新文件就像全新的文件一样,有新的修改时间。
$ cp test_one test_two
$ ls -l test_*
-rw-rw-r-- 1 christine christine 0 May 21 14:35 test_one
-rw-rw-r-- 1 christine christine 0 May 21 15:15 test_two
$

-i参数
如果目标文件已经存在,cp命令可能并不会提醒这一点。最好是加上-i选项,强制shell询问是否需要覆盖已有文件。
$ ls -l test_*
-rw-rw-r-- 1 christine christine 0 May 21 14:35 test_one
-rw-rw-r-- 1 christine christine 0 May 21 15:15 test_two
$
$ cp -i test_one test_two
cp: overwrite 'test_two'? n
$
如果不回答y,文件复制将不会继续。

或者也可以将文件复制到现有目录中
$ cp -i test_one /home/christine/Documents/
$
$ ls -l /home/christine/Documents
total 0
-rw-rw-r-- 1 christine christine 0 May 21 15:25 test_one
$

在前面介绍了特殊符号可以用在相对文件路径中。其中的单点符(.)就很适合用于cp命令。记住,单点符表示当前工作目录。如果需要将一个带有很长的源对象名的文件复制到当前工作目录中时,单点符能够简化该任务。例如:
$ cp -i /etc/NetworkManager/NetworkManager.conf .
$
$ ls -l NetworkManager.conf
-rw-r--r-- 1 christine christine 76 May 21 15:55 NetworkManager.conf
$

-R参数
可以用它在一条命令中递归地复制整个目录的内容
$ ls -Fd *Scripts
Scripts/
$ ls -l Scripts/
total 25
-rwxrw-r-- 1 christine christine 929 Apr 2 08:23 file_mod.sh
-rwxrw-r-- 1 christine christine 254 Jan 2 14:18 SGID_search.sh
-rwxrw-r-- 1 christine christine 243 Jan 2 13:42 SUID_search.sh
$
$ cp -R Scripts/ Mod_Scripts
$ ls -Fd *Scripts
Mod_Scripts/ Scripts/
$ ls -l Mod_Scripts
total 25
-rwxrw-r-- 1 christine christine 929 May 21 16:16 file_mod.sh
-rwxrw-r-- 1 christine christine 254 May 21 16:16 SGID_search.sh
-rwxrw-r-- 1 christine christine 243 May 21 16:16 SUID_search.sh
$

在执行cp –R命令之前,目录Mod_Scripts并不存在。它是随着cp –R命令被创建的,整个Scripts目录中的内容都被复制到其中。注意,在新的Mod_Scripts目录中,所有的文件都有对应的新日期。 Mod_Scripts目录现在已经成为了Scripts目录的完整副本

注:-d选项表示只列出目录本身的信息,不列出其中的内容

制表键[Tab]

在使用命令行时,很容易输错命令、目录名或文件名。实际上,对长目录名或文件名来说,输错的几率还是蛮高的。 这正是制表键自动补全挺身而出的时候。制表键自动补全允许你在输入文件名或目录名时按 一下制表键,让shell帮忙将内容补充完整。

mv命令

Linux中,重命名文件称为移动(movingmv命令还可以将文件和目录移动到另一个位置。
如下是一个重命名文件的例子:
$ ls -li f?ll
296730 -rw-rw-r-- 1 christine christine 0 May 21 13:44 fall
296717 -rw-rw-r-- 1 christine christine 0 May 21 13:44 fell
294561 -rw-rw-r-- 1 christine christine 0 May 21 13:44 fill
296742 -rw-rw-r-- 1 christine christine 0 May 21 13:44 full
$
$ mv fall fzll
$
$ ls -li f?ll
296717 -rw-rw-r-- 1 christine christine 0 May 21 13:44 fell
294561 -rw-rw-r-- 1 christine christine 0 May 21 13:44 fill
296742 -rw-rw-r-- 1 christine christine 0 May 21 13:44 full
296730 -rw-rw-r-- 1 christine christine 0 May 21 13:44 fzll
$

可以看到,mv命令可以将文件名从fall更改为fzll

也可以使用mv来移动文件的位置。
$ ls -li /home/christine/fzll
296730 -rw-rw-r-- 1 christine christine 0 May 21 13:44
/home/christine/fzll
$
$ ls -li /home/christine/Pictures/
total 0
$ mv fzll Pictures/
$
$ ls -li /home/christine/Pictures/
total 0
296730 -rw-rw-r-- 1 christine christine 0 May 21 13:44 fzll
$
$ ls -li /home/christine/fzll
ls: cannot access /home/christine/fzll: No such file or directory
$

在上例中,我们使用mv命令把文件fzll/home/christine移动到了/home/christine/Pirctures

注:和cp命令类似,也可以在mv命令中使用-i参数。这样在命令试图覆盖已有的文件时,你
就会得到提示

也可以使用mv命令移动文件位置并修改文件名称,这些操作只需一步就能完成。
$ ls -li Pictures/fzll
296730 -rw-rw-r-- 1 christine christine 0 May 21 13:44
Pictures/fzll
$
$ mv /home/christine/Pictures/fzll /home/christine/fall
$
$ ls -li /home/christine/fall
296730 -rw-rw-r-- 1 christine christine 0 May 21 13:44
/home/christine/fall
$
$ ls -li /home/christine/Pictures/fzll
ls: cannot access /home/ch

rm 命令

迟早有一天,你得删除已有的文件。不管是清理文件系统还是删除某个软件包,总有要删除
文件的时候。

Linux中,删除(deleting)叫作移除removingbash shell中删除文件的命令是rmrm 命令的基本格式非常简单。
$ rm -i fall
rm: remove regular empty file 'fall'? y
$
$ ls -l fall
ls: cannot access fall: No such file or directory
$

注意:-i命令参数提示你是不是要真的删除该文件。bash shell中没有回收站或垃圾箱,文件一旦删除,就无法再找回。因此,在使用rm命令时,要养成总是加入-i参数的好习惯。

-f参数

强制删除,不提示确认(即使文件是只读的),也不显示 “文件不存在” 之类的错误信息。

-r参数
递归删除,用于删除目录及其包含的所有子文件 / 子目录(如果不加此参数,rm 无法直接删除目录)。

这两个参数常组合使用,这是最常用的彻底删除方式,例如:
# 删除单个文件(彻底删除,不提示)
rm -f file.txt
# 删除整个目录及其内容(彻底删除,不提示)
rm -rf mydir/

注意:rm -rf命令既没有警告信息,也没有声音提示。这肯定是一个危险的工具,尤其是在拥有超级用户权限的时候。务必谨慎使用,请再三检查你所要进行的操作是否符合预期。

mkdir命令

Linux中,有些命令(比如cp命令)对文件和目录都有效,而有些只对目录有效。创建新目录需要用到的一个特殊命令mkdir(其实就是make directory的缩写)
$ mkdir New_Dir
$ ls -ld New_Dir
drwxrwxr-x 2 christine christine 4096 May 22 09:48 New_Dir
$

上例子系统创建了一个名为New_Dir的新目录。注意,新目录长列表是以d开头的。这表示New_Dir 并不是文件,而是一个目录。

可以根据需要批量地创建目录和子目录。但是,如果你想单单靠mkdir命令来实现,就会得到下面的错误消息:
$ mkdir New_Dir/Sub_Dir/Under_Dir
mkdir: cannot create directory 'New_Dir/Sub_Dir/Under_Dir':
No such file or directory
$

-p参数
要想同时创建多个目录和子目录,需要加入-p参数:
$ mkdir -p New_Dir/Sub_Dir/Under_Dir
$
$ ls -R New_Dir
New_Dir:
Sub_Dir
New_Dir/Sub_Dir:
Under_Dir
New_Dir/Sub_Dir/Under_Dir:
$

rmdir命令

删除目录之所以很棘手,是有原因的。删除目录时,很有可能会发生一些不好的事情。shell会尽可能防止我们捅娄子。删除目录的基本命令是rmdir
$ touch New_Dir/my_file
$ ls -li New_Dir/
total 0
294561 -rw-rw-r-- 1 christine christine 0 May 22 09:52 my_file
$
$ rmdir New_Dir
rmdir: failed to remove 'New_Dir': Directory not empty
$

默认情况下,rmdir命令只删除空目录。因为我们在New_Dir目录下创建了一个文件my_file,所以rmdir命令拒绝删除目录。

要解决这一问题,得先把目录中的文件删掉,然后才能在空目录上使用rmdir命令。
$ rm -i New_Dir/my_file
rm: remove regular empty file 'New_Dir/my_file'? y
$
$ rmdir New_Dir
$
$ ls -ld New_Dir
ls: cannot access New_Dir: No such file or directory

rmdir并没有-i选项来询问是否要删除目录。这也是为什么说rmdir只能删除空目录还是有好处的原因。

注:也可以在整个非空目录上使用rm命令。使用-r选项使得命令可以向下进入目录,删除其中的文件,然后再删除目录本身。这种方法虽然可行,但很难用。因为你依然要确认每个文件是否要被删除。如果该目录有很多个文件和子目录,这将非常琐碎。所以如果要一口气删除目录及其所有内容的终极大法就是使用带有-r参数和-f参数的rm命令 rm -rf

file命令

file命令是一个随手可得的便捷工具。它能够探测文件的内部,并决定文件是什么类型的:
$ file my_file
my_file: ASCII text
$

上面例子中的文件是一个text(文本)文件。file命令不仅能确定文件中包含的文本信息,还能确定该文本文件的字符编码,ASCII

下面例子中的文件就是一个目录。因此,以后可以使用file命令作为另一种区分目录的方法:
$ file New_Dir
New_Dir: directory
$

cat命令

cat命令是显示文本文件中所有数据的得力工具。
$ cat test1
hello
This is a test file.
That we'll use to test the cat command.
$

没什么特别的,就是文本文件的内容而已。如下还有一些可以和cat命令一起用的参数,可能对你有所帮助。

注意:如果是想自己测试这些命令又苦于不知怎么编辑进入文件的,可以用 vim/vi 编辑器
vim 文件名  # 打开文件
# 按 i 进入编辑模式,修改完成后按 Esc,输入 :wq 保存退出(:q! 强制退出不保存)

后续更新还会详细讲这些内容哦!

-n参数

-n参数会给所有的行加上行号。

$ cat -n test1
 1 hello
 2
 3 This is a test file.
 4
 5
 6 That we'll use to test the cat command.
$

-b参数

如果只想给有文本的行加上行号,可以用-b参数。

$ cat -b test1
 1 hello
 2 This is a test file.
 3 That we'll use to test the cat command.
$

-T参数
如果不想让制表符出现,可以用-T参数。-T参数会用^I字符组合去替换文中的所有制表符。
$ cat -T test1
hello
This is a test file.
That we'll use to^Itest the cat command.
$

more命令

cat 命令的主要缺陷是:一旦运行,就会连续输出文件的全部内容,它没有 “分页” 或 “暂停” 的逻辑 —— 无论文件有多大(比如 1000 行、10000 行),cat 都会一次性把所有内容快速打印到终端上,直到文件结束。

如果是有几百上千行的大文件(比如日志文件、配置文件),cat 会以极快的速度 “刷屏”—— 终端会瞬间被填满,前面的内容会被后面的内容覆盖,你根本来不及看清或暂停,直到所有内容输出完毕才会停止。

为了解决这个问题,开发人员编写了more命令。

more命令设计目标就是 “解决大文件的分页查看问题”,它的核心逻辑是 “按‘页’分割内容,显示完一页就暂停,等待用户指令”。

比如我们举个栗子:我们输入命令more /etc/bash.bashrc 会生成如图中所显示的内容。

其实使用more的具体流程就如下:

  1. 按页分割more 会根据你当前终端的高度(比如终端一次能显示 24 行,这就是 “一页”),自动把文件内容分成多页;
  2. 显示暂停:先显示第一页的内容,然后在终端底部提示类似 --More--(56%) 的信息(表示已显示 56%,等待操作),此时会暂停输出,不再继续刷屏;
  3. 用户控制:你可以通过简单的按键控制后续操作,比如:
    • 按 空格键:显示下一页;
    • 按 Enter 键:显示下一行(比空格键更精细);
    • 按 q 键:直接退出查看(不想看了可以随时终止)。

less命令

less 命令的命名实际上是个文字游戏(从 俗语“less is more”得来),它实为more命令的升级版。它提供了一些极为实用的特性,能够实 现在文本文件中前后翻动,而且还有一些高级搜索功能。

less命令的操作和more命令基本一样,一次显示一屏的文件文本。除了支持和more命令相同的命令集,它还包括更多的选项。

其中一组特性就是 more 只能向前滚动(按空格翻下一页,无法回看前面的内容),一旦翻过某一页,就不能再退回去看了;而 less 支持双向滚动。

注:要想查看less命令所有的可用选项,可以输入man less浏览对应的手册页。也可以这样
查看more命令选项的参考资料

ps命令

默认情况下,ps命令并不会提供那么多的信息:
$ ps
    PID  TTY     TIME  CMD
   3081 pts/0 00:00:00 bash
   3209 pts/0 00:00:00 ps
$
默认情况下,ps命令只会显示运行在当前控制台下的属于当前用户的进程。在此例中,我们只运行了bash shell(注意,shell也只是运行在系统上的另一个程序而已)以 及ps命令本身。

上例中的基本输出显示了程序的进程IDProcess IDPID)、它们运行在哪个终端(TTY)以及进程已用的CPU时间。

-ef 参数
如果你想查看系统上运行的所有进程,可用-ef 参数组合(ps命令允许你像这样把参数组合在一起)。
$ ps -ef
UID     PID PPID C STIME TTY    TIME      CMD
root    1    0   0 11:29  ?    00:00:01  init [5]
root    2    0   0 11:29  ?    00:00:00  [kthreadd]
root    3    2   0 11:29  ?    00:00:00  [migration/0]
root    4    2   0 11:29  ?    00:00:00  [ksoftirqd/0]
root    5    2   0 11:29  ?    00:00:00  [watchdog/0]
root    6    2   0 11:29  ?    00:00:00  [events/0]
root    7    2   0 11:29  ?    00:00:00  [khelper]
root    47   2   0 11:29  ?    00:00:00  [kblockd/0]
root    48   2   0 11:29  ?    00:00:00  [kacpid]
68     2349  1   0 11:30  ?    00:00:00  hald
root   3078 1981 0 12:00  ?    00:00:00  sshd: rich [priv]
rich   3080 3078 0 12:00  ?    00:00:00  sshd: rich@pts/0
rich   3081 3080 0 12:00 pts/0 00:00:00  -bash
rich   4445 3081 3 13:48 pts/0 00:00:00  ps -ef
$
这个例子用了两个参数:-e参数指定显示所有运行在系统上的进程;-f参数则扩展了输出,这些扩展的列包含了有用的信息。
  • UID:启动这些进程的用户。
  • PID:进程的进程ID
  • PPID:父进程的进程号(如果该进程是由另一个进程启动的)。
  • C:进程生命周期中的CPU利用率。
  • STIME:进程启动时的系统时间。
  • TTY:进程启动时的终端设备。
  • TIME:运行进程需要的累计CPU时间。
  • CMD:启动的程序名称。

-l参数
如果想要获得更多 的信息,可采用-l参数,它会产生一个长格式输出。
$ ps -l
F S UID PID  PPID C PRI NI ADDR SZ  WCHAN  TTY   TIME     CMD
0 S 500 3081 3080 0 80  0   -  1173  wait  pts/0 00:00:00 bash
0 R 500 4463 3081 1 80  0   -  1116   -    pts/0 00:00:00 ps
$
注意使用了-l参数之后多出的那些列。
  • F:内核分配给进程的系统标记。
  • S:进程的状态(O代表正在运行;S代表在休眠;R代表可运行,正等待运行;Z代表僵化,进程已结束但父进程已不存在;T代表停止)。
  • PRI:进程的优先级(越大的数字代表越低的优先级)。
  • NI:谦让度值用来参与决定优先级。
  • ADDR:进程的内存地址。
  • SZ:假如进程被换出,所需交换空间的大致大小。
  • WCHAN:进程休眠的内核函数的地址。

l参数

下例是使用l参数的输出:

$ ps l
F UID PID  PPID PRI NI  VSZ RSS   WCHAN STAT TTY   TIME  COMMAND
0 500 3081 3080 20  0  4692 1432  wait  Ss   pts/0 0:00  -bash
0 500 5104 3081 20  0  4468 844   -     R+   pts/0 0:00   ps l
$

l参数是BSD类型的参数,其中大部分的输出列跟使用Unix风格参数(-l参数)时的输出是一样的,只有一小部分不同。
  • VSZ:进程在内存中的大小,以千字节(KB)为单位。
  • RSS:进程在未换出时占用的物理内存。
  • STAT:代表当前进程状态的双字符状态码。

许多系统管理员都喜欢BSD风格的 参数。它能输出更详细的进程状态码(STAT列)。双字符状态码能比Unix风格输出的单字符状态码更清楚地表示进程的当前状态。

其中第一个字符采用了和Unix风格S列相同的值,表明进程是在休眠、运行还是等待。第二个参数进一步说明进程的状态。
  • <:该进程运行在高优先级上。
  • N:该进程运行在低优先级上。
  • L:该进程有页面锁定在内存中。
  • s:该进程是控制进程。
  • l:该进程是多线程的。
  • +:该进程运行在前台。
从前面的例子可以看出,bash命令处于休眠状态,但同时它也是一个控制进程(在我的会话中,它是主要进程),而ps命令则运行在系统的前台。
--forest参数
GNU长参数中一个着实让喜爱的功能就是--forest参数。它会显示进程的层级信息,并用ASCII字符绘出可爱的图表。
1981 ?      00:00:00 sshd
3078 ?      00:00:00 \_ sshd
3080 ?      00:00:00 \_ sshd
3081 pts/0  00:00:00 \_ bash
16676 pts/0 00:00:00 \_ ps
这种格式让跟踪子进程和父进程变得十分容易。

top命令

ps命令虽然在收集运行在系统上的进程信息时非常有用,但也有不足之处:它只能显示某个特定时间点的信息。如果想观察那些频繁换进换出的内存的进程趋势,用ps命令就不方便了。

top命令刚好适用这种情况。top命令跟ps命令相似,能够显示进程信息,但它是实时显示的。图中top命令运行时输出的截图。
输出的第一部分显示的是系统的概况:第一行显示了当前时间、系统的运行时间、登录的用户数以及系统的平均负载。
第二行显示了进程概要信息——top命令的输出中将进程叫作任务task):有多少进程处在运行、休眠、停止或是僵化状态(僵化状态是指进程完成了,但父进程没有响应)。
下一行显示了CPU的概要信息。top根据进程的属主(用户还是系统)和进程的状态(运行、空闲还是等待)将CPU利用率分成几类输出。
紧跟其后的两行说明了系统内存的状态。第一行说的是系统的物理内存:总共有多少内存,当前用了多少,还有多少空闲。后一行说的是同样的信息,不过是针对系统交换空间(如果分配了的话)的状态而言的。
最后一部分显示了当前运行中的进程的详细列表,有些列跟ps命令的输出类似。
  • PID:进程的ID
  • USER:进程属主的名字。
  • PR:进程的优先级。
  • NI:进程的谦让度值。
  • VIRT:进程占用的虚拟内存总量。
  • RES:进程占用的物理内存总量。
  • SHR:进程和其他进程共享的内存总量。
  • S:进程的状态(D代表可中断的休眠状态,R代表在运行状态,S代表休眠状态,T代表跟踪状态或停止状态,Z代表僵化状态)。
  • %CPU:进程使用的CPU时间比例。
  • %MEM:进程使用的内存占可用内存的比例。
  • TIME+:自进程启动到目前为止的CPU时间总量。
  • COMMAND:进程所对应的命令行名称,也就是启动的程序名。
默认情况下,top命令在启动时会按照%CPU值对进程排序。可以在top运行时使用多种交互命令重新排序。每个交互式命令都是单字符,在top命令运行时键入可改变top的行为。键入f允许你选择对输出进行排序的字段,键入d允许你修改轮询间隔。键入q可以退出top。用户在top命令的输出上有很大的控制权。用这个工具就能经常找出占用系统大部分资源的罪魁祸首。

kill命令

作为系统管理员,很重要的一个技能就是知道何时以及如何结束一个进程。有时进程挂起了,只需要动动手让进程重新运行或结束就行了。但有时,有的进程会耗尽CPU且不释放资源。在这两种情景下,你就需要能控制进程的命令。Linux沿用了Unix进行进程间通信的方法。

Linux中,进程之间通过信号来通信。进程的信号就是预定义好的一个消息,进程能识别它并决定忽略还是作出反应。进程如何处理信号是由开发人员通过编程来决定的。大多数编写完善的程序都能接收和处理标准Unix进程信号。这些信号都列在了下表中。

Linux上有两个命令可以向运行中的进程发出进程信号。kill 和 killall命令。
kill命令可通过进程IDPID)给进程发信号。默认情况下,kill命令会向命令行中列出的全部PID发送一个TERM信号。遗憾的是,你只能用进程的PID而不能用命令名,所以kill命令有时并不好用。

要发送进程信号,你必须是进程的属主或登录为root用户。
$ kill 3940
-bash: kill: (3940) - Operation not permitted
$
-s参数
上面例子中,TERM信号告诉进程可能的话就停止运行。不过,如果有不服管教的进程,那它通常会忽略这个请求。如果要强制终止,-s参数支持指定其他信号(用信号名或信号值)。

你能从下例中看出,kill命令不会有任何输出。
# kill -s HUP 3940
#
要检查kill命令是否有效,可再运行pstop命令,看看问题进程是否已停止。

killall命令

killall命令非常强大,它支持通过进程名而不是PID来结束进程。
# killall http*
#
上例中的命令结束了所有以http开头的进程,比如Apache Web服务器的httpd服务。

mount命令

        Linux文件系统将所有的磁盘都并入一个虚拟目录下。在使用新的存储媒 体之前,需要把它放到虚拟目录下。这项工作称为挂载mounting)。

        在今天的图形化桌面环境里,大多数Linux发行版都能自动挂载特定类型的可移动存储媒体。可移动存储媒体指的是可从PC上轻易移除的媒体,比如CD-ROM、软盘和U盘。

        但是如果用的发行版不支持自动挂载和卸载可移动存储媒体,就必须手动完成。
Linux上用来挂载媒体的命令叫作mount。默认情况下,mount命令会输出当前系统上挂载的设备列表。
$ mount
/dev/mapper/VolGroup00-LogVol00 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/sda1 on /boot type ext3 (rw)
tmpfs on /dev/shm type tmpfs (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
/dev/sdb1 on /media/disk type vfat
(rw,nosuid,nodev,uhelper=hal,shortname=lower,uid=503)
$
mount命令提供如下四部分信息:
  • 媒体的设备文件名
  • 媒体挂载到虚拟目录的挂载点
  • 文件系统类型
  • 已挂载媒体的访问状态

上面例子的最后一行输出中,U盘被GNOME桌面自动挂载到了挂载点/media/diskvfat文件系统类型说明它是在Windows机器上被格式化的。
要手动在虚拟目录中挂载设备,需要以root用户身份登录,或是以root用户身份运行sudo命令。手动挂载媒体设备的基本命令是:mount -t type device directory

type参数指定了磁盘被格式化的文件系统类型。Linux可以识别非常多的文件系统类型。如
果是和Windows PC共用这些存储设备,通常得使用下列文件系统类型。
  • vfatWindows长文件系统。
  • ntfsWindows NTXPVista以及Windows 7中广泛使用的高级文件系统。
  • iso9660:标准CD-ROM文件系统。
大多数U盘和软盘会被格式化成vfat文件系统。而数据CD则必须使用iso9660文件系统类型。
后面两个参数定义了该存储设备的设备文件的位置以及挂载点在虚拟目录中的位置。比如说,手动将U/dev/sdb1挂载到/media/disk,可用下面的命令:
mount -t vfat /dev/sdb1 /media/disk
媒体设备挂载到了虚拟目录后,root用户就有了对该设备的所有访问权限,而其他用户的访问则会被限制。然后也可以通过目录权限指定用户对设备的访问权限(后续更新会讲到)

umount命令

Linux系统上移除一个可移动设备时,不能直接从系统上移除,而应该先卸载。
卸载设备的命令是umount(是的,你没看错,命令名中并没有字母n)。umount命令的格式非常简单:umount [directory | device ]
umount命令支持通过设备文件或者是挂载点来指定要卸载的设备。如果有任何程序正在使用设备上的文件,系统就不会允许你卸载它:
[root@testbox mnt]# umount /home/rich/mnt
umount: /home/rich/mnt: device is busy
umount: /home/rich/mnt: device is busy
[root@testbox mnt]# cd /home/rich
[root@testbox rich]# umount /home/rich/mnt
[root@testbox rich]# ls -l mnt
total 0
[root@testbox rich]#
上例中,命令行提示符仍然在挂载设备的文件系统目录中,所以umount命令无法卸载该镜像文件。一旦命令提示符移出该镜像文件的文件系统,umount命令就能卸载该镜像文件。
posted @ 2025-10-01 10:53  yxysuanfa  阅读(15)  评论(0)    收藏  举报