树莓派开始,玩转Linux
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

第5章 贝壳里的树莓派

树莓派的图形化桌面算不上精美,如果真想用图形化界面进行办公,那么你恐怕会失望。用树莓派的浏览器打开网站上的视频,很可能会遭遇页面加载缓慢和视频播放卡顿等情况。如果想打开多个窗口工作,那么桌面很容易崩溃。毕竟,树莓派的性能不高,而计算机图形的呈现相当消耗资源。幸好,Linux提供了一种更易与树莓派互动的方式——Shell。

5.1 初试Shell

打开终端,桌面上就会出现一个黑色背景的窗口,窗口上显示着:

    pi@raspberrypi:~ $

这里的pi是用户名,raspberrypi是计算机的名字,$是命令提示符。如果敲击键盘,那么字符会显示在$提示符的后面,形成一串文本形式的命令。在英文中,Shell是贝壳之类的外壳。在Linux中,所谓的Shell,就是运行在终端中的文本互动程序。Shell分析文本输入,然后把文本转换成相应的计算机动作。用户透过Shell这个“壳”,来触及电脑。贝壳里的Shell,如图5-1所示。

图5-1 贝壳里的Shell

在后面的内容中,将用$来表示Linux系统Shell的命令提示符,例如输入date命令:

    $date

date用于日期时间的相关功能。按Enter键后,Shell会显示系统的当前时间。

Shell看起来简陋,但实际上比图形化桌面强大得多。Linux操作系统继承自UNIX操作系统。无论是Linux操作系统,还是UNIX操作系统,最初都只提供了Shell这一种用户操作界面。如果你习惯了这种文本操作方式,会渐渐体会到它的好处。

5.2 用命令了解树莓派

为了展示Shell的功能,首先介绍一些命令,用于查询系统信息,例如CPU的型号、内存的大小、IP地址等。这些命令可以让你更加了解树莓派的硬件,另一方面,你也可以借此机会体验一下Shell。

1.Linux通用查询命令

Linux系统提供了各种各样的命令。在Shell中输入这些命令可以实现许多功能。首先用lscpu命令来查询CPU的信息:

    $lscpu

终端窗口中就会打印出CPU的信息:

    Architecture:        armv7l
    Byte Order:          Little Endian
    CPU(s):             4
    On-line CPU(s) list:  0-3
    Thread(s) per core:   1
    Core(s) per socket:   4
    Socket(s):           1
    Model name:          ARMv7 Processor rev 4 (v7l)
    CPU max MHz:         1200.0000
    CPU min MHz:         600.0000

可以看到,这个树莓派用的是4核的ARM处理器,最高频率可以达到1200MHz。

然后,可以用free命令来了解内存的使用状况:

    $free -h

在使用上面的命令时,增加了-h的选项(option)。通过给命令增加选项,可以改变命令的行为方式。这里的字母h是human readable的意思。如果不使用-h选项,那么free命令会以字节为单位显示结果。有了-h选项,free可以将结果转换成更适合显示的单位。

Shell打印的结果如下:

              total      used      free    shared   buffers    cached
    Mem:        862M      739M      122M       14M       44M      397M
    -/+ buffers/cache:      298M      563M
    Swap:        99M        0B       99M

可以看到,内存总量是862MB,其他列中还显示了已用和可用的内存空间。通过增加选项,Linux命令的功能变得更加丰富。

再看SD卡的存储情况,用命令fdisk:

    $sudo fdisk -l

命令fdisk用于显示磁盘信息。选项-l表示列出所有磁盘。可以看到命令前面增加了sudo。某些命令的运行需要特殊权限,而sudo提供了以系统管理员的身份来执行后面的命令,即fdisk -l。结果的最后两行如下:

    Device       Boot  Start     End  Sectors  Size Id Type
    /dev/mmcblk0p1       8192  131071  122880  60M  c W95 FAT32 (LBA)
    /dev/mmcblk0p2     1310723031859130187520 14.4G 83 Linux

整个SD卡被分成了两个分区,其中的一个分区有60MB,专门用于树莓派的开机启动;另一个分区用于储存其他的所有数据。

使用lsusb,可以找到所有的USB外设:

    $lsusb

Shell将打印:

    Bus 001 Device 005: ID 0e8f:2517 GreenAsia Inc.
    Bus 001 Device 006: ID 045e:0750 Microsoft Corp. Wired Keyboard 600
    Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast
Ethernet Adapter
    Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

使用uname命令,可以打印出操作系统的信息:

    $uname -a

选项-a表示显示所有的相关信息。Shell将打印:

    Linux raspberrypi 4.1.19-v7+ #858 SMP Tue Mar 15 15:56:00 GMT 2016 armv7l
GNU/Linux

这里的系统使用的内核是Linux 4.1.19版本,而内核的发布时间是2016年3月15日。

最后,用ifconfig命令来查看网络接口:

    $ifconfig

命令运行结果如下:

    eth0     Link encap:Ethernet  HWaddr b8:27:eb:d8:ed:f4
            inet6 addr: fe80::9b8b:c0de:d083:6ddd/64 Scope:Link
            UP BROADCAST MULTICAST  MTU:1500  Metric:1
            RX packets:0 errors:0 dropped:0 overruns:0 frame:0
            TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
            collisions:0 txqueuelen:1000
            RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

    lo       Link encap:Local Loopback
            inet addr:127.0.0.1  Mask:255.0.0.0
            inet6 addr: ::1/128 Scope:Host
            UP LOOPBACK RUNNING  MTU:65536  Metric:1
            RX packets:243 errors:0 dropped:0 overruns:0 frame:0
            TX packets:243 errors:0 dropped:0 overruns:0 carrier:0
            collisions:0 txqueuelen:0
            RX bytes:19020 (18.5 KiB)  TX bytes:19020 (18.5 KiB)

    wlan0    Link encap:Ethernet  HWaddr b8:27:eb:8d:b8:a1
            inet addr:192.168.0.108  Bcast:192.168.0.255  Mask:255.255.255.0
            inet6 addr: fe80::ba27:ebff:fe8d:b8a1/64 Scope:Link
            UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
            RX packets:45926 errors:0 dropped:4268 overruns:0 frame:0
            TX packets:10469 errors:0 dropped:0 overruns:0 carrier:0
            collisions:0 txqueuelen:1000
            RX bytes:26867855 (25.6 MiB)  TX bytes:1360267 (1.2 MiB)

其中eth0代表了以太网接口,wlan0代表了Wi-Fi接口,而lo是虚拟出来的本地接口,用来表示本机。在连接上网的接口中,我们可以看到该接口的IP地址等信息。例如wlan0的IP地址是192.168.0.108。因为没有插网线,所以eth0并没有IP地址。

2.树莓派专用查询命令

除通用的Linux命令外,树莓派还提供了vcgencmd命令,用于和树莓派硬件直接互动。比如在Shell中执行:

    $vcgencmd measure_temp

在上面的命令中,第二段的measure_temp是命令的参数。参数是选项之外另一种给命令提供额外信息的方式。上面的命令将返回CPU的温度:

    temp=51.5'C

用下面的命令测量树莓派的核心电压:

    $vcgencmd measure_volts core

返回电压值:

    volt=1.2000V

5.3 什么是Shell

Shell是UNIX系统提供的文本交互界面。你只要用键盘输入命令就可以和操作系统交互,但这还是不够具体。说到底,Shell其实是一个运行着的程序。这个程序接收到你两次单击“Enter”键之间的输入,就会对输入的文本进行分析,比如下面这个命令:

    $free -h

包括空格在内总共7个字符。Shell程序通过空格区分出命令的不同部分。第一个部分是命令名,剩下的部分是选项和参数。在这个例子中,Shell会进一步分析第二个部分,发现这一部分的开头是“-”字符,从而知道它是一个选项。

有了命令名,Shell下一步就要执行该命令名对应的动作。这听起来就像是在戏剧舞台上,演员按照脚本演戏。Shell命令可以分为如下三类。

●Shell内建函数(built-in function)。

●可执行文件(executable file)。

●别名(alias)。

Shell的内建函数是保存在Shell内部的脚本。相对应地,可执行文件是保存在Shell之外的脚本。Shell必须在系统中找到对应命令名的可执行文件,才能正确执行。我们可以用绝对路径来告诉Shell可执行文件所在的位置。所谓路径,是指一个文件在存储空间的位置,例如:

    /bin/date

这个路径表明date这个可执行文件位于根目录下的bin文件夹内。

如果用户只给出了命令名,而没有给出准确的位置,那么Shell必须自行搜索一些特殊的位置,也就是所谓的默认路径。Shell会执行第一个和命令名相同名字的可执行文件。这就相当于,Shell帮我们自动补齐了可执行文件的位置信息。我们可以通过which命令来确定命令名对应的是哪个可执行文件:

    $which date

别名就是给某个命令起的一个简称,以后在Shell中就可以通过这个简称来调用对应的命令。在Shell中,我们可以用alias来定义别名:

    $alias freak="free -h"

Shell会记住我们的别名定义。以后在这个Shell中输入命令freak时,都将等价于输入free -h。

在Shell中,可以通过type命令来了解命令的类型。如果一个命令是可执行文件,那么type将打印出文件的路径。

    $type date
    $type pwd

总的来说,Shell就是根据空格和其他特殊符号,来让电脑理解并执行用户要求的动作。到了后面,我们还将看到Shell中的其他特殊符号。

5.4 Shell的选择

Shell是文本解释器程序的统称,所以包括了不止一种Shell。常见的Shell有sh、bash、ksh、rsh、csh等。在树莓派中,就安装了sh和bash两个Shell解释器。sh的全名是Bourne Shell,其中Bourne就是这个Shell的作者。而bash的全名是Bourne Again Shell。在UNIX系统中流行的是sh,而bash作为sh的改进版本,提供了更加丰富的功能。一般来说,都推荐使用bash作为默认的Shell。树莓派及其他Linux系统中广泛安装了sh,都是出于兼容历史程序的目的。

我们可以通过下面的命令来查看当前的Shell类型:

    $echo $SHELL

echo用于在终端打印文本,而$是一个新的Shell特殊符号,它提示Shell,后面跟随的不是一般的文本,而是用于存储数据的变量。Shell会根据变量名找到真正的文本,并替换到变量所在的位置。SHELL变量存储了当前使用的Shell的信息,可以在bash中用sh命令启动,用exit命令从中退出。

5.5 命令的选项和参数

我们已经看到,一行命令里还可以包含着选项和参数。总的来说,选项用于控制命令的行为,而参数说明了命令的作用对象,例如:

    $uname -m

在上面的命令中,选项-m影响了命令uname的行为,导致uname输出了树莓派的CPU型号。如果不是受该选项的影响,那么uname输出的将是Linux。我们不妨把每个命令看作多功能的瑞士军刀,而选项使命令可以在不同的功能间切换。由一个“-”引领一个英文字母,这称为短选项。多个短选项的字母可以合在一起,跟在同一个“-”后面。比如,下面的两个命令是等价的:

    $uname -m -r
    $uname -mr

此外还有一种长选项,是用“--”引领一个英文单词,比如:

    $date --version

上面的命令将输出date程序的版本信息。

如果说选项控制了瑞士军刀的行为,那么参数就提供了瑞士军刀发挥用途的原材料。以echo命令为例,它能把字符打印到终端。它选择打印的对象,正是它的参数:

    $echo hello

有的时候,选项也会携带变量,以便说明选项行为的原材料,比如:

    $sudo date --set="1999-01-01 08:00:00"

选项“--set”用于设置时间,用等号连接的就是它的参数。date会把日期设置成这一变量所代表的日期。如果用短选项,那么就要用空格取代等号了:

    $sudo date -s "1999-01-01 08:00:00"

值得注意的是,Shell对空格敏感。当参数信息中包含了空格时,我们需要用引号把参数包裹起来,以便Shell能识别出这是一个整体。

选项和参数都是提供给命令的附加信息,因此,命令最终会拿这些字符串做什么,是由命令自己决定的。因此,有时会发现一些特异的选项或参数用法。这个时候,就要从文档中寻找答案。

5.6 如何了解一个陌生的命令

每一个Linux系统都带有一套完善的文档用于解释每个命令的用途。你可以用下面三个命令来调用某个命令的文档信息。

1.whatis

    $whatis ls

whatis命令的作用是用很简短的一句话来介绍命令。

2.man

    $man ls

man会返回命令的帮助手册。对于大部分Linux自带的命令来说,作者编写时,都会写一个帮助文档,告诉用户怎样使用这个命令。man可以说是我们了解Linux最好的百科全书,它不仅告诉你Linux自带的命令的功能,还可以查询Linux的系统文件和系统调用。如果想要深入学习Linux,就必须要懂得如何用man来查询相关文档。

3.info

    $info ls

info将返回更详细的帮助信息。

5.7 Shell小窍门

使用Shell时应用一些小窍门,可以让你事半功倍。

1.命令补齐

大多数的Shell都有命令补齐的功能。当你在$的后面输入命令的一部分时,比如“dat”,按Tab键,Linux会把它补充成为“date”。在这个过程中,Shell会搜索该命令名的所有可能。如果只有一种可能,那么Shell就会把该文件名补齐。如果不止一种,那么第一次按Tab键会没有反应,第二次按Tab键时,终端会打印出所有可能的命令名。比如输入“da”,按两次Tab键后,终端输出:

    dash date

这样的提示,能帮你想起自己想要输入的命令。

2.文件名补齐

不止是命令名,如果输入的是作为参数的文件名,Linux也可以帮你补齐。比如,当前目录下有a.txt文件。当你输入到ls a.t的时候,按Tab键,Shell会帮你补齐该文件名,即lsa.txt

3.历史命令

在Shell中,可以用向上箭头,或history命令来查看之前输入的命令。

    $history

4.中止与暂停命令

当一个命令运行时,如果中途想要停止它,那么可以用快捷键Ctrl+C。如果只是想暂时停止,那么可以使用快捷键Ctrl+Z。中止与暂停应用了Linux中的信号(Signal)机制,笔者将在第23章介绍。