Linux 入门教程
严格的来讲,Linux 不算是一个操作系统,只是一个 Linux 系统中的内核,即计算机软件与硬件通讯之间的平台;Linux的全称是GNU/Linux,这才算是一个真正意义上的Linux系统。GNU是Richard Stallman组织的一个项目,世界各地的程序员可以变形GNU程序,同时遵循GPL协议,允许任何人任意改动。但是,修改后的程序必须遵循GPL协议。
Linux 是一个多用户多任务的操作系统,也是一款自由软件,完全兼容POSIX标准,拥有良好的用户界面,支持多种处理器架构,移植方便。
为程序分配系统资源,处理计算机内部细节的软件叫做操作系统或者内核。如果你希望详细了解操作系统的概念,请查看操作系统教程。
用户通过Shell与Linux内核交互。Shell是一个命令行解释工具(是一个软件),它将用户输入的命令转换为内核能够理解的语言(命令)。
Linux下,很多工作都是通过命令完成的,学好Linux,首先要掌握常用命令。
内核版本指的是在 Linus 领导下的开发小组开发出的系统内核的版本号。Linux 的每个内核版本使用形式为 x.y.zz-www 的一组数字来表示。其中:
当内核功能有一个飞跃时,主版本号升级,如 Kernel2.2、2.4、2.6等。如果内核增加了少量补丁时,常常会升级次版本号,如Kernel2.6.15、2.6.20等。
一些组织或厂家将 Linux 内核与GNU软件(系统软件和工具)整合起来,并提供一些安装界面和系统设定与管理工具,这样就构成了一个发型套件,例如Ubuntu、Red Hat、Centos、Fedora、SUSE、Debian、FreeBSD等。相对于内核版本,发行套件的版本号随着发布者的不同而不同,与系统内核的版本号是相对独立的。因此把Red Hat等直接说成是Linux是不确切的,它们是Linux的发行版本,更确切地说,应该叫做"以linux为核心的操作系统软件包"。
下面是Linux体系结构的示意图:
在所有Linux版本中,都会涉及到以下几个重要概念:
如果你有一台装有Linux的电脑,加电后系统会自动启动,然后提示你登录系统,只有登录后才能进行其他操作。
第一次使用Linux,会看到登录的提示,如下所示:
login:
-
login : amrood
-
amrood
's password:
-
Last login: Sun Jun
14
09:
32:
32
2009
from
62.61
.164
.73
-
$
-
登录后会出现命令提示符($),你可以输入任何命令。下面通过 cal 命令来查看日历:
-
$ cal
-
June
2009
-
Su Mo Tu We Th Fr Sa
-
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
-
-
$
-
Linux系统通过密码来保证数据和文件的安全,防止黑客破解和攻击。你可以通过以下方法来修改密码:
-
$ passwd
-
Changing password
for amrood
-
(current) Linux password:******
-
New Linux password:*******
-
Retype
new Linux password:*******
-
passwd: all authentication tokens updated successfully
-
-
$
-
注意:输入的密码是看不到的,只会看到一个占位符(*)。
在Linux中,所有的数据都被保存在文件中,所有的文件又被分配到不同的目录;目录是一种类似树的结构,称为文件系统。
你可以使用 ls 命令来查看当前目录下的文件和目录。下面的例子,使用了 ls 命令的 -l 选项:
-
$ ls -l
-
total 19621
-
drwxrwxr-x 2 amrood amrood 4096 Dec 25 09:59 uml
-
-rw-rw-r-- 1 amrood amrood 5341 Dec 25 08:38 uml.jpg
-
drwxr-xr-x 2 amrood amrood 4096 Feb 15 2006 univ
-
drwxr-xr-x 2 root root 4096 Dec 9 2007 urlspedia
-
-rw-r--r-- 1 root root 276480 Dec 9 2007 urlspedia.tar
-
drwxr-xr-x 8 root root 4096 Nov 25 2007 usr
-
-rwxr-xr-x 1 root root 3192 Nov 25 2007 webthumb.php
-
-rw-rw-r-- 1 amrood amrood 20480 Nov 25 2007 webthumb.tar
-
-rw-rw-r-- 1 amrood amrood 5654 Aug 9 2007 yourfile.mid
-
-rw-rw-r-- 1 amrood amrood 166255 Aug 9 2007 yourfile.swf
-
-
$
-
注意:以 d* 开头的为目录,如 uml、univ、urlspedia等;其他的都是文件。
登录系统后,如果你希望知道自己的用户名(用户ID),可以使用 whoami 命令:
$ whoami amrood $
如果你希望了解更多关于当前用户的信息,可以使用 who am i 命令,读者可以自己尝试一下。
如果你希望知道当前在线的用户(同时登录到系统的用户),可以使用 users、who 和 w 命令:
-
$ users
-
amrood bablu qadir
-
-
$ who
-
amrood ttyp0
Oct
8
14:
10 (limbo)
-
bablu ttyp2
Oct
4
09:
08 (calliope)
-
qadir ttyp4
Oct
8
12:
09 (dent)
-
-
$
-
w 命令可以看到在线用户的更多信息,读者可以自己尝试。
完成工作后,你需要退出系统,防止他人使用你的账户。
使用 logout 命令即可退出登录,系统会清理有关信息并断开连接。
关系Linux系统可以使用下列命令:
命令 |
说明 |
halt |
直接关闭系统 |
init 0 |
使用预先定义的脚本关闭系统,关闭前可以清理和更新有关信息 |
init 6 |
重新启动系统 |
poweroff |
通过断电来关闭系统 |
reboot |
重新启动系统 |
shutdown |
安全关闭系统 |
注意:一般情况下只有超级用户和root用户(Linux系统中的最高特权用户)才有关闭系统的权限,但是给普通用户赋予相应权限也可以关闭系统。
Linux中的所有数据都被保存在文件中,所有的文件被分配到不同的目录。目录是一种类似于树的结构,称为文件系统。
当你使用Linux时,大部分时间都会和文件打交道,通过本节可以了解基本的文件操作,如创建文件、删除文件、复制文件、重命名文件以及为文件创建链接等。
在Linux中,有三种基本的文件类型:
普通文件是以字节为单位的数据流,包括文本文件、源码文件、可执行文件等。文本和二进制对Linux来说并无区别,对普通文件的解释由处理该文件的应用程序进行。
目录可以包含普通文件和特殊文件,目录相当于Windows和Mac OS中的文件夹。
有些教程中称特殊文件,是一个含义。Linux 与外部设备(例如光驱,打印机,终端,modern等)是通过一种被称为设备文件的文件来进行通信。Linux 输入输出到外部设备的方式和输入输出到一个文件的方式是相同的。Linux 和一个外部设备通讯之前,这个设备必须首先要有一个设备文件存在。
例如,每一个终端都有自己的设备文件来供 Linux 写数据(出现在终端屏幕上)和读取数据(用户通过键盘输入)。
设备文件和普通文件不一样,设备文件中并不包含任何数据。
设备文件有两种类型:字符设备文件和块设备文件。
查看当前目录下的文件和目录可以使用 ls 命令,例如:
-
$ls
-
-
bin hosts lib res
.03
-
ch07 hw1 pub test_results
-
ch07.bak hw2 res
.01 users
-
docs hw3 res
.02 work
-
通过 ls 命令的 -l 选项,你可以获取更多文件信息,例如:
-
$ls -l
-
total 1962188
-
-
drwxrwxr-x 2 amrood amrood 4096 Dec 25 09:59 uml
-
-rw-rw-r-- 1 amrood amrood 5341 Dec 25 08:38 uml.jpg
-
drwxr-xr-x 2 amrood amrood 4096 Feb 15 2006 univ
-
drwxr-xr-x 2 root root 4096 Dec 9 2007 urlspedia
-
-rw-r--r-- 1 root root 276480 Dec 9 2007 urlspedia.tar
-
drwxr-xr-x 8 root root 4096 Nov 25 2007 usr
-
drwxr-xr-x 2 200 300 4096 Nov 25 2007 webthumb-1.01
-
-rwxr-xr-x 1 root root 3192 Nov 25 2007 webthumb.php
-
-rw-rw-r-- 1 amrood amrood 20480 Nov 25 2007 webthumb.tar
-
-rw-rw-r-- 1 amrood amrood 5654 Aug 9 2007 yourfile.mid
-
-rw-rw-r-- 1 amrood amrood 166255 Aug 9 2007 yourfile.swf
-
drwxr-xr-x 11 amrood amrood 4096 May 29 2007 zlib-1.2.3
-
$
-
每一列的含义如下:
注意:每一个目录都有一个指向它本身的子目录"." 和指向它上级目录的子目录"..",所以对于一个空目录,第二列应该为 2。
通过 ls -l 列出的文件,每一行都是以 a、d、- 或 l 开头,这些字符表示文件类型:
前缀 |
描述 |
- |
普通文件。如文本文件、二进制可执行文件、源代码等。 |
b |
块设备文件。硬盘可以使用块设备文件。 |
c |
字符设备文件。硬盘也可以使用字符设备文件。 |
d |
目录文件。目录可以包含文件和其他目录。 |
l |
符号链接(软链接)。可以链接任何普通文件,类似于 Windows 中的快捷方式。 |
p |
具名管道。管道是进程间的一种通信机制。 |
s |
用于进程间通信的套接字。 |
提示:通俗的讲软连接就是windows的快捷方式,原来文件删了,快捷方式虽然在但是不起作用了。
元字符是具有特殊含义的字符。* 和 ? 都是元字符:
例如
$ls ch*.doc
可以显示所有以 ch 开头,以 .doc 结尾的文件:
-
ch01-1.doc ch010.doc ch02.doc ch03-2.doc
-
ch04-1
.doc
ch040
.doc
ch05
.doc
ch06-2
.doc
-
ch01-2
.doc
ch02-1
.doc
c
-
这里,* 匹配任意一个字符。如果你希望显示所有以 .doc 结尾的文件,可以使用
$ls *.doc。
隐藏文件的第一个字符为英文句号或点号(.),Linux程序(包括Shell)通常使用隐藏文件来保存配置信息。
下面是一些常见的隐藏文件:
.profile:Bourne shell (sh) 初始化脚本
.kshrc:Korn shell (ksh) 初始化脚本
.cshrc:C shell (csh) 初始化脚本
.rhosts:Remote shell (rsh) 配置文件
查看隐藏文件需要使用 ls 命令的 -a 选项:
-
$ ls -a
-
-
. .profile docs lib test_results
-
.. .rhosts hosts pub users
-
.emacs bin hw1 res.
01 work
-
.exrc ch07 hw2 res.
02
-
.kshrc ch07.bak hw3 res.
03
-
$
-
一个点号(.)表示当前目录,两个点号(..)表示上级目录
注意:输入密码时,星号(*)作为占位符,代表你输入的字符个数。
在Linux中,可以使用 vi 编辑器创建一个文本文件,例如:
$ vi filename
上面的命令会创建文件 filename 并打开,按下 i 键即可进入编辑模式,你可以向文件中写入内容。例如:
-
This is Linux file....I created it for the first time.....
-
I
'm going to save this content in this file.
-
完成编辑后,可以按 esc 键退出编辑模式,也可以按组合键 Shift + ZZ 完全退出文件。这样,就完成了文件的创建。
$ vi filename $
vi 编辑器可以用来编辑文件。由于篇幅限制,这里仅作简单介绍,将在后面章节进行详细讲解。
如下可以打开一个名为 filename 的文件:
$ vi filename
当文件被打开后,可以按 i 键进入编辑模式,按照自己的方式编辑文件。如果想移动光标,必须先按 esc 键退出编辑模式,然后使用下面的按键在文件内移动光标:
使用上面的按键,可以将光标快速定位到你想编辑的地方。定位好光标后,按 i 键再次进入编辑模式。编辑完成后按 esc 键退出编辑模式或者按组合键 Shift+ZZ 退出当前文件。
可以使用 cat 命令来查看文件内容,下面是一个简单的例子:
-
$ cat filename
-
This
is Linux file....I created it
for the first
time.....
-
I
'm going to save this content in this file.
-
$
-
可以通过 cat 命令的 -b 选项来显示行号,例如:
-
$ cat -b filename
-
1 This
is Linux file....I created it
for the first
time.....
-
2 I
'm going to save this content in this file.
-
$
-
可以使用 wc 命令来统计当前文件的行数、单词数和字符数,下面是一个简单的例子:
-
$ wc filename
-
2
19
103 filename
-
$
-
每一列的含义如下:
也可以一次查看多个文件的内容,例如:
$ wc filename1 filename2 filename3
可以使用 cp 命令来复制文件。cp 命令的基本语法如下:
$ cp source_file destination_file
下面的例子将会复制 filename 文件:
$ cp filename copyfile $
现在在当前目录中会多出一个和 filename 一模一样的 copyfile 文件。
重命名文件可以使用 mv 命令,语法为:
$ mv old_file new_file
下面的例子将会把 filename 文件重命名为 newfile:
$ mv filename newfile $
现在在当前目录下,只有一个 newfile 文件。
mv 命令其实是一个移动文件的命令,不但可以更改文件的路径,也可以更改文件名。
rm命令可以删除文件,语法为:
$ rm filename
注意:删除文件是一种危险的行为,因为文件内可能包含有用信息,建议结合 -i 选项来使用 rm 命令。
下面的例子会彻底删除一个文件:
$ rm filename $
你也可以一次删除多个文件:
$ rm filename1 filename2 filename3 $
一般情况下,每个Linux程序运行时都会创建三个文件流(三个文件):
目录也是一个文件,它的唯一功能是用来保存文件及其相关信息。所有的文件,包括普通文件、设备文件和目录文件,都会被保存到目录中。
登录后,你所在的位置就是你的主目录(或登录目录),接下来你主要是在这个目录下进行操作,如创建文件、删除文件等。
使用下面的命令可以随时进入主目录:
$cd ~ $
这里 ~ 就表示主目录。如果你希望进入其他用户的主目录,可以使用下面的命令:
$cd ~username $
返回进入当前目录前所在的目录可以使用下面的命令:
$cd - $
Linux 的目录有清晰的层次结构,/ 代表根目录,所有的目录都位于 / 下面;文件在层次结构中的位置可以用路径来表示。
如果一个路径以 / 开头,就称为绝对路径;它表示当前文件与根目录的关系。举例如下:
/etc/passwd /users/sjones/chem/notes /dev/rdsk/Os3
不以 / 开头的路径称为相对路径,它表示文件与当前目录的关系。例如:
chem/notes personal/res
获取当前所在的目录可以使用 pwd 命令:
-
$pwd
-
/user
0/home/amrood
-
-
$
-
查看目录中的文件可以使用 ls 命令:
$ls dirname
下面的例子将遍历 /usr/local 目录下的文件:
-
$ls /usr/local
-
-
X11 bin gimp jikes sbin
-
ace doc
include lib share
-
atalk etc info man ami
-
可以使用 mkdir 命令来创建目录,语法为:
$mkdir dirname
dirname 可以为绝对路径,也可以为相对路径。例如
$mkdir mydir $
会在当前目录下创建 mydir 目录。又如
-
$mkdir /tmp/test-dir
-
$
-
会在 /tmp 目录下创建 test-dir 目录。mkdir 成功创建目录后不会输出任何信息。
也可以使用 mkdir 命令同时创建多个目录,例如
$mkdir docs pub $
会在当前目录下创建 docs 和 pub 两个目录。
使用 mkdir 命令创建目录时,如果上级目录不存在,就会报错。下面的例子中,mkdir 会输出错误信息:
-
$mkdir /tmp/amrood/test
-
mkdir: Failed to make directory
"/tmp/amrood/test";
-
No such file
or directory
-
$
-
为 mkdir 命令增加 -p 选项,可以一级一级创建所需要的目录,即使上级目录不存在也不会报错。例如
-
$mkdir -p /tmp/amrood/test
-
$
-
会创建所有不存在的上级目录。
可以使用 rmdir 命令来删除目录,例如:
$rmdir dirname $
注意:删除目录时请确保目录为空,不会包含其他文件或目录。
也可以使用 rmdir 命令同时删除多个目录:
$rmdir dirname1 dirname2 dirname3 $
如果 dirname1、dirname2、dirname3 为空,就会被删除。rmdir 成功删除目录后不会输出任何信息。
可以使用 cd 命令来改变当前所在目录,进入任何有权限的目录,语法为:
$cd dirname
dirname 为路径,可以为相对路径,也可以为绝对路径。例如
-
$cd /usr/local/bin
-
$
-
可以进入 /usr/local/bin 目录。可以使用相对路径从这个目录进入 /usr/home/amrood 目录:
$cd ../../home/amrood $
mv (move) 命令也可以用来重命名目录,语法为:
$mv olddir newdir
下面的例子将会把 mydir 目录重命名为 yourdir 目录:
$mv mydir yourdir $
一个点号(.)表示当前目录,两个点号(..)表示上级目录(父目录)。
ls 命令的 -a 选项可以查看所有文件,包括隐藏文件;-l 选项可以查看文件的所有信息,共有7列。例如:
-
$ls -la
-
drwxrwxr-x
4 teacher
class 2048 Jul 16 17.56 .
-
drwxr-xr-x
60 root
1536 Jul
13
14:
18 ..
-
----------
1 teacher
class 4210 May 1 08:27 .profile
-
-rwxr-xr-x
1 teacher
class 1948 May 12 13:42 memo
-
$
-
为了更加安全的存储文件,Linux为不同的文件赋予了不同的权限,每个文件都拥有下面三种权限:
使用 ls -l 命令可以查看与文件权限相关的信息:
-
$ls -l /home/amrood
-
-rwxr-xr
-- 1 amrood users 1024 Nov 2 00:10 myfile
-
drwxr-xr
--- 1 amrood users 1024 Nov 2 00:10 mydir
-
第一列就包含了文件或目录的权限。
第一列的字符可以分为三组,每一组有三个,每个字符都代表不同的权限,分别为读取(r)、写入(w)和执行(x):
文件权限是Linux系统的第一道安全防线,基本的权限有读取(r)、写入(w)和执行(x):
目录的访问模式和文件类似,但是稍有不同:
可以使用 chmod (change mode) 命令来改变文件或目录的访问权限,权限可以使用符号或数字来表示。
对于初学者来说最简单的就是使用符号来改变文件或目录的权限,你可以增加(+)和删除(-)权限,也可以指定特定权限。
符号 |
说明 |
+ |
为文件或目录增加权限 |
- |
删除文件或目录的权限 |
= |
设置指定的权限 |
下面的例子将会修改 testfile 文件的权限:
-
$ls -l testfile
-
-rwxrwxr--
1 amrood users
1024 Nov
2
00:
10 testfile
-
$chmod o+wx testfile
-
$ls -l testfile
-
-rwxrwxrwx
1 amrood users
1024 Nov
2
00:
10 testfile
-
$chmod u-x testfile
-
$ls -l testfile
-
-rw-rwxrwx
1 amrood users
1024 Nov
2
00:
10 testfile
-
$chmod g=rx testfile
-
$ls -l testfile
-
-rw-r-xrwx
1 amrood users
1024 Nov
2
00:
10 testfile
-
也可以同时使用多个符号:
-
$chmod o+wx,u-x,g=rx testfile
-
$ls -l testfile
-
-rw-r-xrwx
1 amrood users
1024 Nov
2
00:
10 testfile
-
除了符号,也可以使用八进制数字来指定具体权限,如下表所示:
数字 |
说明 |
权限 |
0 |
没有任何权限 |
--- |
1 |
执行权限 |
--x |
2 |
写入权限 |
-w- |
3 |
执行权限和写入权限:1 (执行) + 2 (写入) = 3 |
-wx |
4 |
读取权限 |
r-- |
5 |
读取和执行权限:4 (读取) + 1 (执行) = 5 |
r-x |
6 |
读取和写入权限:4 (读取) + 2 (写入) = 6 |
rw- |
7 |
所有权限: 4 (读取) + 2 (写入) + 1 (执行) = 7 |
rwx |
下面的例子,首先使用 ls -1 命令查看 testfile 文件的权限,然后使用 chmod 命令更改权限:
-
$ls -l testfile
-
-rwxrwxr--
1 amrood users
1024 Nov
2
00:
10 testfile
-
$
chmod
755 testfile
-
$ls -l testfile
-
-rwxr-xr-
x
1 amrood users
1024 Nov
2
00:
10 testfile
-
$chmod
743 testfile
-
$ls -l testfile
-
-rwxr---wx
1 amrood users
1024 Nov
2
00:
10 testfile
-
$chmod
043 testfile
-
$ls -l testfile
-
----r---wx
1 amrood users
1024 Nov
2
00:
10 testfile
-
在Linux中,每添加一个新用户,就会为它分配一个用户ID和群组ID,上面提到的文件权限也是基于用户和群组来分配的。
有两个命令可以改变文件的所有者或群组:
chown 命令用来更改文件所有者,其语法如下:
-
$ chown user filelist
-
user 可以是用户名或用户ID,例如
$ chown amrood testfile $
将 testfile 文件的所有者改为 amrood。
注意:超级用户 root 可以不受限制的更改文件的所有者和用户组,但是普通用户只能更改所有者是自己的文件或目录。
chgrp 命令用来改变文件所属群组,其语法为:
-
$ chgrp group filelist
-
group可以是群组名或群组ID,例如
$ chgrp special testfile $
将文件 testfile 的群组改为 special。
在Linux中,一些程序需要特殊权限才能完成用户指定的操作。
例如,用户的密码保存在 /etc/shadow 文件中,出于安全考虑,一般用户没有读取和写入的权限。但是当我们使用passwd 命令来更改密码时,需要对 /etc/shadow 文件有写入权限。这就意味着,passwd 程序必须要给我们一些特殊权限,才可以向 /etc/shadow 文件写入内容。
Linux 通过给程序设置SUID(Set User ID)和SGID(Set Group ID)位来赋予普通用户特殊权限。当我们运行一个带有SUID位的程序时,就会继承该程序所有者的权限;如果程序不带SUID位,则会根据程序使用者的权限来运行。
SGID也是一样。一般情况下程序会根据你的组权限来运行,但是给程序设置SGID后,就会根据程序所在组的组权限运行。
如果程序设置了SUID位,就会在表示文件所有者可执行权限的位置上出现's'字母;同样,如果设置了SGID,就会在表示文件群组可执行权限的位置上出现's'字母。如下所示:
-
$ ls -l /usr/bin/passwd
-
-r-
sr-xr-x 1 root bin 19031 Feb 7 13:47 /usr/bin/passwd*
-
$
-
上面第一列第四个字符不是'x'或'-',而是's',说明 /usr/bin/passwd 文件设置了SUID位,这时普通用户会以root用户的权限来执行passwd程序。
注意:小写字母's'说明文件所有者有执行权限(x),大写字母'S'说明程序所有者没有执行权限(x)。
如果在表示群组权限的位置上出现SGID位,那么也仅有三类用户可以删除该目录下的文件:目录所有者、文件所有者、超级用户 root。
为一个目录设置SUID和SGID位可以使用下面的命令:
-
$ chmod ug+s dirname
-
$ ls -l
-
drwsr-sr-x
2 root root
4096 Jun
19
06
:
45 dirname
-
$
-
在Linux中,环境变量是一个很重要的概念。环境变量可以由系统、用户、Shell以及其他程序来设定。
变量就是一个可以被赋值的字符串,赋值范围包括数字、文本、文件名、设备以及其他类型的数据。
下面的例子,我们将为变量 TEST 赋值,然后使用 echo 命令输出:
-
$TEST="Linux Programming"
-
$echo $TEST
-
Linux Programming
-
注意:变量赋值时前面不能加 $ 符号,变量输出时必须要加 $ 前缀。退出 Shell 时,变量将消失。
登录系统后,Shell会有一个初始化的过程,用来设置环境变量。这个阶段,Shell会读取 /etc/profile 和 .profile 两个文件,过程如下:
读取完上面两个文件,Shell就会出现 $ 命令提示符:
$
出现这个提示符,就可以输入命令并调用相应的程序了。
注意:上面是Bourne Shell的初始化过程,bash 和 ksh 在初始化过程中还会检查其他文件。
/etc/profile文件包含了通用的Shell初始化信息,由Linux管理员维护,一般用户无权修改。
但是你可以修改主目录下的 .profile 文件,增加一些"私人定制"初始化信息,包括:
找到主目录下的 .profile 文件,使用 vi 编辑器打开并查看内容。
一般情况下,我们使用的终端是由 login 或 getty 程序设置的,可能会不符合我们的习惯。
对于没有使用过的终端,可能会比较生疏,不习惯命令的输出样式,交互起来略显吃力。所以,一般用户会将终端设置成下面的类型:
-
$TERM=vt100
-
$
-
vt100 是 virtual terminate 100 的缩写。虚拟终端是一种假的终端,真正有自己的显示器和键盘的终端,会通过特殊电缆(如串口)连到计算机主机。vt100 是被绝大多数Linux系统所支持的一种虚拟终端规范,常用的还有ansi、xterm等。
在命令提示符下输入一个命令时,Shell 会根据 PATH 变量来查找该命令对应的程序,PATH变量指明了这些程序所在的路径。
一般情况下PATH变量的设置如下:
-
$PATH=/bin:/usr/bin
-
$
-
多个路径使用冒号(:)分隔。如果用户输入的命令在PATH设置的路径下没有找到,就会报错,例如:
-
$hello
-
hello:
not found
-
$
-
PS1变量用来保存命令提示符,可以随意修改,如果你不习惯使用 $ 作为提示符,也可以改成其他字符。PS1变量被修改后,提示符会立即改变。
例如,把命令提示符设置成'=>':
-
$PS1='=>'
-
=>
-
=>
-
=>
-
也可以将提示信息设置成当前目录,例如:
-
=>PS1="[\u@\h \w]\$"
-
[root@ip-
72-
167-
112-
17 /var/www/tutorialspoint/Linux]$
-
[root@ip-
72-
167-
112-
17 /var/www/tutorialspoint/Linux]$
-
命令提示信息包含了用户名、主机名和当前目录。
下表中的转义字符可以被用作PS1的参数,丰富命令提示符信息。
转义字符 |
描述 |
\t |
当前时间,格式为 HH:MM:SS |
\d |
当前日期,格式为Weekday Month Date |
\n |
换行 |
\W |
当前所在目录 |
\w |
当前所在目录的完整路径 |
\u |
用户名 |
\h |
主机名(IP地址) |
# |
输入的命令的个数,每输入一个新的命令就会加1 |
\$ |
如果是超级用户 root,提示符为#,否则为$。 |
你可以在每次登录的时候修改提示符,也可以在 .profile 文件中增加 PS1 变量,这样每次登录时会自动修改提示符。
如果用户输入的命令不完整,Shell还会使用第二提示符来等待用户完成命令的输入。默认的第二命令提示符是 >,保存在 PS2 变量,可以随意修改。
下面的例子使用默认的第二命令提示符:
-
$ echo "this is a
-
> test"
-
this is a
-
test
-
$
-
下面的例子通过PS2变量改变提示符:
-
$ PS2="secondary prompt->"
-
$ echo
"this is a
-
secondary prompt->test"
-
this is a
-
test
-
$
-
下表列出了部分重要的环境变量,这些变量可以通过上面提到的方式修改。
变量 |
描述 |
DISPLAY |
用来设置将图形显示到何处。 |
HOME |
当前用户的主目录。 |
IFS |
内部域分隔符。 |
LANG |
LANG可以让系统支持多语言。例如,将LANG设为pt_BR,则可以支持(巴西)葡萄牙语。 |
PATH |
指定Shell命令的路径。 |
PWD |
当前所在目录,即 cd 到的目录。 |
RANDOM |
生成一个介于 0 和 32767 之间的随机数。 |
TERM |
设置终端类型。 |
TZ |
时区。可以是AST(大西洋标准时间)或GMT(格林尼治标准时间)等。 |
UID |
以数字形式表示的当前用户ID,shell启动时会被初始化。 |
下面的例子中使用了部分环境变量:
-
$ echo $HOME
-
/root
-
]$
echo
$DISPLAY
-
-
$
echo
$TERM
-
xterm
-
$
echo
$PATH
-
/usr/
local/bin:/bin:/usr/bin:/home/amrood/bin:/usr/
local/bin
-
$
-
通过前面的介绍,相信你对 Linux 的命令和特性有了一个基本的认识,本节将介绍如果打印文件以及发送邮件。
如果你希望打印文本文件,最好预先处理一下,包括调整边距、设置行高、设置标题等,这样打印出来的文件更加美观,易于阅读。当然,不处理也可以打印,但是可能会比较丑陋。
大部分的Linux自带了 nroff 和 troff 两个强大的文本格式化工具,不过比较老旧,使用的人很少,有兴趣的读者可以可以自行学习,本教程不再进行深入讲解。
pr 命令用来将文本文件转换成适合打印的格式,它可以把较大的文件分割成多个页面进行打印,并为每个页面添加标题。
pr 命令的语法如下:
-
pr option(s) filename(s)
-
pr 命令仅仅改变文件在屏幕上的显示样式和打印输出样式,并不会更改文件本身。下表是 pr 命令的几个选项:
选项 |
说明 |
-k |
分成几列打印,默认为1。 |
-d |
两倍行距(并不是所有版本的 pr 都有效)。 |
-h "header" |
设置每个页面的标题。 |
-t |
不打印标题和上下边距。 |
-l PAGE_LENGTH |
每页显示多少行。默认是每个页面一共66行,文本占56行。 |
-o MARGIN |
每行缩进的空格数。 |
-w PAGE_WIDTH |
多列输出时,设置页面宽度,默认是72个字符。 |
例如,food 文件包含了很多食品的名字,使用 pr 命令分成两列打印,并设置每页的标题为"Restaurants"。
首先查看文件内容:
-
$cat food
-
Sweet Tooth
-
Bangkok Wok
-
Mandalay
-
Afghani Cuisine
-
Isle
of Java
-
Big Apple Deli
-
Sushi
and Sashimi
-
Tio Pepe
's Peppers
-
........
-
$
-
然后使用 pr 命令打印:
-
$pr -2 -h "Restaurants" food
-
Nov
7
9:
58
1997 Restaurants Page
1
-
-
Sweet Tooth Isle
of Java
-
Bangkok Wok Big Apple Deli
-
Mandalay Sushi
and Sashimi
-
Afghani Cuisine Tio Pepe
's Peppers
-
........
-
$
-
lp 和 lpr 命令将文件传送到打印机进行打印。使用 pr 命令将文件格式化后就可以使用这两个命令来打印。
打印机一般由系统管理员来设置,下面的例子使用默认的打印机打印food文件:
-
$lp food
-
request id
is laserp
-525 (
1 file)
-
$
-
命令成功执行会返回一个表示打印任务的ID,通过这个ID可以取消打印或者查看打印状态。
如果你希望打印多份文件,可以使用 lp 的 -nNum 选项,或者 lpr 命令的 -Num 选项。Num 是一个数字,可以随意设置。
如果系统连接了多台打印机,可以使用 lp 命令的 -dprinter 选项,或者 lpr 命令的 -Pprinter 选项来选择打印机。printer 为打印机名称。
lpstat 命令可以查看打印机的缓存队列(有多少个文件等待打印),包括任务ID、所有者、文件大小、请求时间和请求状态。
提示:等待打印的文件会被放到打印机的的缓存队列中。
例如,使用 lpstat -o 命令查看打印机中所有等待打印的文件,包括你自己的:
-
$lpstat -o
-
laserp-
573 john
128865 Nov
7
11
:
27 on laserp
-
laserp-
574 grace
82744 Nov
7
11
:
28
-
laserp-
575 john
23347 Nov
7
11
:
35
-
$
-
lpstat -o 命令按照打印顺序输出队列中的文件。
lpq 命令显示的信息与 lpstat -o 稍有差异:
-
$lpq
-
laserp is ready
and printing
-
Rank Owner Job Files Total Size
-
active john
573 report.ps
128865 bytes
-
1st grace
574 ch03.ps ch04.ps
82744 bytes
-
2nd john
575 standard input
23347 bytes
-
$
-
第一行为打印机的状态。如果打印机无法使用或者纸被用完,将会输出其他信息。
cancel 和 lprm 分别用来终止 lp 和 lpr 的打印请求。使用这两个命令,需要指定ID(由 lp 或 lpq 返回)或打印机名称。
例如,通过ID取消打印请求:
-
$cancel laserp-575
-
request
"laserp-575" cancelled
-
$
-
如果希望取消正在打印的文件,那么可以不指定ID,仅仅指定打印机名称即可:
-
$cancel laserp
-
request
"laserp-573" cancelled
-
$
-
lprm 命令用来取消当前用户的正在等待打印的文件,使用任务号作为参数可以取消指定文件,使用横线(-)作为参数可以取消所有文件。
例如,取消575号打印任务:
-
$lprm 575
-
dfA575diamond dequeued
-
cfA575diamond dequeued
-
$
-
lprm 会返回被取消的文件名。
可以使用mail命令发送和接收邮件,语法如下:
-
$mail [-s subject] [-c cc-addr] [-b bcc-addr] to-addr
-
每个选项的含义如下:
选项 |
描述 |
-s |
邮件标题。 |
-c |
要发送的用户,多个用户以逗号(,)分隔。 |
-b |
需要密件发送(密送)的用户,多个用户以逗号(,)分隔。 |
例如,向[email protected]发送邮件:
-
$mail -s "Test Message" admin@yahoo.com
-
Hello everyone,
-
this
is Linux tutorial and url
is http:
//see.xidian.edu.cn/cpp/linux/.
-
Cc:
-
第一行是输入的命令,-s表示邮件的主题,后面的[email protected]则是邮件的接收人,输入完这行命令后回车,会进入邮件正文的编写,你可以输入任何文字,比如上面的两行。输入完邮件正文,需要按CTRL+D结束输入,此时会提示你输入Cc地址,即邮件抄送地址,没有直接回车就完成了邮件的发送。
也可以通过重定向操作符 < 来发送文件:
-
$mail -s "Report 05/06/07" [email protected] < demo.txt
-
通过上面的命令,就可以把demol.txt文件的内容作为邮件的内容发送给[email protected]了。
接收邮件不需要任何参数:
-
$mail
-
no email
-
有时候,我们可以把两个命令连起来使用,一个命令的输出作为另一个命令的输入,这就叫做管道。为了建立管道,需要在两个命令之间使用竖线(|)连接。
管道是Linux进程之间一种重要的通信机制;除了管道,还有共享内存、消息队列、信号、套接字(socket) 等进程通信机制。
管道使用竖线(|)将两个命令隔开,竖线左边命令的输出就会作为竖线右边命令的输入。连续使用竖线表示第一个命令的输出会作为第二个命令的输入,第二个命令的输出又会作为第三个命令的输入,依此类推。
能够接受数据,过滤(处理或筛选)后再输出的工具,称为过滤器。
grep 是一个强大的文本搜索工具,可以使用正则表达式,并返回匹配的行,语法为:
$grep pattern file(s)
"grep"源于 ed(Linux的一个行文本编辑器)的 g/re/p 命令,g/re/p 是"globally search for a regular expression and print all lines containing it"的缩写,意思是使用正则表达式进行全局检索,并把匹配的行打印出来。
正则表达式是一个包含了若干特殊字符的字符串,每个字符都有特殊含义,可以用来匹配文本,更多信息请查看正则表达式教程。
grep 可以看做是一个过滤器,如果没有为 grep 指定要检索的文件,那么它会从标准输入设备(一般是键盘)读取;其他过滤器也是如此。
grep 命令最简单的使用就是检索包含固定字符的文本。
例如,在管道中使用 grep 命令,只允许包含指定字符的行输出到显示器:
-
$ls -l | grep "Aug"
-
-rw-rw-rw- 1 john doc 11008 Aug 6 14:10 ch02
-
-rw-rw-rw- 1 john doc 8515 Aug 6 15:30 ch07
-
-rw-rw-r-- 1 john doc 2488 Aug 15 10:51 intro
-
-rw-rw-r-- 1 carol doc 1605 Aug 23 07:35 macros
-
$
-
grep 命令有很多选项:
选项 |
说明 |
-v |
反转查询,输出不匹配的行。例如,grep -v "test" demo.txt 将输出不包含"test"的行。 |
-n |
输出匹配的行以及行号。 |
-l |
输出匹配的行所在的文件名。 |
-c |
输出匹配的总行数。 |
-i |
不区分大小写进行匹配。 |
下面我们使用正则表达式来匹配这样的行:包含字符"carol",然后包含任意数目(含零个)的其他字符,最后还要包含"Aug"。
使用 -i 选项进行不区分大小写的匹配:
-
$ls -l | grep -i "carol.*aug"
-
-rw-rw-r--
1 carol doc
1605 Aug
23
07:
35 macros
-
$
-
sort 命令在 Linux 中非常有用,它将文件中的各行按字母或数进行排序。sort命令既可以从特定的文件,也可以从stdin获取输入。
例如,对 foot 文件的各行进行排序:
-
$sort food
-
Afghani Cuisine
-
Bangkok Wok
-
Big Apple Deli
-
Isle
of Java
-
Mandalay
-
Sushi
and Sashimi
-
Sweet Tooth
-
Tio Pepe
's Peppers
-
$
-
通过下面的选项可以控制排序规则:
选项 |
描述 |
-n |
按照数字大小排序,例如,10会排在2后面;-n 选项会忽略空格或 tab缩进。 |
-r |
降序排序。sort 默认是升序排序。 |
-f |
不区分大小写。 |
+x |
对第x列(从0开始)进行排序。 |
下面的例子通过管道将 ls、grep 和 sort 命令连起来使用,过滤包含"Aug"的行,并按照文件大小排序:
-
$ls -l | grep "Aug" | sort +4n
-
-rw-rw-r--
1 carol doc
1605 Aug
23
07:
35 macros
-
-rw-rw-r--
1 john doc
2488 Aug
15
10:
51 intro
-
-rw-rw-rw-
1 john doc
8515 Aug
6
15:
30 ch07
-
-rw-rw-rw-
1 john doc
11008 Aug
6
14:
10 ch02
-
$
-
上面的命令,对当前目录中八月份修改的文件按照大小排序;+4n 表示对第5列按照数字大小排序。
如果文件内容过多,全部显示会很乱,可以使用 pg 和 more 命令分页显示,每次只显示一屏。
例如,通过管道,使用more命令显示目录中的文件:
-
$ls -l | grep "Aug" | sort +4n | more
-
-rw-rw-r-- 1 carol doc 1605 Aug 23 07:35 macros
-
-rw-rw-r-- 1 john doc 2488 Aug 15 10:51 intro
-
-rw-rw-rw- 1 john doc 8515 Aug 6 15:30 ch07
-
-rw-rw-r-- 1 john doc 14827 Aug 9 12:40 ch03
-
.
-
.
-
.
-
-rw-rw-rw- 1 john doc 16867 Aug 6 15:56 ch05
-
--More--(74%)
-
如上,一次只显示一屏文本,显示满后,停下来,并提示已显示全部内容的百分比,按空格键(space)可以查看下一屏,按 b 键可以查看上一屏。
当我们运行程序时,Linux会为程序创建一个特殊的环境,该环境包含程序运行需要的所有资源,以保证程序能够独立运行,不受其他程序的干扰。这个特殊的环境就称为进程。
每个 Linux 命令都与系统中的程序对应,输入命令,Linux 就会创建一个新的进程。例如使用 ls 命令遍历目录中的文件时,就创建了一个进程。
简而言之,进程就是程序的实例。
系统通过一个五位数字跟踪程序的运行状态,这个数字称为 pid 或进程ID。每个进程都拥有唯一的 pid。
理论上,五位数字是有限的,当数字被用完时,下一个 pid 就会重新开始,所以 pid 最终会重复。但是,两个 pid 一样的进程不能同时存在,因为Linux会使用 pid 来跟踪程序的运行状态。
有两种方式来创建进程:前台进程和后台进程。
默认情况下,用户创建的进程都是前台进程;前台进程从键盘读取数据,并把处理结果输出到显示器。
我们可以看到前台进程的运行过程。例如,使用 ls 命令来遍历当前目录下的文件:
-
$ls ch*.doc
-
ch01
-1.doc ch010.doc ch02.doc ch03
-2.doc
-
ch04
-1.doc ch040.doc ch05.doc ch06
-2.doc
-
ch01
-2.doc ch02
-1.doc
-
这个程序就运行在前台,它会直接把结果输出到显示器。如果 ls 命令需要数据(实际上不需要),那么它会等待用户从键盘输入。
当程序运行在前台时,由于命令提示符($)还未出现,用户不能输入其他命令;即使程序需要运行很长时间,也必须等待程序运行结束才能输入其他命令。
后台进程与键盘没有必然的关系。当然,后台进程也可能会等待键盘输入。
后台进程的优点是不必等待程序运行结束就可以输入其他命令。
创建后台进程最简单的方式就是在命令的末尾加 &,例如:
-
$ls ch*.doc &
-
ch01
-1.doc ch010.doc ch02.doc ch03
-2.doc
-
ch04
-1.doc ch040.doc ch05.doc ch06
-2.doc
-
ch01
-2.doc ch02
-1.doc
-
如果 ls 命令需要输入(实际上不需要),那么它会暂停,直到用户把它调到前台并从键盘输入数据才会继续运行。
可以使用 ps 命令查看进程的运行状态,包括后台进程,例如:
-
$ps
-
PID TTY
TIME CMD
-
18358 ttyp3
00:
00:
00 sh
-
18361 ttyp3
00:
01:
31 abiword
-
18789 ttyp3
00:
00:
00 ps
-
还可以结合 -f 选项查看更多信息,f 是 full 的缩写,例如:
-
$ps -f
-
UID PID PPID C STIME TTY TIME
CMD
-
amrood
6738
3662
0
10:
23:
03 pts/
6
0:
00 first_one
-
amrood
6739
3662
0
10:
22:
54 pts/
6
0:
00 second_one
-
amrood
3662
3657
0
08:
10:
53 pts/
6
0:
00 -ksh
-
amrood
6892
3662
4
10:
51:
50 pts/
6
0:
00 ps -f
-
每列的含义如下:
列 |
描述 |
UID |
进程所属用户的ID,即哪个用户创建了该进程。 |
PID |
进程ID。 |
PPID |
父进程ID,创建该进程的进程称为父进程。 |
C |
CPU使用率。 |
STIME |
进程被创建的时间。 |
TTY |
与进程有关的终端类型。 |
TIME |
进程所使用的CPU时间。 |
CMD |
创建该进程的命令。 |
ps 命令还有其他一些选项:
选项 |
说明 |
-a |
显示所有用户的所有进程。 |
-x |
显示无终端的进程。 |
-u |
显示更多信息,类似于 -f 选项。 |
-e |
显示所有进程。 |
当进程运行在前台时,可以通过 kill 命令或 Ctrl+C 组合键来结束进程。
如果进程运行在后台,那么首先要通过 ps 命令来获取进程ID,然后使用 kill 命令"杀死"进程,例如:
-
$ps -f
-
UID PID PPID C STIME TTY TIME CMD
-
amrood
6738
3662
0
10:
23:
03 pts/
6
0:
00 first_one
-
amrood
6739
3662
0
10:
22:
54 pts/
6
0:
00 second_one
-
amrood
3662
3657
0
08:
10:
53 pts/
6
0:
00 -ksh
-
amrood
6892
3662
4
10:
51:
50 pts/
6
0:
00 ps -f
-
$kill
6738
-
Terminated
-
如上所示,kill 命令终结了 first_one 进程。
如果进程忽略 kill 命令,那么可以通过 kill -9 来结束:
-
$kill -9 6738
-
Terminated
-
每个 Linux 进程会包含两个进程ID:当前进程ID(pid)和父进程ID(ppid)。可以暂时认为所有的进程都有父进程。
由用户运行的大部分命令都将 Shell 作为父进程,使用 ps -f 命令可以查看当前进程ID和父进程ID。
正常情况下,子进程被终止时会通过 SIGCHLD 信号通知父进程,父进程可以做一些清理工作或者重新启动一个新的进程。但在某些情况下,父进程会在子进程之前被终止,那么这些子进程就没有了"父亲",被称为孤儿进程。
init 进程会成为所有孤儿进程的父进程。init 的 pid 为1,是Linux系统的第一个进程,也是所有进程的父进程。
如果一个进程被终止了,但是使用 ps 命令仍然可以查看该进程,并且状态为 Z,那么这就是一个僵尸进程。僵尸进程虽然被终止了,但是仍然存在于进程列表中。一般僵尸进程很难杀掉,你可以先杀死他们的父进程,让他们变成孤儿进程,init 进程会自动清理僵尸进程。
常驻进程一般是系统级进程,以 root 权限运行在后台,可以处理其他进程的请求。
常驻进程没有终端,不能访问 /dev/tty 文件,如果使用 ps -ef 查看该进程,tty 这一列会显示问号(?)。
更确切地说,常驻进程通常运行在后台,等待指定事件发生,例如打印进程是一个常驻进程,它会等待用户输入打印相关的命令并进行处理。
top 命令是一个很有用的工具,它可以动态显示正在运行的进程,还可以按照指定条件对进程进行排序,与Windows的任务管理器类似。
top 命令可以显示进程的很多信息,包括物理内存、虚拟内存、CPU使用率、平均负载以及繁忙的进程等。例如:
$top
这里仅给出一个示意图,读者最好亲自运行一下:
任务(task)是最抽象的,是一个一般性的术语,指由软件完成的一个活动。一个任务既可以是一个进程,也可以是多个进程。简而言之,它指的是一系列共同达到某一目的的操作。例如,读取数据并将数据放入内存中。这个任务可以由一个进程来实现,也可以由多个进程来实现。 每个任务都有一个数字表示的任务号。
进程(process)常常被定义为程序的执行。可以把一个进程看成是一个独立的程序,在内存中有其完备的数据空间和代码空间。一个进程所拥有的数据和变量只属于它自己。
jobs 命令可以用来查看系统中正在运行的任务,包括后台运行的任务。该命令可以显示任务号及其对应的进程ID。一个任务可以对应于一个或者多个进程号。
jobs 命令的 -l 选项可以查看当前任务包含的进程ID:
-
$jobs -l
-
[
1] +
1903 running ls ch*.doc &
-
$
-
其中,第一列表示任务号,第二列表示任务对应的进程ID,第三列表示任务的运行状态,第四列表示启动任务的命令。
fg 命令可以将后台任务调到前台,语法为:
$fg %jobnumber
jobnumber 是通过 jobs 命令获取的后台任务的的序号,注意不是pid。如果后台只有一个任务,可以不指定 jobnumber。
bg 命令可以将后台暂停的任务,调到前台继续运行,语法为:
$bg %jobnumber
jobnumber 同样是通过 jobs 命令获取的后台任务的的序号,注意不是pid。如果前台只有一个任务,可以不指定 jobnumber。
如果希望将当前任务转移到后台,可以先 Ctrl+z 暂停任务,再使用 bg 命令。任务转移到后台可以空出终端,继续输入其他命令。
现在是一个互联网的时代,你不可避免的要和其他用户进行远程交流,连接到远程主机。
ping 命令会向网络上的主机发送应答请求,根据响应信息可以判断远程主机是否可用。
ping 命令的语法:
-
$ping hostname or ip-address
-
如果网络畅通,很快就可以看到响应信息。
例如,检测是否可以连接到谷歌的主机:
-
$ping google.com
-
PING google.com (
74.125.
67.100)
56(