ubuntu学习

Liunx文件目录

  1. home是家目录,是个人目录,建议在通常情况下个人相关的内容也是保存在该目录中,因为其它目录大都是系统相关的,使用时容易导致混乱,而且需要相关权限
  2. 特别地,前面说明的家目录(个人目录)路径为“/home/用户名/”,见下图,图中的例子目录是/home/embedfire 。也就是说,在 Ubuntu 系统下,用户的个人目录都在“/home”下,并且按照用户名命名,如果系统下有多个用户 A、B、C 并且它们都有个人目录的话,那么它们的个人目录路径默认就是“/home/A”,“/home/B”,“/home/C”。
  3. 如软件工具默认安装在/usr/bin 目录,软件工具的配置文件可能位于/etc 目录,甚至系统的日常使用如插入 U 盘或光盘,又发现它们不会像 Windows 有独立的盘符可以访问,而是默认挂载在/media 或/mnt 目录下。

根目录结构

整个 Linux 系统有且只有一棵从根目录开始的目录树,如下图所示
在这里插入图片描述

  • 给电脑插入 U 盘,系统会自动把 U 盘挂载在“/media/用户名/”目录下,打开该目录即可访问 U盘进行读写

根目录的内容如下图:
在这里插入图片描述

文件类型

在Linux下一切皆文件

  • 普通文件
    如文本文件,bin 文件等
  • 可执行文件
    可执行文件包括脚本和应用程序,这些文件可被系统加载运行,类似 Windows 下的 bat 脚本、exe程序文件等。
  • 链接文件分为硬链接和软链接:
    • 硬链接是指同一个文件的不同别名。
    • 软链接文件有类似于 Windows 的快捷方式。它实际上是 一 个特殊的文件。在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息。
  • 目录文件
    在 Linux 下目录也是文件。
  • 设备文件
    硬件设备也是文件,通过打开对应的设备文件可以初始化设备,部分设备还可以通过读写设备文
    件实现对硬件的控制

文件扩展名

在 Windows 下习惯通过文件的后缀名来判断可以使用什么软件打开对应的文件,而 Linux 下没有
这样的要求,便 Linux 下为了容易区分和兼容用户使用 Windows 的习惯,我们还是会用扩展名来
表示文件类型。举例如下:

  • 后缀.tar、.tar.gz、.tgz、.zip、.tar.bz 表示压缩文件,创建命令一般为 tar,gzip,zip 等。在压
    缩文件中的后缀名来通常表示自身由什么压缩格式打包的,以便解压时方便选择要使用的
    命令。
  • .sh 表示 shell 脚本文件,通过 shell 语言开发的程序。
  • .pl 表示 perl 语言文件,通过 perl 语言开发的程序。
  • .py 表示 python 语言文件,通过 python 语言开发的程序。
  • .html、.htm、.php、.jsp、.do 表示网页语言的文件。
  • .conf 表示系统服务的配置文件。
  • .rpm 表示 rpm 安装包文件。

用户组与文件权限

  • 在etc文件夹下有三个重要的文件:/etc/passwd ;/etc/shadow;/etc/group
  • /etc/passwd用于存放用户帐号信息,/etc/shadow 用于存放每个用户加密的密码,/etc/group用于 存放用户的组信息。
    • 开机登入时,先在password上查找用户名是否正确,正确的话获取UID;
    • 然后在group文件获取gid;
    • 前两部完成后,在shadow文件下查看密码是否正确

用户及用户组

  • 用户按照使用者分为:管理员,系统用户,普通用户
  • 在 Linux 中,每个用户都有一个特定的编号——UID,用于标识一个系统用户。Linux 将标号 0 分配给 root 用户的 uid,它可以分配给每个用户不同的权限,因此每个用户可进行的操作也不同。
  • UID取值范围: root 0; 系统用户:1~999;普通用户1000以上
  • 每个用户可以对应多个分组

文件权限

  • Linux 的文件属性,可以分为读权限、写权限、执行权限。
  • 读权限以及写权限,基本上和 Windows操作系统是一样的。
  • 执行权限,是指可以加载到内存中,并由操作系统加载程序执行的文件。
    在 Windows 操作系统中,我们接触最多的应该是后缀为.exe 的文件。但是对Linux 来说,它并不是通过后缀名来识别文件类型的,如果我们想要执行某个可执行文件,则需要为其添加执行权限,即勾选前面的“允许作为程序可执行文件"。
  • 关于 Linux 文件权限,还需要分三种情况:文件拥有者(owner),分组成员(groups)
    以及其他分组成员(other)。
  • 我们可以通过 chmod 命令在终端快速地修改文件的权限。
  • 如果给所有人添加可执行权限:chmod a+x 文件名;
    如果给文件所有者添加可执行权限:chmod u+x 文件名
    r w x

Linux命令行

在早期的 Unix 系统与用户就是通过 Shell 进行交互的,如下图所示,Shell 对外接受用户输入的命令,对内通过“系统调用”传递给内核,内核执行操作后把输出通过 Shell 呈现给用户,也就是说,Shell 就是一个中间人。而 Shell 的英文原意“壳”,也是为了把它与内核区分开来。
在这里插入图片描述
Shell、终端(Terminal)或控制台(Console),严格来说它们实际上不是同样的东西,但只要明白,当我们说打开 Shell、终端或控制台的时候,通常就是为了使用命令行控制系统。它们的严格区分如下,了解下即可:

  • Shell:指命令行解释器,常见的解释器有 bash,sh,在 Ubuntu 系统默认用的是 bash 解释器,所以有时说 bash 也是指命令行。
  • 终端(Terminal):通常指用来运行 Shell 的程序,示场景的不同有不一样的名称,如 Ubuntu系统自带的叫本地终端,嵌入式开发板常常提供串口进行输入输出的串口终端,通过网络访问的 ssh 终端。
  • 控制台(Console):特指某些终端,通常是指它的物理形态,如带键盘和显示器的物理设备。

通过快捷键 Ctrl+Alt+T,可以快速打开一个命令行终端;

命令提示符

在这里插入图片描述

  • pwd 输出当前所在目录
  • ls 显示当前目录所有内容
  • 每个命令都会带有一个“-h”或者“–help”的参数,可以用来打印一些帮助说明
    在这里插入图片描述

    自动补全

    • 按一下“Tab”键时如果只有一个匹配的内容时它会自动补全,按两下“Tab”键则会列出所有的匹配项。
    • Tab”键除了用来补全命令名,还可以自动补全路径,如我们使用 cd 命令输入“/home”参数时,先输入“/ho”然后按下“Tab”键,它会把“/ho”自动补全为“/home”路径名

命令的退出与取消

在应用中我们有时会想要中止命令的执行,或者命令输入到一半的时候觉得输错了不想继续,这时我们都可以通过“Ctrl”+“c”的组合键来结束。

命令究竟是什么

在终端中,我们使用 which 命令可以查看指定命令的路径,如查看 ls、pwd、cd 命令:
在这里插入图片描述ls 命令实际是/bin/ls 程序,pwd 命令实际是/bin/pwd 程序,而 which cd 命令没
有输出,因为 cd 命令是 Shell 自己内部的程序

  • 我们在 Shell 中输入 ls 命令与输入/bin/ls 的作用是一样的,当我们输入 Shell 时,它会到预定的目录下查找有没有该程序,如果有就使用命令选项及参数调用该程序执行,并把程序的输出再呈现出来。而这个预定的目录我们可以通过如下命令来查看:
    echo $ PATH //echo 是输出命令,而"$PATH" 是一个变量,表示输出变量内容!
    在这里插入图片描述

  • “$ PATH”是终端使用的路径环境变量,它使用“: ”进行分隔,表示 Shell 将会在这些路径下寻找命令程序,在其中我们可以看到/bin 路径。也就是说,“$PATH”路径环境变量让我们输入命令时省去了输入完整路径的麻烦,而命令的本质大都是在文件系统中的一些应用程序。

常用命令

cd

把终端当前所在的路径切换至目标路径,比如:cd /home/embedfire/test

在这里插入图片描述

mkdir 命令

它可以在文件系统中创建一个新的目录
其命令格式如下:mkdir [-p] 目录名

  • 命令格式中的“目录名”就是要创建的目录路径,“-p”选项可以不输入,若使用了“-p”选项,当创建的目录名包含的上级目录不存在时,它会自动创建所有不存在的目录

touch命令

touch 命令可以创建不存在的文件,或者 touch 通过参数修改目录或文件的日期时间,就是摸一下,更新它的时间。
它的命令格式如下:touch 文件名

ls命令

显示指定目录下的内容(文件及子目录) ,还可以查看文件大小,修改日期等等信息
ls 命令格式如下:ls [选项] [目录]
当“目录”参数省略时,它会列出当前目录的内容。在这里插入图片描述
在这里插入图片描述

-rw-r--r-- 1 jing jing 8980 4月  12 07:26 examples.desktop
drwxr-xr-x 2 jing jing 4096 4月  12 15:29 公共的
  • 第一字段:文件属性
    文件属性共有十个字符,第一个字符代表文件的类型,字符“-”表示该文件是一个普通文件;字符“d”是 dirtectory(目录) 的首字符,表示该文件是一个目录。

  • 后面的九个字符,每三个为一组,分别表示文件拥有者的权限、文件所属组拥有的权限以及其他用户拥有的权限。字符“r”代表的是读(read)权限,字符“w”代表的是写(write)权限,字符“x”代表的是执行(execute)权限

  • 第二字段:链接占用的节点/子目录的个数
    第二字段的含义,主要取决该文件的类型,如果是文件的话,则表示该文件所具有的硬连接数。某个文件的第二字段如果等于 1 的话,代表没有其他指向该文件的硬连接。
    在这里插入图片描述

  • 第三字段和第四字段:文件拥有者和文件所在的组

  • 第五字段:文件所占用的空间 (以字节为单位)
    第五字段表示文件大小,在 Linux 中,目录是一个特殊的文件。

  • 第六字段:最近访问(修改)时间

  • 第五字段表示文件最近访问的时间,使用 touch 命令,可以修改文件的第六字段。

cat命令

cat 命令是 concatenate 的简写,译为串联,即它可以把两个内容串联起来,我们通常使用它在终端下输出文件的内容进行查看。cat不能查看目录
命令格式为:cat 文件名

echo命令

echo 命令的功能是在终端上打印一段文字,也可以把终端的变量内容打印出来
其命令格式如下:

  • echo " 字符串"
  • echo 字符串
  • echo $ 变量名

使用 echo 命令时,带双引号和不带双引号的效果是一样的,使用引号时,要注意用英文符号

输出重定向到文件

把命令执行的结果保存到文件进行分析,这时我们可以使用输出重定向到文件的控制符“>”或“»”,其中“>”会直接用输出覆盖原文件,而“»”则把输出追加到原文件的末尾。
使用格式如下:

  • 命令 > 文件名
  • 命令 >> 文件名
    重定向时文件不存在会自动创建。

rmdir 命令

rmdir 命令是 remove directory 的简写,它的功能是删除空的目录。

  • 命令格式如下:rmdir [-p] 目录名
    -p 可以用来递归删除目录,如果子目录删除后其父目录为空时,也一同被
    rmdir 命令只能够用来删除空目录

rm 命令

rm 命令是 remove 的简写,它的功能是删除一个或多个文件或目录。

  • 其命令格式如下:rm [选项] 一个或多个文件/文件夹名
    使用 rm 命令删除内容时,文件是会被直接永久删除的,它并不会放到回收站中再确认
    它支持的选项如下:
    • -i:删除文件或文件夹前,终端会逐一询问确认
    • -r:将目录及其包含的子目录或文件全部删除
    • -f:忽略不存在的文件,无需逐一确认
mkdir -p ABC/test     //创建 ABC/test 目录
rm a.txt b.txt           //直接删除 a.txt b.txt
3 rm –i c.txt d.txt            //询问式删除 c.txt d.txt

当带有参数 i 时,则会有询问是否删除文件,如果是,输入 y;反之,则输入 n。

  • 前面提到 rmdir 命令不能删除非空的目录,我们可以使用 rm 命令配合“-r”选项来完成:rm –r ABC/

sudo

sudo 命令是 switch user do 的简写,意思是切换用户去做某件事情
有时我们在执行命令时忘记添加 sudo 前缀,执行失败提示时才想起要加 sudo,这时可以使用
“sudo !!”的方式使用 sudo 权限重新执行上一条命令

cd /home            #  切换至/home 目录
 touch test.txt      # 提示没有权限
 sudo !!                  # sudo 加两个感叹号,重新使用 sudo 权限执行上一条命令

reboot/poweroff 命令

在终端上,reboot/poweroff 命令来控制系统的重启与关机

man命令

可用于查看 Linux 系统自带的参考手册,该手册包含非常丰富的内容,甚至在我们进行编程开发时还可以使用它来查看函数的接口
man 命令格式:man [要查询的内容]
在命令行中输入:man man #即使用man来查询man
下面截取了一段
在这里插入图片描述
在命令行中输入 man printf
在这里插入图片描述输出的PRINTF(1),表示是man的第一章的printf
如果查第三章中库调用需要在终端输入:

  • man -s 3 printf
  • man 3 printf
    -s可以省略

在这里插入图片描述

apt 及 yum 包管理工具

deb 包、dpkg 及 apt

在 Linux 操作系统中,最常见的两种包分别是 deb 和 rpm。
在 Debian、Ubuntu 等 Linux 发行版中,通常使用 deb(debian)形式的软件包
包提供了操作系统的基本组件,以及共享的库、应用程序、服务和文档,当用户需要时,可以运行特定的指令来安装。

  • 对于下载到本地和已经安装的软件包可以使用dpkg命令
sudo dpkg -i xxxx.deb
  • apt 能够自动从互联网的软件仓库中搜索、安装、升级、卸载软件,它会咨询软件仓库,并能安装软件时的模块及依赖问题。
sudo apt-get install 软件名
  • 概括起来可以这么理解,deb 是软件包,dpkg 是手动安装工具,apt 是自动安装工具。

rpm 包、rpm 及 yum

在 RedHat,Fedora,Centos 等派系的 Linux 发行版中,通常使用 rpm(RedHat PackageManager) 形式的软件包

  • rpm 与 dpkg 的功能类似,同样是主要用于对已下载到本地和已经安装的软件包进行管理。
rpm -ivh xxxx.rpm
  • yum(Yellow dog Updater, Modified)包管理工具,功能与 apt 工具类似,它会咨
    询软件仓库,并能安装软件时的模块及依赖问题。
yum install 软件名

在这里插入图片描述

apt 工具的使用

  • apt-get 工具:主要负责软件包的的安装、卸载以及更新等事务。
  • apt-cache 工具:用于查询软件包的相关信息。
  • apt-config 工具:用于配置所有 apt 工具。

apt-get 安装与删除软件包

apt-get 工具安装程序,具体的命令语法:sudo apt-get install 软件包名

  • apt-get install 会扫描本地存放的软件包更新列表/var/lib/apt/lists/,找到最新版本的软件包,然后检查软件包依赖关系,找到支持该软件正常运行的所有软件包,并从镜像源地址中下载所需的软件包,最后解压软件包,自动完成应用程序的安装和配置。
apt-get remove

具体的命令语法如下:sudo apt-get remove 软件包名

apt-cache 查询软件包信息

apt-cache 工具配合对应的子命令,可以实现查找,显示软件包信息及包依赖关系等功能
在这里插入图片描述
例如,可通过如下命令搜索支持 ifconfig 命令的软件包:apt-cache search ifconfig

直接使用 apt 命令

在 Ubuntu 16.04 中就引入了 apt 命令,apt 是集 apt-get、apt-cache 和 apt-config 各工具之所长的工具在这里插入图片描述
apt 命令比 APT(上面的apt-get等) 包管理工具更加精简

sudo apt install vim    #安装Vim

Ctrl”+“z”强制退出vim编辑器。

软件源及其修改

• 清华大学镜像源:https://mirrors.tuna.tsinghua.edu.cn
• 中国科技大学镜像源:https://mirrors.ustc.edu.cn
• 阿里云镜像源:https://opsx.alibaba.com/mirror
在 Ubunut 下, 软 件 源 的 配 置 是 记 录 在 文件/etc/apt/sources.list 中的
在这里插入图片描述在这里插入图片描述

Vim

  • vi 文件名 #若文件存在则打开,文件不存在则创建
  • vim 文件名字 #若文件存在则打开,文件不存在则创建

退出

注意若开启了输入法,要先把输入法设置成英文:

  • “Ctrl”+“z”直接强制退出。
  • 按下退出键“Esc”,Vim 会进入到“一般模式”。
  • 输入英文冒号“:”,Vim 会进入到“命令行模式”。
  • 输入强制退出命令“q!”,即字母“q”及英文叹号“!”。
  • 按回车执行命令,会退出 Vim,返回到终端。

输入内容

  1. 按下退出键“Esc”进入“一般模式”。
  2. 输入一般命令“i”,即直接按字母“i”,进入“插入模式”,如下图所示。
  3. 随意输入一些内容。
  4. 按下退出键“Esc”再次进入“一般模式”。
  5. 输入英文冒号“:”,Vim 会进入到“命令行”模式。
  6. 输入保存退出命令“wq”。
  7. 按回车执行命令,会退出 Vim,返回到终端。

Vim 的三种模式

  • 一般模式(normal mode):一般模式用来浏览文本,查找内容,但是不可以编辑,在该模式下的键盘输入会被当成快捷键,如复制粘贴等。打开 Vim 时,默认是工作在一般模式。
  • 插入模式(insert mode):插入模式下具有普通编辑器的功能,该模式下的键盘输入会被当成文本内容。
  • 命令行模式(command-line mode):命令行模式支持保存、退出、替换等命令,以及 Vim 的高级功能。

插入模式

在这里插入图片描述

一般模式

在这里插入图片描述

命令行模式

按下键盘的冒号键“:”就可以进入命令行模式
在这里插入图片描述

磁盘管理

  • df命令可以查看所有的存储设备以及其挂载点

  • du命令可以查看当前文件夹下所有文件的使用量

    # 直接使用du命令的话,会把所有的文件等列出来,比较多,可以使--max-depth=a层数来限制
    #加入-h显示的是,k,G等容量
    $ du --max-depth=1  #只显示一层目录
    16	./笔记
    5700836	./linux
    5700856	.
    $ du -h --max-depth=1
    16K	./笔记
    5.5G	./linux
    5.5G	.
    
  • 新加入的硬盘设备在dev目录下,u盘这种移动设备在根目录下的media文件夹下,media文件夹下的内容会自动挂载

  • 如果对u盘进行类似分区的操作,需要先挂载u盘时,一般直接挂载分区,而不会是前面的sd*

    比如挂载sda时,应挂载其下的分区sda1和sda2

    在这里插入图片描述

    <在这里插入图片描述

  • 挂载命令:mount

    sudo mount /dev/sda1 /mnt  # 前面是需要挂载的,后面是挂载的目录
    
    # 挂载过程中的中文可能会出现乱码的情况,可以制定相应的编码格式
    sudo mount -O iocharset=utf8 /dev/sda1 /mnt #O为大写
    
  • 卸载命令:umount

    sudo umount /mnt  #mnt为相应的挂载点
    

Ubuntu新添加硬盘

  • 文件/etc/fstab 详细的记录了 Ubuntu 中硬盘分区的情况

  • 在对一块新硬盘使用时,流程如下:

    fdisk创建分区
    mkfs格式化
    mount挂载
  • fdisk 在创建分区时

    $ sudo fdisk /dev/sda
    
  • 根据提示和帮助信息可以按n创建新的扇区,但是确定容量时,根据扇区确

  • 一个扇区等于512个字节

  • 比如分区的大小想确定为1G,那么1G容量对应的扇区数如下:
    1 G = 1024 M = 1024 ∗ 1024 K B = 1024 ∗ 1024 ∗ 1024 B = 1073741824 B 扇区数 = 1073741824 / 512 = 2097512 1G=1024M=1024*1024KB=1024*1024*1024B=1073741824B \\ 扇区数=1073741824/512=2097512 1G=1024M=10241024KB=102410241024B=1073741824B扇区数=1073741824/512=2097512
    在这里插入图片描述

  • 确定了第一个扇区的起始位置,在加上所需的扇区数,就是最后一个扇区的扇区数,比如上图中的第一个扇区是2048,分配1G的空间需要2097512个扇区,所以最后一个分区就是2048+2097512

  • w为保存退出,退出之后可以通过fdisk -l 来查看新创建的分区

linux连接文件

  • Linux有两种连接文件:符号连接(软连接)和硬链接
  • 软连接类似Windows下的快捷方式,硬连接在在我看来就是映射存储设备的同一个inode
  • 硬连接创建好之后,更改一个,所有的都被更改,删除的话需要把所有的硬连接和原文件都删除,才能彻底删除,删除原文件并不会影响硬连接的文件

Linux c编程

编写程序

  • 使用的vim进行编写程序,首先设置以下vim

    • vi/vim编辑器默认 TAB 键为 8 空格,我们改成 4 空格,打开文件/etc/vim/vimrc,在文件后面加上如下代码(修改时应使用管理员权限,代码写在endif后)
    set ts=4
    
    • vim显示行数,在上述文件添加以下代码
    set nu
    
    • 修改后的/etc/vim/vimrc最后部分如下:
     " Source a global configuration file if available
     if filereadable("/etc/vim/vimrc.local")
     	source /etc/vim/vimrc.local
     endif
     set ts=4
     set nu
    
  • 通过vim会直接新建不存在的文件

编译程序

  • 编译器使用的是gcc,在终端中输入gcc -v可以查看gcc的版本信息,其有x86架构的版本,也有ARM版本的,PC端一般都是x86版本的,如果想编译ARM版本的,需要交叉编译

  • gcc的编译流程为:预处理、编译、汇编和链接

    • 预处理就是展开所有的头文件、替换程序中的宏、解析条件编译并添加到文件中
    • 编译是将经过预编译处理的代码编译成汇编代码,也就是我们常说的程序编译
    • 汇编就是将汇编语言文件编译成二进制目标文件。
    • 链接就是将汇编出来的多个二进制目标文件链接在一起,形成最终的可执行文件
  • gcc 命令

    gcc [选项] [文件名]
    gcc main.c -o main
    
    • 主要的选项如下,可通过man命令具体查看
    • -c:只编译不链接为可执行文件,编译器将输入的.c 文件编译为.o 的目标文件。
    • -o:<输出文件名>用来指定编译结束以后的输出文件名,如果不使用这个选项的话 GCC 默认编译出来的可执行文件名字为 a.out。(链接之后的可执行文件
    • -g:添加调试信息,如果要使用调试工具(如 GDB)的话就必须加入此选项,此选项指示编译的时候生成调试所需的符号信息。
    • -O:对程序进行优化编译,如果使用此选项的话整个源代码在编译、链接的的时候都会进
      行优化,这样产生的可执行文件执行效率就高。
    • -O2:比-O 更幅度更大的优化,生成的可执行效率更高,但是整个编译过程会很慢。
  • 执行的话使用命令“./+可执行文件”

  • 如果有多个c文件和头文件,只需要使用gcc编译c文件,不需要编译h文件

Makefile

Makefile基础

  • 工程编译的工具:make,描述哪些文件需要编译、哪些需要重新编译的文件就叫做 Makefile,Makefile 就跟脚本文件一样,Makefile 里面还可以执行系统命令。使用的时候只需要一个 make

  • 在和c和头文件的文件夹内创建Makefile文件(文件名要对,makefile也行

  • 通过input.c,mian.c,calcu.c生成main可执行文件为例子:

    • 首先在文件夹内创建Makefile文件,Makefile文件内容如下:
    1 main: main.o input.o calcu.o           # 两行一组,第一行冒号之前的是生成的文件,后面是它的依赖
    2     gcc -o main main.o input.o calcu.o # 第二行开头是一个Tab按键,这一行是需要执行的操作
    3 main.o: main.c
    4     gcc -c main.c
    5 input.o: input.c
    6     gcc -c input.c
    7 calcu.o: calcu.c
    8     gcc -c calcu.c
    9
    10 clean:
    11     rm *.o
    12     rm main
    
    
    • 文件的第一行是最终生成的可执行文件,最终需要生成的必须放在文件的第一个
    • 此处必须使用Tab,不能使用空格
    • 里面的gcc命令和普通的不太一样,需要生成的文件和依赖文件的位置不同
  • 编写完Makefile后,直接使用make指令

    在这里插入图片描述

Makefile语法

Makefile规则格式

  • Makefile 里面是由一系列的规则组成

    目标…... : 依赖文件集合……
    	命令 1
    	命令 2
    	……
    
  • make 命令会为 Makefile 中的每个以 TAB 开始的命令创建一个 Shell 进程去执行

  • make的执行过程大致如下:

    • make 命令会在当前目录下查找以 Makefile(makefile 其实也可以)命名的文件。
    • 当找到 Makefile 文件以后就会按照 Makefile 中定义的规则去编译生成最终的目标文件
    • 当发现目标文件不存在,或者目标所依赖的文件比目标文件新(也就是最后修改时间比目标文件晚)的话就会执行后面的命令来更新目标。

Makefile变量

  • 变量示例如下:

    1 #Makefile 变量的使用
    2 objects = main.o input.o calcu.o  
    3 main: $(objects)   				#Makefile 中变量的引用方法是“$(变量名)”
    4	gcc -o main $(objects)
    
    • 注意等号前后的空格
  • 赋值符“=”

    1 name = ss1
    2 curname = $(name)
    3 name = ss2
    4
    5 print:
    6	@echo curname: $(curname)
    
    • “echo”前面加了个“@”符号,因为 Make 在执行的过程中会自动输出命令执行过程,在命令前面加上“@”的话就不会输出命令执行过程
    • 调用make print的结果如下:

    在这里插入图片描述

    • 注意结果是ss2,不是ss1,如果想结果是ss1的话,需要使用下面的“ := ”
    • 赋值符“=”的神奇之处!借助另外一个变量,可以将变量的真实值推到后面去定义。
    • 也就是变量的真实值取决于它所引用的变量的最后一次有效值。
  • 赋值符“:=”

    1 name = ss1
    2 curname := $(name)
    3 name = ss2
    4
    5 print:
    6	@echo curname: $(curname)
    
    • 注意等号前后的空格
    • 调用make print如下:

    在这里插入图片描述

    • 赋值符“ := ”会使用后面定义的变量,只能使用前面已经定义好的,这就是“ = ”和“ := ”两个的区别
  • 赋值符“?=”

    curname ?= zuozhongkai
    
    • 上述代码的意思就是,如果变量 curname 前面没有被赋值,那么此变量就是“zuozhongkai”,如果前面已经赋过值了,那么就使用前面赋的值。
  • 变量追加“+=“

    objects = main.o inpiut.o
    objects += calcu.o
    
    • 一开始变量 objects 的值为“main.o input.o”,后面我们给他追加了一个“calcu.o”,因此变量 objects 变成了“main.o input.o calcu.o”

Makefile 模式规则

  • 减少Makefile命令的重复书写,使用类似于统配符的方式来简化书写

  • 示例如下:

     1 objects = main.o input.o calcu.o
     2 main: $(objects)            #注意空格
     3     gcc -o main $(objects)
     4 
     5 %.o: %.c                    #注意空格
    
    
  • 至少在规则的目标定定义中要有“%”,否则就是一般规则

  • 目标中的“%”表示对文件名的匹配,“%”表示长度任意的非空字符串

  • 比如“%.c”就是所有的以.c 结尾的文件,类似与通配符,a.%.c 就表示以 a.开头,以.c 结束的所有文件

Makefile 自动化变量

  • 通过一行命令来从不同的依赖文件中生成对应的目标

    自动化变量描述
    $@规则中的目标集合,在模式规则中,如果有多个目标的话,“$@”表示匹配模
    式中定义的目标集合。
    $%当目标是函数库的时候表示规则中的目标成员名,如果目标不是函数库文件,
    那么其值为空。
    $<依赖文件集合中的第一个文件,如果依赖文件是以模式(即“%”)定义的,那么
    “$<”就是符合模式的一系列的文件集合。
    $?所有比目标新的依赖目标集合,以空格分开。
    $^所有依赖文件的集合,使用空格分开,如果在依赖文件中有多个重复的文件,
    “$^”会去除重复的依赖文件,值保留一份。
    $+和“$^”类似,但是当依赖文件存在重复的话不会去除重复的依赖文件。
    $*这个变量表示目标模式中"%"及其之前的部分,如果目标是 test/a.test.c,目标模
    式为 a.%.c,那么“$*”就是 test/a.test。
  • 示例如下:

    1 objects = main.o input.o calcu.o
    2 main: $(objects)
    3     gcc -o main $(objects)
    4 
    5 %.o: %.c
    6     gcc -c $<
    7 
    8 clean:
    9     rm *.o
    10    rm main
    
    

Makefile 伪目标

  • Makefile 有一种特殊的目标——伪目标,一般的目标名都是要生成的文件,而伪目标不代表真正的目标名,比如上面的clean

  • 使用伪目标主要是为了避免 Makefile 中定义的执行命令的目标和工作目录下的实际文件出现名字冲突

  • 比如在Makefile的同级目录下有clean文件,那么当Makefile时就发现其已经存在,不需要执行下面的命令,因此下面的命令不会被执行

  • 为了解决上述的问题就需要声明其为伪目标文件,示例如下:(第四行)

    1 objects = main.o input.o calcu.o
    2 main: $(objects)
    3     gcc -o main $(objects)
    4 .PHONY: clean             #写成".PHONY : clean"也没有问题
    5 %.o: %.c
    6     gcc -c $<
    7 
    8 clean:
    9     rm *.o
    10    rm main
    

Makefile 条件判断

  • 条件判断两种语法如下:

    • <条件关键字>
      	<条件为真时执行的语句>
      endif
      
    • <条件关键字>
      	<条件为真时执行的语句>
      else
      	<条件为假时执行的语句>
      endif
      
  • 条件关键字有4个,分别是ifeq,ifneq,ifdef,ifndef

  • ifeq判断是否相等,ifneq判断是否不相等

    • ifeq用法如下,相等的话为真,ifneq用法与其相似,不相等为真

      ifeq (<参数 1>, <参数 2>)
      ifeq ‘<参数 1 >’,‘ <参数 2>’
      ifeq “<参数 1>”, “<参数 2>”
      ifeq “<参数 1>”, ‘<参数 2>’
      ifeq ‘<参数 1>’, “<参数 2>
  • ifdef判断变量是否为非空。ifndef判断变量是否为空

    • ifdef非空为真,ifndef空为真

      ifdef <变量名>
      

Makefile函数使用

  • Makefile 中的函数是已经定义好的,不支持自定义函数

  • 函数用法如下:

    $(函数名 参数集合)或者${函数名 参数集合}
    
  • 参数集合是函数的多个参数,参数之间以逗号“,”隔开,函数名和参数之间以“空格”分隔开

shell脚本

  • shell脚本类似windows的批处理文件,shell脚本就是将连续执行的命令写成一个文件。

  • shell脚本是个纯文本文件,命令从上而下,一行一行的开始执行。shell脚本扩展名为.sh。

  • shell的第一行一定是

    #!/bin/bash   #表示使用bash
    

shell相关语法

  • 第一个shell脚本如下:

    1 #!/bin/bash
    2 echo "Hello Word "   
    
    • echo为在终端输出

    在这里插入图片描述

  • 交互式的shell脚本

     1 #!/bin/bash
     2 echo "Please input your name "
     3 read name
     4 echo "your name:" $name
    
    • 第三行是读取终端的输入并给变量name,在第四行使用变量的时候不加括号

    在这里插入图片描述

    • 第四行中的 $name 放到双引号里面也可以
      1 #!/bin/bash
      2 read -p "input your name and age:" name age
      3 echo "your name:$name,age=$age"
    
    • 使用read -p 可以输出字符

    在这里插入图片描述

  • 数值计算

    • shell仅支持整形,数值计算使用$((表达式))
      1 #!/bin/bash
      2 read -p "input two number:" first second
      3 sum=$(($first+$second))      
      4 echo "$first+$second=$sum"
    
    • 第三行的等号前后均没有空格

    在这里插入图片描述

  • test命令

    • test命令用于查看文件是否存在、权限等信息,可以进行数值,字符,文件三方面的测试。
    • &&和||命令:
      • cmd1 && cmd2 当cmd1执行完并且正确,那么cmd2开始执行,如果cmd1执行完毕错误,那么cmd2不执行。
      • cmd1 || cmd2 当cmd1执行完毕并正确,那么cmd2不执行,反之cmd2执行。
      • && 和 || 可以连用
      • cmd1 && cmd2 || cmd3 此条命令就是如果cmd1执行成功就执行cmd2,反之就执行cmd3
  • 中括号[]判断符

    • 示例如下:
      1 #!/bin/bash
      2 read -p "input two str:" first second
      3 [ $first == $second ] && echo "yes" || echo "no"
    
    • 注意第三行***[ ]里面的前后均有一个空格***,里面可以写==或者!=

    在这里插入图片描述

    • 但是需要注意的是[ ]里面的比较也会比较你带的分号,比如
      1 #!/bin/bash
      2 read -p "input two str:" first second
      3 [ $first == "a" ] && echo "yes" || echo "no"  
      
      #如果键盘输入的第一个是a,但是此时的输出结果是No,但是如果把a的引号去掉,或者给$first加上引号输出的就是yes
    
  • 默认变量

    $0~$n,表示shell脚本的参数,包括shell脚本命令本身,shlle脚本命令本身为$0
    $##表示最后一个参数的标号。
    $@:表$1$2$3......
    

    在这里插入图片描述

    在这里插入图片描述

  • shell脚本的条件判断

    • shell脚本支持条件判断,虽然可以通过&&和||来实现简单的条件判断,但是稍微复杂一点的场景就不适合了
    • shell脚本提供了if then条件判断语句,语法如下:
    if  条件判断 ; then
    	//判断成立要做的事情
    fi
    
    • 示例如下
      1 #!/bin/bash
      2 read -p "input first num:" first
      3 read -p "input second num:" second
      4 if [ $first == $second ]; then
      5         echo "=="
      6         exit 0
      7 elif [ $first -gt $second ]; then
      8         echo ">"
      9         exit 0
     10 else
     11         echo "<"
     12 fi
    
    
  • case选择语句

    case $变量 in
    “第1个变量内容”)
    	程序段
    	;;	//表示该程序块结束!!
    “第2个变量内容”)
    	程序段;;
    “第n个变量内容”)
    	程序段
    	;;
    esac
    
    • 示例如下:
      1 #!/bin/bash
      2 
      3 case $1 in
      4         "a")
      5                 echo "param is a"
      6                 ;;
      7         "b")
      8                 echo "param is b"
      9                 ;;
     10         *)
     11                 echo "other"
     12                 ;;
     13 esac
     14 
    
    • $1表示shell命令的第一个参数,第四行只有半个括号,通配符不需要加引号

    在这里插入图片描述

  • shell函数

    • shell支持自建函数,写法如下:
    function fname () {
    	//函数代码段
    }
    
    • function可写可不写,fname为函数名
      1 #!/bin/bash
      2 
      3 print(){
      4     echo "param 1:$1"
      5     echo "param 2:$2"   
      6 }
      7 print a b
    
    • 最后一行是给print传递参数

    在这里插入图片描述

  • shell循环

    while [条件] 	//括号内的状态是判断式
    do			//循环开始
    	//循环代码段
    done
    
    
    # until do done,表示条件不成立的时候循环,条件成立以后就不循环了
    until [条件]
    do
    	//循环代码段
    done
    
  • for 循环

    for var in con1 con2 con3……
    do
    	//循环代码段   如果要使用in后面的变量,那么就使用var和python差不多
    done
    
    
    # 还有一种for循环和c语言的比较相似
    for((初始值; 限制值; 执行步长))
    do
    	//循环代码段
    done
    

    在这里插入图片描述

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值