7. Linux命令行¶
我们的LubanCat-RK系列板卡的桌面端有很多功能,我们可以根据图形化界面去完成大部分工作, 日常的基础应用都可以通过它的图形界面完成, 但界面做得再完善,还是有很多操作无法通过界面完成的,因为绝大部分程序本身根本就不提供界面, 或者界面只提供一小部分常用操作。但是几乎所有的程序都能通过命令行来调用运行, 并且通过命令行提供丰富的操作选项。尤其是做开发时,不要总想着有IDE,有当然好, 但我们要接受只能使用命令行的处境,实际上,用多了就习惯了。
Linus Torvalds(林纳斯)在其自传中提到,他在编写Linux操作系统内核的时候, 首要目标就是让Linux系统能兼容正常运行Unix下的Shell程序。因为Shell是命令行解释器, 他的Linux系统若能兼容Unix的Shell,那么大部分类Unix的程序也很容易做到兼容了。
在早期的Unix系统与用户就是通过Shell进行交互的,如下图所示,Shell对外接受用户输入的命令, 对内通过“系统调用”传递给内核,内核执行操作后把输出通过Shell呈现给用户,也就是说, Shell就是一个中间人。而Shell的英文原意是“壳”的意思,也是为了把它与内核区分开来。
在平时的交流中,有时我们会说打开Shell、终端(Terminal)或控制台(Console), 严格来说它们实际上不是同一种的东西,但只要明白,当我们说打开Shell、终端或控制台的时候, 通常就是为了使用命令行控制系统。它们的严格区分如下,了解下即可:
Shell:指命令行解释器,常见的解释器有bash,sh,在Ubuntu系统默认用的是bash解释器, 所以有时说bash也是指命令行。
终端(Terminal):通常指用来运行Shell的程序,视场景的不同有不一样的名称, 如Ubuntu系统自带的叫本地终端,嵌入式开发板常常提供串口进行输入输出的串口终端, 通过网络访问的ssh终端。
控制台(Console):特指某些终端,通常是指它的物理形态,如带键盘和显示器的物理设备。
7.1. 打开终端¶
板卡终端的打开方式有三种,大家可以选择自己最为方便的方式登录终端
串口连接(适合小白以及板卡在身边的)
ssh连接(适合远程用户)
桌面打开终端(适合桌面端用户)
7.1.1. 串口连接¶
串口连接的方法
安装能够进行串口通讯的工具,这里推荐Mobaxterm
使用串口线连接板卡
配置Mobaxterm,使得Mobaxterm可与板卡通信
具体方法可参考快速使用手册 《启动系统与系统登录》 章节。
7.1.2. ssh连接¶
ssh连接的方法
板卡处于开机状态
板卡与通信的电脑连接在同一个局域网
打开可以ssh通讯的软件,这里推荐Mobaxterm
配置Mobaxterm,使得Mobaxterm可与板卡通信
具体方法可参考快速使用手册 《SSH终端登录》 章节。
7.1.3. 桌面打开终端¶
可以在软件管理里打开Terminal
可以在键盘里按下“Ctrl + Alt + T”打开桌面终端
7.2. 命令提示符¶
当我们打开终端后,我们可以看到终端本身显示了一行字符,而且按回车后会重复出现:
root@lubancat:~#
实际上这行提示符分成以下几个部分:
root :“@”符号的左侧,它表示的是当前登录用户,上图使用的是 root用户登录。
@ :分隔符号,可理解为at,表示root用户at主机lubancat上。
lubancat :当前系统的主机名。
“:” :分隔符号。
“~” :冒号后表示用户当前所在的目录,此处的波浪线表示当前用户的家目录, root用户的家目录为
/root
,普通用户的目录在/home/(用户名)
“#”:命令提示符,Linux 用这个符号标识登录的用户权限等级。如果是超级用户, 提示符就是“#”,如果是普通用户,提示符就是“$”。
7.3. 命令行体验¶
废话少说,在终端中输入如下命令,注意如果使用的是中文输入法,要记得把它切换成英文模式。 另外,在以下命令中的波浪号“~”也是英文符号,还要注意终端中所有的内容都是区分大小写的:
1 2 3 4 5 6 7 8 9 10 11 | # 在后面的说明中,#号表示注释,它后面的内容不要输入到终端中
# 从下面开始是你要在终端中输入的命令(不包括#号后的内容):
cd /home # 切换到/home目录
pwd # 显示当前目录
cd ~ # 切换至家目录,~代表家目录,不同用户家目录不一样
pwd # 显示当前目录
touch hello # 创建叫hello的文件
touch abc.c # 创建叫abc.c的文件
ls # l是字母L的小写,不要把l输入成数字1或字母i的大写
ls -l # 同上,两个l都是字母L的小写
|
每行命令输入后按回车,Shell就会对输入的命令进行解释,执行后输出,运行结果如下所示。
以上各行命令的意义如下:
cd /home :执行 “cd”命令,并以“/home”作为参数,表示切换至/home目录,命令执行后,我们 可以看到命令提示符已从 root@lubancat:~# 变为 root@lubancat:/home# 即其中的波浪符号“~”已变成“/home”。
pwd:执行“pwd”命令,表示输出当前所在目录,可看到它的输出为“/home”,与命令提示符中的是一致的。
cd ~ :再次执行 “cd”命令,并以“~”作为参数,表示切换至“~”目录,命令执行后, 我们可以看到命令提示符中的路径已由“/home”变回“~”。
pwd:再次执行“pwd”命令,输出当前所在目录,可看到它的输出为/root, 是当前用户的家目录,与命令提示符中的“~”表示的意思是一致的。
touch + 文件名 创建文件
ls :执行“ls”命令,(注意这是字母L的小写, 不是数字1也不是字母i的大写),该命令表示列出当前目录下的内容
ls -l :执行“ls”命令,并带“ -l ”(同样地,注意这是L的小写,不是数字1也不是字母i的大写)选项, 该选项表示以列表的形式列出目录下的详细内容,可看到它比普通的ls命令多了很多内容,具体我们后面再分析。
7.4. 命令的格式与帮助¶
7.4.1. 命令的格式¶
通过以上的一些命令示例,我们大致可以归纳一下命令的格式:
1 | command [-options] [argument]
|
命令的组成一般分三部分,每部分之间使用空格隔开,说明如下:
command:命令名,如前面的cd命令,pwd命令,ls命令。
-options:命令的选项,使用
-
开头的或--
开头,如前面示例ls -l
中的-l
选项, 命令会根据具体的选项执行不同的操作。使用 - 时一般是选项的简写, 一些选项可以同时使用,ls -la
等价于ls -l -a
,即同时使用“l”和“a”选项。 而--
一般后面带选项的全名,如ls -a
等价于ls --all
。argument:命令参数,如前面cd命令中以“/home”可“~”参数作为路径名。
在命令格式中,使用“[ ]”括起来的内容表示它不是要求必需的,例如前面使用时cd命令时没有带选项, 使用pwd命令不带选项及参数。
7.4.2. 命令的帮助¶
Linux下系统本身就支持数不清的命令,不同的命令又带不同的选项, 输入的参数往往又有不同的意义,除了丢下一句“用多了就会记住”这不负责任的说法外, 使用命令其实还是有一些门道的。
每个命令都会带有一个 -h
或者 --help
的参数,可以用来打印一些帮助说明。
比如,如果现在不知道ls的选项a有什么用法,那么就可以执行下面的命令:
1 | ls --help
|
从上图中圈出来的地方,可以知道参数a可以只列出隐藏的内容。现在执行命令:
1 | ls -a
|
从上图中可看到该执行后比直接用“ls”命令多列出了很多以“.”开头的内容, 在Linux下以“.”开头命名的文件或目录默认为隐藏文件,而ls的“-a”选项可以把它们显示出来。
补充说明一下,帮助信息中的 -a
后面还有 --all
参数,这两个参数是等价的,只不过 --all
会比 -a
好记。
7.4.3. 自动补全¶
有些时候我们一时想不起命令的全称是什么,这时候就可以用到命令行的自动补全功能。就是键盘上神奇的“Tab”键。
假如我们知道有个命令是以“whic”开头,但想不起全称, 那么我们可以在终端输入“whic”然后按一下“Tab”键(在键盘上字母Q的左边),它会自动补全命令为“which”。
如果我们只记得命令是以“wh”开头的话,按一下“Tab”键发现它没反应, 这时我们尝试按两下“Tab”键,如下图所示。
终端输出了好多以“wh”开头的命令,如which,who,whoami等。
所以按一下“Tab”键时如果只有一个匹配的内容时它会自动补全,按两下“Tab”键则会列出所有的匹配项。
“Tab”键除了用来补全命令名,还可以自动补全路径,如我们使用cd命令输入“/home”参数时, 先输入“/ho”然后按下“Tab”键,它会把“/ho”自动补全为“/home”路径名,如下图所示。 这在使用命令行时是频繁使用的技巧,能减少我们的输入,而且不容易出错。
同时还能补全文件名,当你要操作文件时可以不用输入全名,输入部分名字然后按Tab键自动补全
1 2 3 4 5 | #创建一个新文件
touch embedfire
#输入cat em
#按下Tab键,会自动补全文件名
|
7.4.4. 命令的退出与取消¶
在应用中我们有时会想要中止命令的执行,或者命令输入到一半的时候觉得输错了不想继续, 这时我们都可以通过“Ctrl”+“c”的组合键来结束。
如在终端输入:
1 2 | # 在后面的说明中,#号表示注释,它后面的内容不要输入到终端中
ping 127.0.0.1 #尝试ping测试自己的网络地址127.0.0.1
|
以上ping命令会持续输出,可以通过按下“Ctrl”+“c”组合键来结束
又例如,我们在终端输入了以下内容,然后又不想让它执行,使用删除键一个个字符删除很麻烦, 也可以通过“Ctrl”+“c”的组合键来取消:
1 | ls adfadfadsfadsfa
|
输入以上命令后不想运行以上命令,按下“Ctrl”+“c”组合键来结束
7.4.5. 命令究竟是什么¶
命令究竟是什么,当我们敲下命令“ls”后,Shell究竟做了什么事情。 在 《Linux文件目录/bin目录》 小节中提到, /bin目录下包含了很多命令,如下图所示,可看到ls、lsblk、lsmod、mkdir等命令程序。
在终端中,我们使用which命令可以查看指定命令的路径,如查看ls、pwd、cd命令:
1 2 3 4 5 6 | # 在后面的说明中,#号表示注释,它后面的内容不要输入到终端中
which ls # 查看使用的是哪个ls命令
which pwd # 查看使用的是哪个pwd命令
which sudo # 查看使用的是哪个sudo命令
which cd # 查看使用的是哪个cd命令
|
从上图中可了解到ls命令实际是/bin/ls程序,pwd命令实际是/bin/pwd程序,而which cd命令没有输出, 因为cd命令是Shell自己内部的程序。
我们在Shell中输入ls命令与输入/bin/ls的作用是一样的,当我们输入Shell时, 它会到预定的目录下查找有没有该程序,如果有就使用命令选项及参数调用该程序执行, 并把程序的输出再呈现出来。而这个预定的目录我们可以通过如下命令来查看:
1 | echo $PATH # echo是输出命令,而"$PATH"是一个变量,表示输出变量内容
|
“$PATH”是终端使用的路径环境变量,它使用“: ”进行分隔,表示Shell将会在这些路径下寻找命令程序, 在其中我们可以看到/bin路径。也就是说,“$PATH” 路径环境变量让我们输入命令时省去了输入完整路径的麻烦, 而命令的本质大都是在文件系统中的一些应用程序。
7.5. 常用命令¶
下面我们列出一些常用命令的讲解,请都亲自在终端里尝试运行一下。
7.5.2. cd命令¶
cd命令是change dir的简写,它可以把终端当前所在的路径切换至目标路径。该命令的格式如下:
1 | cd [目录名]
|
格式说明中 “目录名”就是要切换至的路径,若目录名称省略,则切换至当前用户的 home 目录 。
除某些有特殊要求的应用程序,Linux自带的所有命令在终端运行时,“目录名”都可以使用绝对路径或相对路径。
例如当前终端所在的路径为“/home/embedfire”,那么以下两个命令是等价的:
1 2 3 4 5 | # 在后面的说明中,#号表示注释,它后面的内容不要输入到终端中
# 假如当前目录为/home/embedfire
cd test
cd /home/embedfire/test
|
它们都表示切换至“/home/embedfire/test”目录,这其中的“test”是相对路径, 而“/home/embedfire/test”是绝对路径。
特别地,我们需要知道目录的如下表示:
“~”:波浪号,表示为当前用户的 home 目录
“.”:一个英文句号,表示当前目录
“..” :两个英文句号,表示当前目录的上一级目录
“/” :斜杠符号,表示为根目录
“-” :减号,不是目录,但作为cd命令的参数时可以返回上一次cd切换前的目录。
我们尝试执行以下命令,进行目录切换实验,注意其中的embedfire是当前的用户名, 具体请根据自己的用户名进行修改。
1 2 3 4 5 6 7 | #在后面的说明中,#号表示注释,它后面的内容不要输入到终端中
cd / # 切换至根目录
ls # 列出当前目录的内容(根目录)
cd - # 返回至上一次的目录(家目录)
cd .. # 切换至上一级目录
ls # 列出当前目录的内容(home目录)
cd /home/cat/ # 切换至cat家目录
|
注意以上命令中,命令名cd与路径名之间是有空格的,实际上包括以后使用的所有命令中, 命令名,命令选项以及命令参数之间都是要使用空格分隔开的。
上图中执行切换至根目录的命令后,命令行提示符中的目录就变成“/”,且可以直接用ls列出了当前目录下的所有文件, 最后再通过“-”参数切换回了用户的家目录。
7.5.3. mkdir命令¶
mkdir命令是make directory的简写,它可以在文件系统中创建一个新的目录。其命令格式如下:
1 | mkdir [-p] 目录名
|
命令格式中的“目录名”就是要创建的目录路径,“-p”选项可以不输入,若使用了“-p”选项, 当创建的目录名包含的上级目录不存在时,它会自动创建所有不存在的目录。
我们尝试执行以下命令:
1 2 3 4 5 6 7 8 | #在后面的说明中,#号表示注释,它后面的内容不要输入到终端中
ls # 列出当前目录的内容,此时没有testdir目录
mkdir testdir # 创建目录testdir
ls # 列出当前目录的内容,发现多了testdir
mkdir other/test # 创建目录other/test,因为other不存在,报错
mkdir -p other/test # 使用 -p 选项创建目录other/test
ls # 列出当前目录的内容,发现other目录
ls other # 列出other目录的内容,发现test目录
|
7.5.4. touch命令¶
touch命令可以创建不存在的文件,或者touch通过参数修改目录或文件的日期时间, 就是触摸一下,更新它的时间。
它的命令格式如下:
1 | touch 文件名
|
尝试执行如下命令:
1 2 3 | #在后面的说明中,#号表示注释,它后面的内容不要输入到终端中
touch helloworld # 在当前目录下创建一个名为helloworld的文件
ls # 显示当前目录下的内容
|
使用touch命令,新建一个helloworld的文件,然后使用ls命令来查看文件是否被创建,执行结果如下图所示。
7.5.5. ls命令¶
ls命令是list的简写,在前面我们已经频繁使用,它是Linux下最常用的指令, 功能为显示指定目录下的内容(文件及子目录),还可以查看文件大小,修改日期等等信息。
ls命令格式如下:
1 | ls [选项] [目录]
|
当“目录”参数省略时,它会列出当前目录的内容。
除了基本的显示,ls命令还有以下常用选项:
-a: 显示所有文件及目录 (ls内定将文件名或目录名称开头为“.”的视为隐藏档,不会列出)
-l :注意这是字母L的小写,除文件名称外,将文件型态、权限、拥有者、文件大小等信息详细列出
-t :将文件依建立时间之先后次序列出
-A: 同 -a ,但不列出 “.”(当前目录) 及 “..”(父目录)
-R :若目录下有文件,则该目录下的文件也会列出,即递归显示
尝试执行如下命令:
1 2 3 4 | #在后面的说明中,#号表示注释,它后面的内容不要输入到终端中
ls # 列出当前目录的内容
ls -a # 显示当前目录下的所有内容
ls -A # 显示当前目录下除“.” 及 “..”外的所有内容
|
从上图可以看到,缺省参数下的ls命令只能列出非隐藏的文件或者文件夹, 而ls -a或者ls -A这两条命令会把所有文件,包括隐藏文件在内的都罗列出来。 在linux中,以点“.”开头命名的文件在系统中被视为隐藏文件。不过ls -a 和 ls -A这两个命令的执行结果, 区别在于是否列出“.”和“..”。
除此之外,在终端上罗列出来的文件是白色的字体,而文件夹是淡蓝色的字体,以此来区分文件和文件夹。
特别地,有时我们需要查看文件的详细信息,可以使用“-l”参数,我们尝试执行以下命令:
1 | ls -l
|
可以看到如下图 参数l的执行结果, 得到当前目录下所有文件所占用的空间总和以及一个7个字段的列表。
7.5.6. cat命令¶
cat命令是concatenate的简写,译为串联,即它可以把两个内容串联起来, 我们通常使用它在终端下输出文件的内容进行查看。
命令格式为:
1 | cat 文件名
|
我们可以把/etc/hostname 的内容输出到终端:
1 | cat /etc/hostname
|
7.5.7. echo命令¶
echo命令的功能是在终端上打印一段文字,也可以把终端的变量内容打印出来。
其命令格式如下:
1 2 3 | echo "字符串"
echo 字符串
echo $变量名
|
使用echo命令时,带双引号和不带双引号的效果是一样的, 使用引号时,要注意用英文符号。
我们尝试执行如下命令:
1 2 3 4 5 | #在后面的说明中,#号表示注释,它后面的内容不要输入到终端中
echo "test" # 打印字符串test
echo test # 打印字符串test
echo $PATH # 打印环境变量PATH
echo "$PATH" # 打印环境变量PATH
|
7.5.8. 输出重定向到文件¶
在上面看到命令执行后都是输入到终端显示,有时我们希望把命令执行的结果保存到文件进行分析,这时我们可以使用 输出重定向到文件的控制符“>”或“>>”,其中“>”会直接用输出覆盖原文件, 而“>>”则把输出追加到原文件的末尾。
使用格式如下:
1 2 | 命令 > 文件名
命令 >> 文件名
|
重定向时文件不存在会自动创建。
尝试执行如下命令:
1 2 3 4 5 6 7 8 9 | #在后面的说明中,#号表示注释,它后面的内容不要输入到终端中
echo test > file.txt # 把echo test的输出重定向至file.txt文件
cat file.txt # 查看file.txt文件的内容
echo abc > file.txt # 把echo abc 的输出重定向至file.txt文件
cat file.txt # 查看file.txt文件的内容
echo 123456 >> file.txt # 把echo 123456的输出重定向追加至file.txt文件
cat file.txt # 查看file.txt文件的内容
ls > file.txt # 把ls命令的输出重定向至file.txt文件
cat file.txt # 查看file.txt文件的内容
|
上图演示了echo命令和ls命令的输出重定向至文件file.txt中,重定向执行命令后输出不会显示在终端上。
7.5.9. rm命令¶
rm命令是remove的简写,它的功能是删除一个或多个文件或目录。
其命令格式如下:
1 | rm [选项] 一个或多个文件/文件夹名
|
使用rm命令删除内容时,文件是会被直接永久删除的,它并不会放到回收站中再确认。 所以在使用rm命令前,一定要考虑清楚。 特别是如果你使用的是系统管理员账户或者通过后面介绍的sudo命令获取了系统权限, 那么只需要一句命令就可以实现删库跑路,酿成大祸!
它支持的选项如下:
-i:删除文件或文件夹前,终端会逐一询问确认
-r:将目录及其包含的子目录或文件全部删除
-f:忽略不存在的文件,无需逐一确认
虽然rm命令使用不当很容易造成严重后果,但不能因噎废食,而且趁我们现在的系统是刚安装的, 没有什么重要内容,在家目录进行操作通常也不会影响到系统的正常运行, 所以大可以放心去运行以下命令进行实验:
#先创建一些试验文件给后面删除
1 2 3 | #在后面的说明中,#号表示注释,它后面的内容不要输入到终端中
mkdir -p ABC/test #创建ABC/test目录
ls #列出内容
|
1 2 | touch a.txt b.txt c.txt d.txt #创建 几个测试文件
ls #列出内容
|
先结合前面学习的mkdir和touch命令,在当前目录创建一个ABC目录, 里面包含了一个子目录test还有a.txt,b.txt, c.txt,d.txt,执行结果如下图所示。
7.5.9.1. 删除文件测试¶
1 2 3 | #在后面的说明中,#号表示注释,它后面的内容不要输入到终端中
rm a.txt b.txt #直接删除a.txt b.txt
rm -i c.txt d.txt #询问式删除c.txt d.txt
|
执行上面两条命令的其中一条都可以完成删除任务。当带有参数i时, 则会有询问是否删除文件,如果是,输入y;反之,则输入n。如下图所示, 直接删除了a.txt,b.txt。使用询问式删除时,删除了c.txt,保留了d.txt文件。
7.5.9.2. 删除目录¶
我们可以使用rm命令配合“-r”选项来完成:
1 | rm -r ABC/
|
执行以上命令之后,就会把目录ABC以及子目录test,即ABC下的内容统统都删除掉。 因此,为了防止误删文件,使用rm命令时尽可能加上参数i。
7.5.9.3. 选项-f的作用¶
执行以下两条命令,比较执行结果的差异:
1 2 | rm a.txt
rm -f a.txt
|
当使用第一条命令时,会提示“删除失败,找不到该文件”,但是当我们使用参数-f时, 就忽略该提示。这里只是简单介绍一下该参数,日常使用中还是尽量不要使用该参数,以免造成无法挽回的损失。
7.5.11. sudo命令¶
sudo命令是switch user do的简写,意思是切换用户去做某件事情。
在Linux中,有一个名为root的超级用户。它可以做任何事情,权力越大,责任越大。 因此在日常工作中,若一时没注意输入了错误的命令,可能会导致系统崩溃, 但是在很多情况下我们又需要用到root的权限, 如安装某个软件,若使用普通的用户会提示“权限不够”。 这时候我们可以在需要root权限的命令前添加sudo命令,从而使当前用户获得root权限, 并执行其后的命令。
sudo命令格式如下:
1 | sudo 命令
|
使用sudo命令时会提示输入你当前的用户密码,而不是root用户的密码。 请注意,你输入的密码不会显示在终端上, 而且终端也不会随着你的输入而显示星号(*)!自信地在键盘上敲入密码,然后按回车即可。
下面我们尝试使用sudo命令在需要root权限的目录进行操作:
1 2 3 4 | 如果你是root用户登录可以切换成cat用户再尝试
su cat # cat为普通用户
cd # 切换为家目录
|
1 2 3 4 5 6 7 8 9 10 | #在后面的说明中,#号表示注释,它后面的内容不要输入到终端中
cd /home # 切换至/home目录
touch test.txt # 尝试在当前目录创建test.txt文件
sudo touch test.txt # 使用sudo增加权限,创建test.txt文件
# 输入密码时终端也不会随着输入而显示星号(*),输入完回车即可!
# 输入密码时终端也不会随着输入而显示星号(*),输入完回车即可!
# 输入密码时终端也不会随着输入而显示星号(*),输入完回车即可!
rm test.txt # 尝试删除test.txt文件
sudo rm test.txt # 使用sudo增加权限,删除test.txt文件
|
如上图所示,当前用户是cat用户,切换至/home目录后,它没有往该目录写入文件的权限, 所以直接用touch命令尝试创建文件时提示权限不够。当我们在touch命令前增加sudo命令, 并输入正确的用户密码后获得了权限,所以文件被成功创建。类似地,当我们直接尝试用rm命令删除文件时, 也会提示权限不足,再增加sudo后即可删除。而且可以发现这时不需要再次输入密码了, 也就是说认证成功后能维持一段时间,但是使用命令时,还是要添加sudo操作。
有时我们在执行命令时忘记添加sudo前缀,执行失败提示时才想起要加sudo, 这时可以使用“sudo !!”的方式使用sudo权限重新执行上一条命令。
1 2 3 4 | #在后面的说明中,#号表示注释,它后面的内容不要输入到终端中
cd /home # 切换至/home目录
touch test.txt # 提示没有权限
sudo !! # sudo加两个感叹号,重新使用sudo权限执行上一条命令
|
执行过程如下图: