> For the complete documentation index, see [llms.txt](https://gaas.gitbook.io/guide/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gaas.gitbook.io/guide/software-realization-build-your-own-autonomous-drone/xian-xiu-zhi-shi-su-cha-shou-ce-linux-cao-zuo.md).

# 先修知识速查手册：Linux操作

## 我们建议开发者通过直接安装镜像来使用 GAAS

{% content-ref url="/pages/-Lt8f6v3oi09\_56KxY\_m" %}
[GAAS v0.7 Release 镜像 - x64](/guide/handy-tools/gaas-v0.7-release-jing-xiang-x86.md)
{% endcontent-ref %}

## Linux命令行的基本使用：

由于ROS和PX4等相关软件都是以Linux操作系统为基础的，因此需要掌握Linux平台的基本操作，主要是在shell命令行中进行基本操作。 下图为Linux终端的界面示例：

![Linux终端](/files/-M-0T8izhNCAY7ioQnKi)

与Windows系统类似，Linux系统也使用目录树的形式来组织文件，典型的Linux的文件系统结构如下图所示：

![](/files/-M-0TEBg314u_hxpn_RZ)

`/`为Linux文件系统的起始点，在`/`以下会有很多其他的文件和文件夹：

![](/files/-M-0TLr0RKUTLd1dexa9)

Linux系统的权限机制使得每一个用户默认都只能操作自己的家（Home）文件夹，这个文件夹的路径为`/home/用户名`。

例如，若当前用户名为`gi`，则家目录的路径为：`/home/gi`——这个路径也可以直接用`~`替代，即`/home/gi/GAAS`等价于`~/GAAS`。

&#x20;`./`表示当前目录——要执行某个当前目录下的程序，需要在前面加上`./`——例如当前目录下有一个程序`hello`，执行该程序需要输入以下命令并回车：

`./hello`&#x20;

类似地，`../`表示上一级目录。&#x20;

以下列出了一些较为常用的命令：

`man` 显示用户手册，在`man`后面接某一个命令可以显示这个命令的详细使用指南；

`ls` 显示指定路径下的所有内容，不指定路径则显示当前文件夹里的所有内容，常用参数为`ls -l`，指定文件夹以列表形式显示；

`cd` 进入某一路径，使用`cd ..`可以进入上级目录；

`mkdir` 建立一个指定名字的目录；

`cp` 复制，用法为`cp 源文件 目标路径`，若要复制一个目录则需要加上参数`-r` ；&#x20;

`mv` 移动，用法同`cp`，但移动目录不需要`-r`参数；

`cat` 显示一个文本文件的内容；

`clear` 清除当前终端显示的所有内容；

`touch` 新建一个指定名字的空的文本文件

若要终止一个正在运行的程序，可以按键盘上的组合键 **Ctrl+C**

## Linux的权限机制

输入`ls -l`可以看到列表形式显示的文件的详细信息：

![](/files/-M-0UnNzTsgdpueMKKCB)

在`/`目录下输入`ls -l`可以发现大部分文件是系统所有的（即所有者为`root`），因此默认情况下用户不能修改这些文件，否则会提示访问被拒绝`permission denied` **。**&#x6B64;时如果当前用户具有`root`权限的话，则可以直接在要执行的命令前加上`sudo`，例如在`/`目录下建立一个文本文件`text.txt`，如下所示：`sudo touch text.txt`

此时会要求输入密码——注意此时你输入的字符不会被显示在终端上，这是正常现象。

![输入密码时没有字符显示](/files/-M-0VAnSZkqA_FjuSNSB)

关于权限机制，有以下命令较为常用（执行时需加`sudo`）：

`chown` 更改某个文件或文件夹的所有者——该命令较为常用的场景是，若用`sudo`执行某命令，生成了一些文件，则这些文件的所有者也会是`root`，执行移动之类的操作会遇到权限问题；

`chmod` 为某个文件添加指定的权限——常用的场景是`chmod +x` 为某个文件（例如自己写的shell脚本）添加可执行权限，若无此权限则无法直接执行。

## Linux的环境变量

1、环境变量介绍：

&#x20;环境变量的作用是，指明一个路径，让Linux shell和通过shell启动的程序，可以从指定的路径查找程序和文件。&#x20;

例如`ls`命令，实际上是一个单独的程序。位于`/bin`目录——通过`which`命令可以查看某一个命令对应的程序的路径：

![](/files/-M-0Vg6RWw9OS5DGm7f9)

**提示：若遇到形如"xxx not found"的报错，xxx为某组件，但该组件已经安装，请首先考虑环境变量问题。**

2、bashrc文件

&#x20;`bashrc`是Linux自带shell的一个脚本，该文件位于家目录，为隐藏文件（文件名以`.` 开头），实际的路径为：`~/.bashrc` **。**

当系统新建一个shell命令行窗口时，该脚本就会被执行一次，因此可以修改这个脚本以实现添加配置环境变量等功能。注意，修改并保存该文件并不会让环境变量马上生效，必须重新打开一个新的终端窗口，或者执行以下命令：&#x20;

`source ~/.bashrc`

例如，在已经通过`apt-get`安装ROS的情况下，若不配置环境变量，则运行时会提示找不到`roscore`：

![](/files/-M-0Vwl7KfhcRZF8Tb48)

需要将以下命令添加到`bashrc`中并执行`source`：

`source /opt/ros/melodic/setup.bash`

该命令的作用是，在shell启动时执行`setup.bash`脚本，完成ROS相关环境变量设置。脚本生效后可以用`which`命令找到`roscore`位置：

![](file:///C:/Users/user/Evernote/TEMP/enhtmlclip/Image\(6\).png)3、echo命令&#x20;

shell实际上也是一种编程语言，`echo`命令的作用是向屏幕上输出特定内容，类似于python中的`print`函数。其常用的作用是在编写shell脚本时输出说明内容，或者显示某个环境变量的内容。 例如，使用以下命令可以显示环境变量`GAZEBO_MODEL_PATH`内容：

![](/files/-M-0WWPpf3f0uob08kMy)

注意环境变量名必须以 `$` 符号开头——该环境变量可以指示Gazebo去下述路径搜索模型文件。 其使用方法如下：&#x20;

`echo $环境变量名`

## 包管理器的使用

1、Ubuntu系统的包管理器使用

在Linux系统下，通过包管理器，可以从指定的软件源上下载并自动安装编译好的软件，并设置好所有正常使用需要的相关设置。

Ubuntu使用`apt`作为包管理器。其基本的使用方式为：

`apt-get install 软件包名`

由于包管理器需要修改系统文件，因此如果你使用非`root`用户运行`apt-get`时，需要加上`sudo`：

`sudo apt-get install 软件包名`\
2、修改软件源地址

Ubuntu系统自带了官方软件源的地址，集成了大量常用的软件。但是由于官方源的服务器位于国外，访问时可能会有网速问题。通常情况下可以将其修改为国内的镜像服务器。Ubuntu系统源的地址保存在`/etc/apt/sources.list`文件中，修改该文件，将里面的地址替换为镜像服务器地址即可。

以下是清华大学开源镜像站（TUNA）的Ubuntu源使用说明：<https://mirror.tuna.tsinghua.edu.cn/help/ubuntu/>

另外，ROS使用apt-get安装，但它并不是官方源的内容，因此安装ROS之前也需要先添加ROS的源。

以下是ROS的安装说明：

<http://wiki.ros.org/melodic/Installation/Ubuntu>

**注意添加ROS源之后必须也将key添加到系统中，否则会无法使用ROS的源。**

![添加ROS源的key](/files/-M-0X8cKhlBK3xmj74pT)

在修改源地址之后，必须运行以下命令，使得修改的源生效，否则会无法使用修改的源：&#x20;

`sudo apt-get update`

3、Python的包管理器使用&#x20;

除了Ubuntu系统之外，Python语言也有一个包管理器——由于ROS依赖于Python的一系列第三方包，因此必须使用包管理器为Python安装这些包。&#x20;

Python的包管理器是pip，需要先用apt安装：

`sudo apt-get install python-pip`

基本用法如下：&#x20;

`pip install 包名`

要从镜像站下载软件包，可以使用参数 `-i`：

`pip install 包名 -i  镜像站地址`

TUNA的pip镜像使用说明如下：

<https://mirrors.tuna.tsinghua.edu.cn/help/pypi/>\
如果在安装时遇到了permission denied问题，可以使用参数`--user`：

`pip install 包名 --user`

**切记尽量不要使用sudo运行pip！**

## 从源码编译程序

1、源码分发与二进制分发&#x20;

软件的分发方式有源码分发和二进制分发两种。大部分 Windows 软件和使用包管理器安装的 Linux 软件都使用的是二进制分发——即用户收到的是编译好的二进制程序。 由于 Linux 系统缺乏二进制兼容，包括 GAAS 在内的很多开源软件通常使用源码分发，需要用户自己下载源码进行编译。这样做的一个好处是可以在不涉及专有指令集的情况下兼容更多的体系结构，例如 GAAS 也可以在ARM平台（英伟达TX2）下编译并运行。

2、cmake与makefile介绍

很多开源软件是基于C/C++的，对于依赖关系复杂的 C/C++ 程序，需要按照依赖顺序依次进行编译和链接——这一过程非常复杂繁琐，如果修改了一部分代码，需要对修改的代码进行增量编译（从头重新编译太耗时间）。UNIX 系统使用 makefile 定义编译规则和依赖关系，使用 `make` 命令可以自动地执行 makefile 中定义好的编译规则，并自动跳过已经编译好且没有被修改的文件。

Ubuntu的C++编译器工具链和make命令并没有随系统自带，需要使用`apt-get`安装：

`sudo apt-get install build-essential`

使用make命令可以执行定义好的makefile，用法如下：&#x20;

`make 目标`

此处“目标”由makefile定义，例如以下命令可以构建PX4固件和Gazebo仿真环境：&#x20;

`make posix_sitl_default gazebo`&#x20;

对于大部分软件，此处直接空着就行，即：&#x20;

`make`&#x20;

使用参数-j可以指定使用多少个子进程并行编译，例如：&#x20;

`make -j4`&#x20;

若有多核CPU则使用该参数可以充分利用，但注意子进程数不能多于实际可用的CPU核心，否则可能导致编译失败。

C++ 程序通常可以实现跨平台复用一些代码，对于不同的平台使用的库和编译工具链会有区别——Cmake 便应运而生。Cmake 可以检测当前平台的编译器和第三方库，自动配置好编译工具链——例如对于Linux系统就可以最终生成 makefile。 Ubuntu下可以使用apt-get安装cmake

3、从源码安装开源软件的标准流程

对于大多数开源软件，其从源码编译安装流程如下：&#x20;

(1) 获取源码，若软件从GitHub上下载，则直接使用git拉取代码：&#x20;

`git clone 软件的git地址`&#x20;

(2) 建立cmake文件夹——由于cmake没有提供清理功能，因此需要建立一个单独的文件夹，一般将其命名为build：&#x20;

`cd 软件目录`&#x20;

`mkdir build`&#x20;

`cd build`&#x20;

(3) 使用cmake生成makefile——大多数情况下直接使用命令行cmake按默认参数配置即可：&#x20;

`cmake ..`&#x20;

此处目录定位在软件所在目录下的`build`子目录中。cmake的配置文件是`CMakeLists.txt`，里面指定了软件需要使用的库和编译参数。该文件由开源软件作者提供，通常保存在软件所在目录里。指定路径之后（此处为`build`子目录的上级目录中，即软件自己所在的目录） cmake会自动寻找`CMakeLists.txt`

(4) 执行编译：&#x20;

`make`&#x20;

`（可选）sudo make install`&#x20;

对于第三方库类的开源软件，`install`的作用是指定将编译好的二进制文件安装到系统库中，供其他程序使用。 若直接执行`sudo make install`则生成的二进制文件所有者为`root`，会带来一些麻烦，因此最好先执行`make`再`install`。当编译完成之后再运行`sudo make install`，则`make`可以自动检查并跳过已经编译好的文件，直接执行`install`。
