[机派X] Day4 - Bash 指令原来如此容易

引言

今天是机派X系列文章的第四天。
昨天介绍了 Bash 的基本概念,大家都熟悉了吗?
本篇将介绍 Linux 的档案系统,并透过 Bash 来操作档案系统。

本篇大纲:

  • 引言
  • Linux 的档案系统
  • Bash 中常用的程序(档案系统的操作)
  • 关於本文章系列

前一篇文章中有提到,shell 是我们(也就是使用者)与 Ubuntu 间的桥梁,透过 shell 输入指令就能操作电脑!因此,接着我们会介绍一些常用的指令,熟悉这些指令後,使用 Ubuntu 将会变得轻松又自在。

我将要介绍的指令依用途分为:

  • 档案系统的操作
  • 使用者及权限管理
  • 网路设定与管理
  • 软件管理

这些类别中的指令彼此可以互相搭配使用,用以构成我们想要电脑做的事!
因此在介绍以上指令後,会有一篇文章提供几个指令使用的范例,这些范例会将不同指令结合并写成脚本,用以完成一些特定工作。

Linux 的档案系统

在介绍档案系统相关的指令前,先简单说一下什麽是档案系统(File System , FS)。档案系统能够将硬体装置中的资料汇整成井然有序的样子(例如:树状结构)以便使用者操作。硬碟(Disk)、磁区(Partition)、资料区块(Block)等概念,透过档案系统的包装形成树状结构,使用者只要透过树状结构所形成的档案路径,即可存取档案。举例来说,当你开启一个 Word 档并进行编辑时,你只需要知道档案的储存路径(例如 D:\Documents\report.docx)就可以完成相关操作,而无须知道档案具体在硬碟中是如何被储存的。

Linux 的档案系统与 Windows 不同,又之後的 Bash 指令介绍会涉及档案操作,因此在介绍 Bash 中常用的指令前,必须要介绍 Linux 的档案系统。

常见的 Windows 系统是以磁区(Partition / Volume)做为档案系统的基本单位。由於一台电脑中可能存在多个不同的磁区,因此一台电脑中的档案结构可能是由多个彼此独立的树状结构所构成。以下图来说,磁碟 0、磁区 1(Disk 0, Partition 1)被挂载上了磁区代号 C,以 C: 为树状结构的根(root)就可以存取底下的档案与资料夹。而光碟机则是被挂载上了磁区代号 E,以 E: 为树状结构的根,又可以得到另一个树状图。
Windows 磁碟管理截图

而 Linux 的档案系统则是仅由一个树状结构所形成。如下图所示,树状图中每个圆圈都是一个节点,也是一个目录(Directory),而灰色线条则是连接父目录与子目录(树状图的概念中可以称为父节点与子节点),这张图其实并不完整,没有把每个节点都绘出,之後实际操作指令时会把完整结构呈现出来。树状图中的的根(root)就是 Linux 档案系统的顶端,我们称它为根目录(root directory),写成路径时会写成 / 。
Linux 档案系统结构图

Note :
别忘了,在 Linux 中,资料夹(Folder)又称为目录(Directory)。
而路径表示中,Windows 采用反斜线 \,Linux 采用正斜线 / 。

在根目录底下,会有许多目录,用於储存不同东西。我们只介绍之後常用到的几个,至於其他部份可以参考 鸟哥的 Linux 教学

目录路径 用途 例子
/dev 目录中的档案直接连接至各设备,例如:硬碟、网路摄影机等。对其下的档案操作,形同於直接操作对应的设备。 如果今天你在 RPi 上插入了一个随身碟,通常会被挂载於 /dev/sda 。直接对 /dev/sda 操作就等同操作随身碟中的资料。
/home 在 Linux 系统中,每个使用者通常都会有一个家目录(Home Directory),其功能类似於 Windows 中的 C:\Users\%USERNAME% ,可用於储存各个使用者的资料。通常,使用者的家目录会位於 /home 目录底下。 例如使用者 ubuntu 的家目录通常位於 /home/ubuntu ,在这个目录中使用者 ubuntu 可以储存自己的私人资料。
/etc 包含各项系统设定档。 例如之後会用到的 ssh server 的设定档就位於这里。
/var 包含系统运作时所产生的档案。 例如:系统日志(Log)、错误发生日志(Error Log)、快取(Cache)等。
/tmp 用於暂时储存某些档案或目录。 例如:程序执行时,临时需要一个资料夹暂存资料,/tmp 就是个好地方。可搭配 mktmp 指令来使用。

Note :
登入 Shell 後,通常预设的工作目录都会是自己的家目录(Home Directory)。例如前一天有提到,使用者 ubuntu 登入後,预设的工作目录是 /home/ubuntu 也就是 ubuntu 的家目录。另外在 Bash 中使用者的家目录又可以被简写为 ~ ,所以如果是以使用者 labuser 登入的话,~ 其实就等同 /home/labuser 。

Bash 中常用的指令(档案系统的操作)

接下来要开始介绍指令(CMD)了,并实际操作这些指令。不同的 Shell 其支援的指令也不相同,本系列文章会以 Bash 为主做介绍。不过即使你使用了其他的 Shell 也没关系,因为很多基本指令是共通的。

Note :
以下仅会带过常用的指令以及常用的用法,若要查看完整的指令说明,请详阅指令使用手册或善用网路资源。另外,部份范例可能会让你觉得难以理解,建议可以查询相关指令的说明书後再看看,可能会有意想不到的发现,毕竟教学不是我一个人的事,希望读者也能自主思考、动手去做,尤其是在实做这个区块更是如此,如果用尽各种方法还是无法理解,欢迎在文章下方留言,让我或邦帮忙上的大家帮你一把。

echo 印出大法

首先第一个是 echo,如果你学过其他程序语言,你应该会知道 print() 或 System.out.print() 等函式。echo 的功用也是如此,echo 用於将资料输出至萤幕上。

以下是 echo 的用法:

echo [OPTION]...... [MESSAGE]......

MESSAGE 就是你要印在萤幕上的讯息,而 [] 代表其内的东西可有可无,依照你的需求而定。

例如:我们希望输出 Hello,我们可以这样下指令:

echo Hello

echo 输出讯息时,会自动在结尾添加一个换行,因此输出看起来会像这样:

ubuntu@ubuntu:~$ echo Hello
Hello
ubuntu@ubuntu:~$

如果不给 MESSAGE 内容的话,只会输出 echo 自动帮你加的换行。

ubuntu@ubuntu:~$ echo

ubuntu@ubuntu:~$

[MESSAGE] 後方的 ...... 代表 [MESSAGE] 可以不只一个!
例如:

ubuntu@ubuntu:~$ echo Hello World
Hello World
ubuntu@ubuntu:~$

而 OPTION 则是 echo 的引数要放的位置。
如果不想要结尾自动添加的换行,可以为 echo 增加一个引数 -n 。

ubuntu@ubuntu:~$ echo -n Hello
Helloubuntu@ubuntu:~$

可以把引数想成修饰的功能,我要执行 echo 指令,但是又希望 echo 能根据我的需求客制化行为,因此加上了引数来做调控。为什麽叫做引数呢?因为他能够引导一些「需求」给 echo,让 echo 改变行为。如果有学过程序的话,这边提到的引数其实跟函式(function)的引数是一样的意思,只是形式看起来不一样而已。

可以观察到 OPTION 也有 [] 包起来,所以没有给 OPTION 也没关系,所以前几个范例没给 OPTION 还是能正常执行。OPTION 後方也有 ...... ,所以引数也可以给很多个。

Note :
使用 echo 输出讯息的时候,建议将讯息以引号包起来,以避免发生问题。
例如: echo 'Hello'
使用单引号 ' 或双引号 " 其实意义不同,不过在这边你可以先混用,之後提到变数时候会再介绍。

请将树莓派开机并登入 Ubuntu,等到看到熟悉的 $ 符号出现就可以开始打指令罗。
你可以尝试以下几个指令:

echo Hello World
echo Hello
echo -n Hello
echo 'Hello World'
echo 'Hello\nWorld'
echo -e 'Hello\nWorld'
echo -e 'Hello\nWorld\n'

在程序中 \n 代表换行,可以观察到 echo 'Hello\nWorld' 并没有作用 。

ubuntu@ubuntu:~$ echo 'Hello\nWorld'
Hello\nWorld
ubuntu@ubuntu:~$

原因是因为 echo 预设不会解读跳脱字元 \n ,所以 \n 会被直接印出。只要加上 -e 引数就可以让 echo 解读跳脱字元了。

ubuntu@ubuntu:~$ echo -e 'Hello\nWorld'
Hello
World
ubuntu@ubuntu:~$

如同前面提到的,echo 允许我们有多个引数,例如:

ubuntu@ubuntu:~$ echo -e -n 'Hello\nWorld'
Hello
Worldubuntu@ubuntu:~$

因为 -e 所以 Hello 和 World 之间有换行,而因为有 -n 所以 World 後方没有自动加换行。

再来看看这些例子吧:

echo 'Happy Father'\''s Day'
echo "Happy Father"\'"s Day"
echo "Happy Father's Day"

touch 来个新档吧

你可以透过 touch 来建立一个纯文字文件。
以下是 touch 的使用方式。

touch [OPTION]...... FILENAME......

可以观察到 FILENAME 没有 [] 包住,代表档名是一定要给的。

ubuntu@ubuntu:~$ touch
touch: missing file operand
Try 'touch --help' for more information.
ubuntu@ubuntu:~$

建立档案时,如果档名有空白,要用引号包起来,不然会被以为是两个文件的档名。

touch Hello World
touch 'Hello World'

ls 看看哪里有什麽

也许你会觉得奇怪,教你使用 touch 建立档案,但是却没教你如何看档案是否成功建立,也不知道目前有什麽档案。

接下来教你使用 ls 来列出特定档案与目录中的内容。
ls 的使用方式如下:

ls [OPTION]...... [FILE]......

FILE 如果是某个档案的档名,则 ls 会列出该档案的相关资讯;FILE 如果是个目录,则 ls 会列出目录中的档案和资料夹;FILE 如果省略不写,则会显示当前工作目录下的档案。FILE 可以使用相对路径来写,也以使用绝对路径。如果是使用相对路径,则其基准就是工作目录。另外,如果路径中有空白,应该将路径以引号包住!

Note :
别忘记了,之前有介绍过工作目录(Working Directory),简单来说工作目录就是「你下指令时,所在的目录位置」。当我们下的指令有需要操作档案时,恰巧档案路径又使用相对路径,此时工作目录就会显的很重要。如果忘记相关说明,请移驾至昨天的文章看看。

举例来说,这样可以显示当前工作目录的档案与目录:

ls

而引数 -l 可以将档案与目录的详细资料列出。在 Linux 中,档案或目录的档名若以 . 开头会被视为隐藏档案,ls 预设不会显示,加上引数 -a 可以将隐藏档也一并列出。

你可以试试看以下几个范例:

ls .
ls ..
ls ~
ls -l ~
ls -l -a ~
ls -l /var/log

cat 看看档案内容

透过 cat 你可以查看纯文字档案的内容。
以下是用法:

cat [OPTION]...... [FILE]......

FILE 就是要查看的档案路径,跟 ls 一样,FILE 可以是绝对路径或相对路径。之後很多指令会用到档案操作,档案路径的写法也相同,之後便不会再多提。

你可以尝试以下指令:

cat /etc/passwd
cat /var/log/syslog

看完这篇文章後,你可以思考这个:

echo -e 'Apple\nBanana\nGrapes' > part1.txt
echo -e 'Papaya\nPineapple' > part2.txt
cat part1.txt part2.txt > fruit.txt
rm part1.txt part2.txt

cd 变更工作目录

cat /var/log/syslog 觉得很麻烦吗?
可曾想过将工作目录换到 /var/log ,这样就可以直接执行 cat syslog ?

透过 cd 可以切换工作目录。以下是 cd 的用法,dir 就是新的工作目录的位置,若是省略 dir 就会直接切换到家目录。

cd [DIR]

你可以尝试以下几个例子,并搭配 ls 使用:

cd /var/log
cd ..
cd
cd ./..

重新定向

透过 > 可以将资料重新定向,> 的左方是资料, > 的右方是资料要输出至的档案名称。

例如,以下指令会在萤幕上输出 Hello World,但是透过 > 可以将资料输出到指定档案中。

echo 'Hello World'

例如,将资料输出至档案 kkk.txt 中。

echo 'Hello King of the World' > kkk.txt

另外,你可以尝试以下指令:

echo 'Hello Queen' >> kkk.txt

目录的建立与删除

你可以透过 mkdir 与 rmdir 来建立与删除目录,请参考以下用法。

mkdir [OPTION]...... [DIR]......
rmdir [OPTION]...... [DIR]......

DIR 就是要建立或删除的目录的路径。

可以尝试以下几个例子并搭配 ls 来观察指令执行结果:

mkdir 123/456/789
mkdir -p 123/456/789
mkdir 123
rmdir 123/456
rmdir 123/456/789
rmdir 123/456
rmdir 123

rm 万能抹除大师

rmdir 只能用来删除空目录,若要删除非空目录或档案,请使用 rm。

rm [OPTION]...... [FILE]......

可以尝试以下例子并搭配 ls 来观察指令执行结果:

mkdir abc
touch abc/hello
rm abc
rm -r abc

mv 千面女郎

mv 可以用於移动档案或目录,可以想成 move 的缩写。
以下是用法,SOURCE 是来源路径,可以是档案或目录,DEST 是目标路径。

mv SOURCE DEST

可以尝试以下例子并搭配 ls 来观察指令执行结果:

touch hello
mv hello world
mkdir 123 456
mv 456 123/456
mkdir foo
touch data
mv data foo
mkdir a b
mv b a
mkdir i j
touch j/data
mv j i/k

cp 拷贝大师

cp 原文是 copy,所以很明显 cp 指令的用途是复制档案或目录。

cp [OPTION] SOURCE DEST

直接来几个范例吧!

echo 'Hello World' > a
cp a A
mkdir bar
touch bar/apple bar/banana
cp bar foo
cp -r bar foo

man 有问题?找男人

以上一些指令大家还 ok 吗?
你会知道怎麽用这些指令是因为我有说明,那你是否好奇我怎麽知道这些指令呢?
指令如此繁多,用法各异,参数也各自自成一国,又该如何记住呢?

你为什麽不问问神奇海螺呢
图源传送门

其实掌握两个技巧就可以了:

  1. 熟练就好
  2. 学习查询、看使用说明

因为常用到的指令自然会记得,以上面那些例子来说,常常会用到 ls ,我想 ls 的用法要你现在忘掉也不容易。常用的东西想忘也忘不掉,当然也就不用背,这就是熟练就好的意思。
我亦无他,唯手熟尔
(图源传送门:此图源於网路,但是我找不到来源,因此版权方若看到本图请跟我联络)

那不常用的东西呢?因为不常用,所以忘记在所难免,可以透过网路查询或看使用说明来解决。如果某个指令或特定参数因不常用而忘记,那也无须逼迫自己硬记,要用到的时候再查询就好,反正也不常用,所以偶尔查一下不会浪费很多时间。

查询时要有效率,才不会浪费时间。
而我又是如何知道这些指令以及使用方式的呢?
Answer:man

man 也是一条指令,man 的原文是 manual 也就是使用手册,man 就是用来查询使用手册的指令。

man [OPTION] [SECTION] [CMD]

CMD 就是你要查询的指令名称,SECTION 是章节编号。
你可以尝试以下几个例子:

man ls
man rmdir
man man
man passwd
man 5 passwd

透过 man 你可以快速了解一个指令的用途、用法等资讯,甚至还能透过 man 来查询 man 的用法。
以後忘记指令或是看到陌生指令,不妨使用 man 来查询看看吧!

今天我想来点注解

在程序的世界中,有时会在程序或指令旁标示一些给人看的文字,用於说明某程序的功用或是呈现作者相关资讯,这些文字不是程序或指令,因此电脑看到时会略过不管,我们称它为注解(comment)。

在 Bash 中,只要是以 # 开头的那行,整行都会被视为注解。

例如:

# Print Hello

因为以 # 开头,所以会被视为注解,# 後面的内容是给人看的,电脑会略过不看。

注解在目前看似无用,但在之後写脚本的时候却会派上用场!

我不知道怎麽关机啊?

最後要介绍的是如何将系统关机或重新开机,这部份虽然不属於档案系统的操作,但是我实在找不到其他适合的地方来摆放这段,所以先放这里吧!

# 关机
poweroff

# 重新开机
reboot

# 登出当前的使用者
exit

Note :
其实也可以使用 shutdown 指令来操作,只是需要熟悉一下参数使用。相对参数的变换来说,也许直观的英文单字所组成的指令更能迅速烙印在你的脑海中,因此上面才会介绍那些指令。

关於本文章系列

如果对於文章内容有建议、纠错或图源标示不正确的问题,欢迎参考 [机派X] Day 1 尝试与文章作者联络。
想看更多本系列的文章,请连结至 [机派X] Day 1 查看大纲。


<<:  Kneron - Kneron Toolchain 转档操作参考笔记

>>:  Day 2 : HTML - 给我去刻个网站!之 我干了件蠢事

Day 08: Python额外知识小补充

Python额外知识 确认变数型别 Number = 1000 print(type(Number)...

LeetCode 双刀流: 412. FizzBuzz

412. FizzBuzz 412. FizzBuzz 是一个相当经典的题目,号称是 Google...

Day 19 不得不变的学习方式

事情在好起来之前,总会先变很坏,然後才会慢慢的变好。在经历这些过程後,记得要把失去的补回来,把得到的...

JavaScript学习日记 : Day20 - call、apply、bind

1. 语法 func.call(thisArg, param1, param2, ...)//fun...

Day25. Form 里面还有 Form 怎麽办?- 表单 part3

Day23 的弹跳视窗元件,送出表单按钮在form标签的外面,理当来说form 外面的送出表单按钮和...