前言

对于普通的PC使用者来说,学会使用Windows操作系统已经足够了。但是,对于一个软件开发者来说,仅仅会使用Windows操作系统是不行的,还需要学会使用Linux操作系统。《Linux命令行大全》正是一本能够帮助初学者系统了解Linux操作系统基本操作的书籍,因此我决定仔细阅读一下。为了方便以后查阅相关知识点,我决定将所学知识记录下来。和《Linux命令行大全》一书一样,笔者并不打算告诉你如何安装Linux操作系统,安装Linux操作系统的详细步骤可以在网络上方便地找到,在此,就不再赘述了。大多数Linux书籍都会告诉你使用Vmware或其它虚拟机安装Linux操作系统。在这里,笔者直接使用阿里云的ECS服务器Centos 6.8,这是Linux的一种发行版本,在互联网行业中得到广泛使用。一般情况下,我们都不会直接操作Linux操作系统,更普遍的情况是,我们会通过Xshell等终端远程连接、访问并操作Linux操作系统。

Xshell简介

Xshell是一个强大的安全终端模拟软件,它支持SSH1, SSH2, 以及Microsoft Windows平台的TELNET协议,可以用来连接并操作远端服务器。Xshell提供了个人和家庭使用的免费版本,而且其安装也是相当简单的,读者可以自行搜索Xshell下载并安装。

当我们准备好Linux操作系统,并通过Xshell连接到远程服务器并登录后,就可以进行相关操作了。

初探Linux操作系统

既然是初探,就应该循序渐进,而不是揠苗助长。学习Linux系统,其实主要学习的是命令行命令。因此,我们先从简单的Linux命令入手。

首先,我们学习如何显示当前系统的时间和日期,这个命令很简单,只需要在终端上输入date命令并回车即可。

date 

此时,Xshell界面会返回当前日期和时间

Wed Feb 20 11:26:30 CST 2019

接下来,我们再敲一个cal命令,这个命令用来显示当前系统的日历,默认情况下,该命令的结果将返回当前月的日历。和上面类似,我们在终端直接输入cal命令并回车就行了。

cal

此时,我们将在终端看到一个显示当前月的日历。

February 2019   
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

通过以上两个例子,我们初步感受了Linux命令行的使用。下面,我们学习一下查看磁盘驱动器可用空间以及Linux可用内存的命令。

查看磁盘驱动器可用空间的命令比较简单,直接输入df命令并回车即可。

df

这样,我们可以得到如下信息

Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/vda1       41151808 2001384  37053376   6% /
tmpfs             509988       0    509988   0% /dev/shm

然后,我们再学习查看Linux可用内存的命令,这个命令和前面一样简单,直接在终端输入free命令回车即可。

free

这样,我们得到如下结果

             total       used       free     shared    buffers     cached
Mem:       1019980     920564      99416        160     143624     681376
-/+ buffers/cache:      95564     924416
Swap:            0          0          0

当我们完成所有操作后,我们可以在终端输入exit命令断开本机与远程Linux的连接。

exit

认识Linux文件系统树

在上一节中,我们初步体验了在Xshell终端中输入命令操作Linux,在本节中,我们开始学习Linux文件系统树。和Windows相同,Linux也是以称之为分层目录结构的方式来组织文件的。这也就意味着文件是在树形结构的目录中组织的,在该树形结构目录中可能包含有文件和其他目录。文件系统的第一个目录称为根目录,它包含了文件和子目录,子目录包含了更多的文件和子目录,就这样一直重复下去,最终构成了Linux文件系统树。

Windows和类Unix系统文件系统树的区别

需要注意的是,虽然Windows和Linux组织文件的方式相同,但在Windows系统中,每个存储设备都有一个独立的文件系统树 ,而在Linux这些类Unix系统中,无论存在多少驱动器和存储设备,通常都只有一个文件系统树,类Unix系统会根据系统管理员的设置,将设备挂载到文件系统树的不同位置。

显示当前工作目录

和Windows一样,当我们处在某个目录中,我们可以看到该目录所包含的文件、去往上一级目录的路径,以及下一级的子目录。此时我们所处的目录称为当前工作目录。正如GPS导航系统可以显示我们所处的经纬度信息一样,我们也可以让Linux告诉我们当前工作目录的路径,使用pwd命令可以显示当前工作目录。

pwd

通过这个命令,我们可以知道当前工作目录的路径。既然可以知道当前工作目录,我们也就可以知道当前目录下的文件和子目录。当我们第一次登陆系统时,当前工作目录会被设置成主目录。每个用户都会有一个主目录,对于普通用户来说,主目录是唯一一个允许用户进行写操作的地方。

列出目录内容

在Linux中,我们可以使用ls命令列出当前目录的文件和子目录

ls

当然,ls命令还有其它用法,在后面的内容中将会更加详细地介绍。

更改当前工作目录

绝大多数情况下,我们都需要更改当前工作目录,此时,我们需要使用cd命令切换工作目录。一般情况下,我们输入cd命令后还需要指定具体的目标工作目录的路径,所谓路径指的是沿着分枝到达目标目录的路由。

cd target

和Windows类似,Linux的路径也分为绝对路径和相对路径

  • 绝对路径:绝对路径从根目录开始,其后跟着一个又一个文件树分枝,直到到达目标目录或文件。对于绝对路径来说,其显著特征是以前导斜杠/开头。

例如,在Linux系统中,有一个目录,大多数系统程序都安装到这个目录里,这个目录是/usr/bin,这也就意味着在根目录下有一个目录usr,在目录usr下存在bin目录,现在我们切换过去

cd /usr/bin

此时,我们使用pwd命令显示当前工作目录

pwd

可以看到,当前工作目录已经是/usr/bin,我们使用ls查看当前工作目录下的文件及子目录,可以看到数量是非常多的。

  • 相对路径:和绝对路径从根目录开始,到目标目录或文件结束不同,相对路径则是从工作目录开始的。我们可以使用一些特殊符号来表示文件系统树中的相对位置,这些符号是...。符号.表示工作目录,符号..表示工作目录的父目录。

若我们想更改当前工作目录\usr\bin\usr,即当前目录的父目录,可以有两种方式。

  • 绝对路径方式
cd /usr
  • 相对路径方式
cd ..

无论哪种方式,我们都可以切换到\usr目录。当然,我们也可以从\usr目录切换到\usr\bin目录。同样地,我们也有两种方式。

  • 绝对路径方式
cd /usr/bin
  • 相对路径方式
cd ./bin

在相对路径方式下,我们还可以省略./,因为其是隐含的。即

  • 隐含相对路径方式
cd bin

一般而言,若是没有指定目录,则默认为当前工作目录

cd命令快捷方式

cd命令提供了几个可以快速切换工作目录的方法

快捷方式 结果
cd 将工作目录切换到主目录
cd - 将工作目录切换到先前的工作目录
cd~username 将工作目录切换为username的主目录

文件名的一些说明

  1. 在Linux中,以.开头的文件是隐藏的,这仅仅说明ls命令不会列出该文件,除非使用ls -a命令,在创建用户账号时,主目录会放置一些隐藏文件,用来配置账号信息。此外,一些应用程序也会将它们的配置文件和设置文件以隐藏文件的形式放在主目录下。
  2. Linux文件名与命令都是区分字母大小写的。例如:File1和file1是不一样的。
  3. Linux没有扩展名的概念,我们可以按照自己的喜好随意给文件命名。文件的内容或用途由其它方式决定。虽然如此,一些应用程序仍然使用扩展名区分文件内容和用途。
  4. Linux支持长文件名,但在文件名中不要嵌入空格,以免给自己带来不必要的麻烦。

Linux命令选项和参数

在Linux中,大部分命令都遵循以下格式

commond -options arguments

即通常情况下,一个命令会带有一个或多个选项,带有不同选项的命令其功能也会有所不同,此外,命令后面还会跟有一个或多个参数,这些参数是命令作用的对象。大部分命令的选项是在单个字符前加上连字符-,但是很多命令,包括GNU里面的命令,也支持在单字前加上两个连字符--的长选项,而且很多命令也允许多个短选项串在一起使用。 下面,我们通过ls命令说明上述描述。

深入了解ls命令

前面说到,ls命令的作用是列出目录内容,鉴于 ls命令是用户最常用的命令之一,它能查看目录内容,确定各种重要文件和目录的属性,我们有必要详细了解一下ls丰富的用法。

  1. 若我们直接查看当前工作目录下的文件和子目录,我们可以直接使用不带参的ls命令,即

    ls
    

    这样,我们就可以获取当前工作目录的文件和子目录信息了

    bin  etc  games  include  java  lib  lib64  libexec  local  sbin  share  src  tmp
    
  2. 若我们想要查看指定目录的信息,我们可以直接指定目录

    ls  /usr
    

    当然我们也可以一次性指定多个目录,同时查看多个目录下的文件和子目录

    ls ~ /usr
    

    其中,~指的是当前账户的主目录,现在,我使用的是root账号,执行这条命令,可以得到如下结果

    /root:
    
    /usr:
    bin  etc  games  include  java  lib  lib64  libexec  local  sbin  share  src  tmp
    

    可以看到,在当前账户的主目录下,没有任何文件和子目录,而在\usr目录下则存在多个子目录。

  3. 若我们想要展示更多的信息并按照文件修改时间排序,我们可以使用选项l,t,选项l产生长格式输出,t选项表示以文件修改的时间顺序先后将结果输出

    ls -lt /usr
    

    这样,我们就按长格式输出/usr目录下按照文件修改的时间排序的文件和子目录信息。

    total 72
    dr-xr-xr-x.  2 root root  4096 Aug  8  2018 sbin
    drwxr-xr-x   3 root root  4096 Jul 25  2018 java
    dr-xr-xr-x. 28 root root 12288 Aug 24  2017 lib64
    dr-xr-xr-x.  2 root root 20480 Aug 24  2017 bin
    dr-xr-xr-x. 12 root root  4096 Aug 24  2017 lib
    drwxr-xr-x. 13 root root  4096 Aug 24  2017 local
    drwxr-xr-x. 65 root root  4096 Aug 24  2017 share
    drwxr-xr-x. 10 root root  4096 Aug 24  2017 libexec
    drwxr-xr-x. 35 root root  4096 Aug 24  2017 include
    drwxr-xr-x.  4 root root  4096 Aug 24  2017 src
    lrwxrwxrwx.  1 root root    10 Aug 24  2017 tmp -> ../var/tmp
    drwxr-xr-x.  2 root root  4096 Sep 23  2011 etc
    drwxr-xr-x.  2 root root  4096 Sep 23  2011 games
    

    若我们想按照相反顺序输出,则加上长选项--reverse即可,即

    ls -lt --reverse /usr
    

    可以预料,输出结果和原结果排序正好相反

    total 72
    drwxr-xr-x.  2 root root  4096 Sep 23  2011 games
    drwxr-xr-x.  2 root root  4096 Sep 23  2011 etc
    lrwxrwxrwx.  1 root root    10 Aug 24  2017 tmp -> ../var/tmp
    drwxr-xr-x.  4 root root  4096 Aug 24  2017 src
    drwxr-xr-x. 35 root root  4096 Aug 24  2017 include
    drwxr-xr-x. 10 root root  4096 Aug 24  2017 libexec
    drwxr-xr-x. 65 root root  4096 Aug 24  2017 share
    drwxr-xr-x. 13 root root  4096 Aug 24  2017 local
    dr-xr-xr-x. 12 root root  4096 Aug 24  2017 lib
    dr-xr-xr-x.  2 root root 20480 Aug 24  2017 bin
    dr-xr-xr-x. 28 root root 12288 Aug 24  2017 lib64
    drwxr-xr-x   3 root root  4096 Jul 25  2018 java
    dr-xr-xr-x.  2 root root  4096 Aug  8  2018 sbin
    

对于ls命令,Linux提供了相当多的选项,常用选项罗列如下

  1. ls命令常用选项及含义
选项 长选项 含义
-a --all 列出所有文件,包括以.开头的隐藏文件,
这些文件在不加该选项时是不显示的
-d --directory 通常情况下,ls命令会罗列指定目录下的文件和子目录,
若想要查看目录本身的信息,需要使用该选项。若与l
项相结合,可以罗列出目录本身的详细信息
-F --classify 该选项会在每个所列出的名字后面加上类型指示符,
若是一个目录,则会加上一个斜杠
-h --human-readable 若使用该选项,当信息以长格式列出时,Linux将以人类可读的方式
而不是字节数显示文件大小
-l 使用长格式显示结果
-r --reverse 以相反的顺序显示结果,通常情况下,ls命令按照字母升序
排列显示结果
-S 按文件大小对结果排序
-t 按修改时间排序
  1. 了解ls命令长格式信息含义

我们随意选取一条长格式的输出结果

dr-xr-xr-x. 12 root root  4096 Aug 24  2017 lib

我们将结果进行拆分,查看这些字段的含义

字段 含义
dr-xr-xr-x 这表示的是用户对文件的访问权限;
第一个字符表示文件的类型。
在不同的类型中,开头的-表示该文件是一个普通文件,d表示目录,l表示链接文件。
紧接着的三个字符表示文件所有者的访问权限,
再紧接着的三个字符表示文件所属组中成员的访问权限,
最后三个字符表示其他所有人的访问权限
12 文件硬链接数目
root 文件所有者的用户名称
root 文件所属用户组名称
4096 以字节数表示的文件大小
Aug 24 2017 上次修改文件的日期和时间,即最近改动文件时间
lib 文件名

使用file命令确定文件类型

先前讲过,Linux并不能通过后缀名确定文件类型,因此,我们需要使用其它命令来确定文件类型,Linux提供了file命令查看文件类型,其命令格式为:

file filename

我们查看一下目录\usr\include下的poll.h文件类型

file poll.h

可以看到,这是一个ASCII C文本文件,也就是C语言编写的源文件

poll.h: ASCII C program text

使用命令查看文本内容

在Linux中,很多文件都以文本文件的形式存储,不可避免地,我们需要经常查看这类格式的文件。因此,我们有必要学习如何查看文本文件。

  1. 使用less命令查看文本内容

在该系统中,Linux提供了各种各样的命令帮助我们查看文本内容,我们先来学习less命令,其命令格式为:

less filename

一旦运行该命令,less命令将允许我们前后滚动文件,这样我们就能查看内容了,现在我们查看一下/etc/passwd文件内容。

less /etc/passwd

若我们查看完成,可以按q退出程序。下面列出less命令常用的键盘命令。

命令 功能
Page Upb 后翻一页
Page DownSpace 前翻一页
向上箭头 向上一行
向下箭头 向下一行
G 跳到文本文件末尾
g 跳到文本文件开头
/charaters 向前查找指定的字符串
n 向前查找指定的字符串,该字符串是之前指定查找的
h 显示帮助屏幕
q 退出less

Linux重要的目录

在Linux中,存在一些比较重要的目录,这些目录存储了比较重要的程序或文件,我们需要对其有一定的了解。

目录 内容
/ 根目录
/bin 包含系统启动和运行必须的二进制文件
/sbin 该目录放置"系统"二进制文件,这些文件执行重要的系统任务
/boot 包含Linux内核,最初的RAM磁盘映像(系统启动时会用到),以及自动加载程序
/lib 包含核心系统程序使用的共享库文件
/dev 包含设备节点的特殊目录
/etc 包含所有系统层面的配置文件,同时也包含一系列shell脚本,系统启动时,这些脚本都会打开相应的系统服务
/home 通常情况下,每个用户都会在/home目录下有属于自己的一个目录,普通用户只能在自己的主目录中创建文件
/opt 主要用来安装其他可选软件,一般用来安装可能安装在系统内的商业软件
/usr 包含普通用户使用的所有程序和相关文件
/usr/sbin 系统管理程序
/var/log 该目录包含的日志文件极其重要,记录了各种系统活动
/tmp 供用户存放各类程序创建的临时文件,在系统重启后,会清空该目录
/var 可能改变的数据会存储在该目录中,如各种数据库、假脱机文件、用户邮件
/root root账户的主目录

操作目录和文件

在Windows里,我们通常使用图形界面提供的功能来对目录和文件进行操作,在Linux中,我们应当尝试使用命令操作目录和文件,因为在实际开发中,我们使用的服务器一般是没有图形界面的。

在学习如何使用命令操作目录和文件之前,我们先学习一下通配符。通配符是一些特殊字符,它允许用户根据字符模式选择文件名,通过通配符,使得为文件名构建复杂的筛选标准成为可能。

  1. 常用的通配符
通配符 匹配项
* 匹配任意多个字符,包括0个或1个
? 匹配任意一个字符,不包括0个
[characters] 匹配任意一个属于字符集的字符
[!characters] 匹配任意一个不属于字符集的字符
[[:class:]] 匹配任意一个属于指定字符类的字符
  1. 常用的字符类
字符类 匹配项
[:alnum:] 匹配任意一个字母或数字
[:alpha:] 匹配任意一个字母
[:digit:] 匹配任意一个数字
[:lower:] 匹配任意一个小写字母
[:upper:] 匹配任意一个大写字母
  1. 通配符和常用字符类使用示例
模式 匹配项
* 所有文件
g* 以g开头的任意文件
b*.txt 以b开头,中间有任意多个字符,以.txt结尾的文件
Data??? 以Data开头,后面跟任意三个字符的文件
[![:digit:]]* 不以数字开头的任意文件

mkdir-创建目录

现在,我们先学习第一个命令,创建目录的mkdir命令,格式如下:

mkdir directory...

...表示可以同时创建多个目录,directory代表具体的目录名称。可以看到,我们可以同时创建一个或多个目录。

  1. 创建单个目录的命令格式
mkdir directory1
  1. 创建多个目录的命令格式
mkdir directory1 directory2 directory3

创建多个目录时,目录之间以空格作为间隔。下面,我们学习复制文件和目录的cp命令。

cp-复制文件和目录

cp命令用来复制文件和目录,需要注意的是,cp命令有两种用法。

  1. 将单个文件或目录item1复制到文件或目录item2中,其命令格式如下:
cp item1 item2

该命令表示将单个文件或目录item1复制到文件或目录item2中。

  1. 若要将多个目录复制到同一文件夹则需要使用以下命令格式:
cp item... directory

当然,在实际使用过程中,cp命令并不会这么简单,Linux提供了多个选项供我们自定义复制。

选项 长选项 含义
-a --archive 复制文件和目录及其属性,包括所有权和权限。
通常来说,复制的文件具有用户所操作文件的默认属性
-i --interactive 在覆盖一个已存在的文件前,提示用户进行确认。
如果没有该选项,cp命令将执行直接覆盖操作
-r --recursive 递归复制目录及其内容,复制目录时需要这个选项
-u --update 当将文件从一个目录复制到另一个目录时,只会复制那些目标
文件中不存在的文件或目标文件相应文件的更新文件
-v --verbose 复制文件时,显示信息性消息

mv-移动和重命名文件

mv命令可以执行文件移动和文件重命名操作,具体取决于如何使用它。 无论如何使用,操作完成后,原来的文件将不再存在,mv命令的使用方式和cp命令相似,都有两种使用方法。

  1. 将文件或目录item1移动或重命名为item2
mv item1 item2
  1. 将一个或多个文件或目录移动到另一个目录下
mv item... directory

mv命令和cp命令很多选项是共享的。

选项 长选项 含义
-i --interactive 覆盖一个文件之前,提示用户确认,
如果没有指定该选项,默认会覆盖文件
-u --update 将文件从一个目录复制到另外一个目录,只移动目标目录
不存在的文件或目标目录里相应文件的更新文件
-v --verbose 移动文件时显示信息性消息

下面是mv命令的一些使用示例。

  1. 将文件移到另一个文件
mv file1 file2

将file1移到file2,如果file2存在,则将会被file1的内容覆盖。如果file2不存在,则会创建file2,不管怎么样,file1都将不会再存在。

  1. 将文件移到另外一个文件,并在操作前给与提示
mv -i file1 file2

从最终结果来看,其和第一种是没有区别的。不同的是,若file2已经存在,覆盖之前Linux会通知用户确认。

  1. 将多个文件移到某个目录下
mv file1 file2 dir1

这个命令可以同时将file1和file2移动到目录dir1下,需要注意的是,该目录必须已经存在。

  1. 将目录移到另一个目录
mv dir1 dir2

该命令意思是将目录dir1的内容移动到目录dir2下,若目录dir2不存在,Linux就会创建目录dir2,最终结果是目录dir1的内容被移动到目录dir2,原有目录dir1将被删除。

rm-删除文件或目录

在Linux中,我们使用rm命令移除(删除)文件和目录,其格式如下:

rm item...

其中,item是一个或多个文件或目录的名称,目录或文件之间使用空格分隔。

警告

Linux默认用户是明智的,并清楚自己在干什么,所以其并没有提供还原删除操作的命令。一旦使用rm命令,就意味着目录或文件被彻底删除了。因此,在进行该操作时,必须仔细检查。在使用rm命令搭配通配符删除文件或目录时,可以先使用ls命令测试通配符,确保不会出现误删除的情况。

和前面一样,rm命令的一些常用选项罗列如下:

选项 长选项 含义
-i --interactive 删除一个已经存在的文件之前,提示用户确认,
如果没有这个选项,rm命令会默认删除文件
-r --recursive 递归地删除目录,也就是说,如果删除的目录有子目录的话
,也要将其删除。如果要删除一个目录,必须指定该选项
-f --force 忽略不存在的文件并无需确认,该选项会覆盖--iteractive选项
-v --verbose 删除文件时显示信息性消息

ln-创建软硬链接

在Linux中,内核为每一个新创建的文件分配一个Inode(索引结点),每个文件都有一个惟一的inode号。文件属性保存在索引结点里,在访问文件时,索引结点被复制到内存中,从而实现文件的快速访问。

在Linux中,链接是一种在共享文件和访问它的用户的若干目录项之间建立联系的一种方法。我们可以使用ln命令创建链接, ln可以创建两种链接:硬链接和符号链接(也称为软链接)。

  • 硬链接硬链接是文件的别名。从技术上讲,他们共用一个inode(inode中包含了一个文件的所有必要的信息,说inode就是文件也是没有问题的)。 由于linux下的文件是通过索引节点(Inode)来识别文件,硬链接也可以认为是一个指向文件索引节点的指针,系统并不为它重新分配inode。

    每添加一个硬链接,文件的链接数就加1, 删除一个则链接数减1。

    对于硬连接来说,其有两大限制:

      1. 硬链接不能引用自身文件系统以外的文件,也就是说,链接不能引用与该链接不在同一磁盘分区的文件。
    
      2. 硬链接不能引用目录。
    

创建硬连接的ln命令格式如下:

ln filepath linkpath
  • 软链接: 软链接是一种特殊的文件类型,其中包含对另一个文件或目录以绝对或相对路径形式的引用,可以看做是对一个文件的间接指针,相当于windows下的快捷方式。

创建软链接的ln命令格式如下:

ln -s item linkpath

在这里,item既可以是文件也可以是目录,和创建硬链接的格式相比,创建软链接多了一个-s选项。

软链接与硬连接的区别:

1. 软链接没有任何文件系统的限制,任何用户可以创建指向文件或目录的软链接。甚至可以跨越不同机器、不同网络对文件进行链接。

2. 创建文件的软链接时,软链接会使用一个新的inode,所以软链接的inode号和文件的inode号不同(表明他们是两个不同的文件)

3. 删除软链接对原文件没有任何影响。

4. 软链接的inode里存放着指向文件的路径,删除源文件,软链接也就无法正常使用了,此时,这是一个坏链接。

Linux操作实践

现在,我们进行一些实际操作,为方便操作,我们将目录切换到当前账号的主目录,输入cd命令,切换到主目录,并在当前目录下创建playground目录。

mkdir playground 

然后,我们切换工作目录到目录playground,然后在该目录下创建两个新的目录dir1dir2。前面我们提到mkdir命令可以接受多个参数,允许我们同时创建多个目录。

mkdir dir1 dir2

接下来,我们使用cp命令复制/etc目录下的passwd文件到当前工作目录。

cp /etc/passwd .

其中,.代表的是当前工作目录。此时,我们查看一下当前工作目录包含的文件和子目录。

ls -l

可以看到,当前工作目录下的详细信息一目了然。

total 12
drwxr-xr-x 2 root root 4096 Feb 25 15:49 dir1
drwxr-xr-x 2 root root 4096 Feb 25 15:49 dir2
-rw-r--r-- 1 root root  964 Feb 25 15:54 passwd

其中,目录dir1dir2是我们创建的,而文件passwd则是我们复制产生的。让我们使用-i选项,重复操作复制命令。

cp -i /etc/passwd .

此时,我们将获得警告信息,根据提示,我们输入y,完成复制,覆盖当前文件。若输入其它字符,则会使cp命令保留原有文件,不进行复制操作。

然后,我们使用mv命令修改passwd文件名为fun

mv passwd fun

我们继续操作,将fun文件移动到目录dir1

mv fun dir1

再将其从目录dir1移动到目录dir2

mv dir1/fun dir2

接着,我们将文件重新移动到当前工作目录下

mv dir2/fun .

我们再操作一下,将数据文件fun移动到dir1目录下

mv fun dir1

完成之后,我们再将dir1目录移动到dir2目录下,因为dir2目录已经存在,mv将正常移动,否则,dir1将重命名为dir2

mv dir1 dir2

为了确认操作是否已经成功,我们使用ls命令查看目录dir2/dir1

ls -l dir2/dir1

查看结果,我们已经操作成功了。

total 4
-rw-r--r-- 1 root root 964 Feb 25 16:03 fun

紧接着,我们将文件恢复原状,将数据文件fun重新移动回当前工作目录,即playground目录。

先将dir1目录移动回playground目录。

mv dir2/dir1 .

再将dir1目录中的fun文件移动回playground目录。

 mv dir1/fun . 

最后,我们尝试创建一些硬链接和软链接,先来创建三个硬链接。

ln fun fun-hard
ln fun dir1/fun-hard
ln fun dir2/fun-hard

查看当前工作目录

total 16
drwxr-xr-x 2 root root 4096 Feb 25 17:12 dir1
drwxr-xr-x 2 root root 4096 Feb 25 17:12 dir2
-rw-r--r-- 4 root root  964 Feb 25 16:03 fun
-rw-r--r-- 4 root root  964 Feb 25 16:03 fun-hard

可以注意到,文件funfun-hard的第二个字段都是4,这表示的是文件fun存在的硬链接数目。由于文件的文件名是由链接创建的,因此一个文件至少有一个链接。实际上,文件funfun-hard是同一个文件。 对于一个文件来说,其包含两部分:包含数据内容的数据部分和包含文件名的名称部分。创建硬链接实际上是创建了文件额外的名称,不同链接指向的是同一数据。Linux系统分配了一系列的盘块给所谓的索引节点,该节点随后与文件名称部分建立联系。因此,每个硬链接都是指向包含文件内容的具体节点

我们可以通过在ls上增加-i选项查看文件的索引节点,若两文件索引节点相同,则表示两文件是同一文件。执行以下命令。

ls  -li

查看结果,观察第一个字段,可以确定,文件funfun-hard是同一个文件。

total 16
1048614 drwxr-xr-x 2 root root 4096 Feb 25 17:12 dir1
1048615 drwxr-xr-x 2 root root 4096 Feb 25 17:12 dir2
1048616 -rw-r--r-- 4 root root  964 Feb 25 16:03 fun
1048616 -rw-r--r-- 4 root root  964 Feb 25 16:03 fun-hard

接下来,我们来创建软链接。

ln -s fun fun-sym
ln -s ../fun dir1/fun-sym
ln -s ../fun dir2/fun-sym

第一个命令,相当直接,通过在ln命令添加-s选项我们创建了软链接,至于第二、第三个命令同样也是创建软链接。我们查看一下dir1目录的文件和子目录。

total 4
-rw-r--r-- 4 root root 964 Feb 25 16:03 fun-hard
lrwxrwxrwx 1 root root   6 Feb 25 17:35 fun-sym -> ../fun

通过文件信息第一个字段的首字符,可以判断fun-sym的列表是一个链接文件,并且其指向../fun。相对于fun-sym文件来说,fun文件是其上级目录playground下的文件,因此,这个写法是正确的。同时注意到,软链接文件的长度是6,代表的是../fun字符串中字符的数目,而不是它所指向的文件的长度。

提示

创建软链接时,可以使用绝对路径,也可以使用相对路径。因为相对路径允许包含软链接的目录被重命名或移动,而且不会破坏链接。因此更适宜使用相对路径。

最后,我们来清理playground目录,我们先删除硬链接fun-hard

rm fun-hard

查看playground目录下的文件和目录信息

total 12
drwxr-xr-x 2 root root 4096 Feb 25 17:35 dir1
drwxr-xr-x 2 root root 4096 Feb 25 17:36 dir2
-rw-r--r-- 3 root root  964 Feb 25 16:03 fun
lrwxrwxrwx 1 root root    3 Feb 25 17:33 fun-sym -> fun

比较上面的结果,文件fun的链接数由4变成了3,硬链接数减少了1。我们再删除文件fun,此时符号链接还存在,只是其指向的文件已经不存在了,链接被破坏。我们删除链接。

rm fun-sym

最后一步,我们切换到主目录,使用rm命令的-r选项删除playground目录以及包括子目录在内的所有内容。

rm -r playground

到这里为止,我们初步了解了操作文件和目录的相关命令。

获取命令信息

在上面的章节中,我们学习了多个命令。在本章节,我们将进一步了解命令,揭开命令神秘的面纱。

命令的含义

在Linux中,一条命令无外乎下面四种情况:

  • 可执行程序:可执行命令就像在\usr\bin目录里所看到的所有文件一样。在该程序类别中,程序可以编译成二进制文件,比如C 、C++语言编写的程序,也可以是shell、Perl、Python、Ruby等脚本语言编写的程序。
  • shell内置命令:bash支持许多在内部被称之为shell builtin的内置命令。例如:cd命令就是shell内置命令。
  • shell函数:shell函数是合并到环境变量中的小型shell脚本。
  • alias命令:我们可以在其它命令的基础之上定义自己的命令。

type-显示命令的类型

type命令是一个shell内置命令,可根据指定的命令名显示shell将要执行的命令类型,其格式如下:

type commond

这里的commond是想要查看的命令名。我们先来查看一下type命令的类型。

type type 

可以看到,终端返回如下信息。

type is a shell builtin

这表明type命令是一个shell内置命令。我们再查看一下ls命令。

type ls

此时,终端返回如下信息

ls is aliased to `ls --color=auto'

我们注意到,ls命令其实是带有--color=auto选项的ls命令的别名。

which-显示可执行程序的位置

有时候,系统中可能安装一个可执行程序的多个版本,这种情况在大型服务器中尤其常见。使用which命令可以确定一个给定可执行文件的准确位置。

我们查看一下ls命令可执行文件的准确位置。

which ls

执行命令,输出如下结果。

alias ls='ls --color=auto'
        /bin/ls

可以看到,使用ls命令实际执行的是bin目录下的ls程序。

TIP

which命令只适用于可执行程序,而不适合内置命令和命令别名(真正可执行程序的替代物),识图在shell内置命令(例如:cd命令)中使用which命令,要么没有响应,要么返回错误信息。

下面,我们来验证一下这个说法。

which cd

此时,终端返回错误信息。

/usr/bin/which: no cd in (/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/java/jdk1.8.0_181/bin:/bin:/bin:/bin:/usr/local/bin:/bin:/root/bin)

在了解命令的含义后,我们学习每一类命令的使用文档。

help-获取shell内置命令的帮助文档

bash为每一个shell内置命令提供了一个内置的帮助工具。其使用方式如下:

help commond

我们尝试一下

help cd 

此时,终端输出如下信息

	cd: cd [-L|-P] [dir]
	 Change the current directory to DIR.  The default DIR is the value of the
    HOME shell variable.
    
    The variable CDPATH defines the search path for the directory containing
    DIR.  Alternative directory names in CDPATH are separated by a colon (:).
    A null directory name is the same as the current directory.  If DIR begins
    with a slash (/), then CDPATH is not used.
    
    If the directory is not found, and the shell option `cdable_vars' is set,
    the word is assumed to be  a variable name.  If that variable has a value,
    its value is used for DIR.
    
    Options:
        -L      force symbolic links to be followed
        -P      use the physical directory structure without following symbolic
        links
    
    The default is to follow symbolic links, as if `-L' were specified.
    
    Exit Status:
    Returns 0 if the directory is changed; non-zero otherwise.

该命令语法描述说明,cd命令后可能跟一个-L-P参数,甚至可以跟参数dir

命令语法描述规则

命令语法描述中的方括号表示这是一个可选的选项,竖线符号代表的是两个互斥的选项。

help选项-显示可执行命令的使用信息

很多可执行命令都支持--help选项,--help选项描述了命令支持的语法和选项。我们查看一下mkdir命令的语法和支持的选项。

mkdir --help 

此时,终端返回如下信息。

Usage: mkdir [OPTION]... DIRECTORY...
Create the DIRECTORY(ies), if they do not already exist.

Mandatory arguments to long options are mandatory for short options too.
  -m, --mode=MODE   set file mode (as in chmod), not a=rwx - umask
  -p, --parents     no error if existing, make parent directories as needed
  -v, --verbose     print a message for each created directory
  -Z, --context=CTX  set the SELinux security context of each created
                      directory to CTX
      When COREUTILS_CHILD_DEFAULT_ACLS environment variable is set, -p/--parents
      option respects default umask and ACLs, as it does in Red Hat Enterprise Linux 7 by default
            --help     display this help and exit
      --version  output version information and exit

Report mkdir bugs to bug-coreutils@gnu.org
GNU coreutils home page: <http://www.gnu.org/software/coreutils/>
General help using GNU software: <http://www.gnu.org/gethelp/>
For complete documentation, run: info coreutils 'mkdir invocation'

一些程序不支持--help选项,使用该选项可能会返回一条错误信息。

man-显示程序的手册页

Linux提供了详细的称为mannual或man的手册供我们查询命令,我们可以通过man命令阅读它。man命令的格式如下所示:

man commond

这里的commond是需要查看的命令名称。

TIP

手册文档在格式上会有所不同,但是通常都包括标题、命令句法的摘要、命令用途的描述、命令选项列表以及每个命令选项的描述。但是,手册文档通常不包括实例,更多地是作为参考使用,而不是教程。

现在,我们尝试使用一下

man ls

执行命令,我们将得到命令名称,命令格式、命令选项及其选项描述等重要信息。

在大多数Linux系统中,man命令通过调用less命令来显示手册文档,所以,当显示手册文档时,可以使用熟悉的less命令。

man命令显示的手册文档不仅包括用户命令,也包括系统管理命令、程序接口、文件格式等。大致来看,其可以分为以下几个部分。我们可以通过指定数字编号在特定范围查询命令。

部分 内容
1 用户命令
2 内核系统调用的程序接口
3 C库函数程序接口
4 特殊文件,如设备节点和驱动程序
5 文件格式
6 游戏和娱乐
7 其他杂项
8 系统管理命令

若我们没有指明编号,通常会获得第一次匹配的实例。我们使用如下格式的man命令通过数字指定范围查找相关信息:

man section search_term

我们执行如下命令

man 5 passwd

该命令将会显示文件/ect/passwd的文件格式描述手册。

apropos-搜索合适的命令

有时候,我们希望通过关键字搜索手册信息,那么我们可以用apropos命令,其格式如下所示:

apropos floppy

执行命令,显示如下信息

fdformat             (8)  - Low-level formats a floppy disk
floppy               (8)  - format floppy disks

其中,第一个字段是手册页的名称,第二个字段显示的是该信息所属手册的部分信息。注意,带有-k选项的man命令和apropos在功能上是一致的

whatis-显示命令的简要描述

whatis命令可以帮助我们快速了解匹配具体关键字的手册页名字和一行描述。其格式如下:

whatis commond

现在,我们可以使用whatis命令查看ls命令的描述信息。

whatis ls

执行命令,我们得到以下信息

ls  (1)  - list directory contents

可以看到,输出简要指出了ls命令的作用是列出目录内容。若我们只想知道一个命令的作用,可以直接使用whatis命令即可。

info-显示程序的info条目

GNU项目提供了info页面来代替手册文档。info页面使用了超链接,其文件是一个树形结构,分为各个单独的节点,每个节点包含一个主题。info文件包含的超链接可以实现节点间的跳转。通过前置星号可以识别超链接,将光标放在超链接上并按Enter即可激活它。它的格式如下所示:

info commond

在上面的格式中,commond是可选的。当我们使用info打开info页面时,可以使用以下命令进行控制。

命令 功能
? 显示命令帮助
Page Up 返回上一页
Page Down 翻到下一页
n 显示下一个节点
p 显示上一个节点
u 显示目前显示节点的父节点
Enter 进入光标所指的超链接
q 退出

定义和删除别名

alias-查看与自定义命令别名

在前面的章节中,我们使用了多个命令来获取命令的信息。在本章节中,我们尝试使用alias命令自定义命令, 在学习自定义命令之前,我们学习一个命令行技巧:通过使用分号来分隔多条命令,使多条命令输入在一行中。其格式如下:

commond1;commond2;commond3...

我们尝试一下这个技巧

cd /usr;ls;cd -

执行命令,该命令成功执行并返回切换之前所在的工作目录。

现在,我们尝试将上述命令组合成一条命令,将其命名为test命令,为了保险起见,我们使用type命令测试一下test命令是否已经被使用了。

type test

执行命令

test is a shell builtin

可以看到,该条命令已经被占用了,因此,我们只能将组合命令定义为其它名字,比如foo

 alias foo='cd /usr;ls;cd -'

观察这个结构,我们得出了指定命令别名的一般格式

alias name ='string'

其中,alias是定义命令别名的关键字,name是别名的名称,后面紧接着一个等号(没有空格),等号后面是一个用单引号括起来的字符串,这个字符串代表了一个或多个命令的组合。

当然,若我们需要查看在环境中定义的所有别名,直接执行不带参数的alias命令即可。

alias cp='cp -i'
alias foo='cd /usr;ls;cd -'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'

unalias-删除命令别名

若我们在定义别名之后,想要删除定义的别名,可以使用unalias命令进行删除操作。其格式如下:

unalias commond
LastUpdated: 3/19/2019, 1:07:45 AM