35、Unix 开发工具与脚本语言全解析

Unix 开发工具与脚本语言全解析

在 Unix 系统开发中,有许多实用的工具和脚本语言,它们能帮助开发者更高效地完成工作。下面将详细介绍这些工具和语言的使用方法和特点。

1. 共享库安装与预防措施

在安装共享库时,可采用一致的方法,使用 -Wl,-rpath 来创建运行时链接路径,或者直接使用不常用库的静态版本,以此预防可能出现的问题。

2. make 工具

当程序包含多个源文件或需要特殊编译选项时,手动编译会变得十分繁琐。而 make 作为传统的 Unix 编译管理工具,能有效解决这一问题。

2.1 make 的基本概念
  • 目标(target) :是 make 要达成的目标,可以是文件(如 .o 文件、可执行文件等)或标签。
  • 依赖(dependencies) :部分目标依赖于其他目标,例如生成可执行文件前需要先有完整的 .o 文件集合。
  • 规则(rule) make 依据规则生成目标,它本身自带许多规则,同时也支持自定义规则。
2.2 Makefile 示例

以下是一个简单的 Makefile,用于从 aux.c main.c 生成名为 myprog 的程序:

# arquivos-objeto
OBJS=aux.o main.o
all: myprog

myprog: $(OBJS)
        $(CC) -o myprog $(OBJS)
  • 首行的 # 表示注释。
  • OBJS 是宏定义,定义了两个目标文件名,后续通过 $(OBJS) 引用。
  • all 是默认目标,即直接执行 make 时要创建的目标。
  • all 依赖于 myprog ,而 myprog 依赖于 $(OBJS) 展开后的 aux.o main.o

执行 make 时,输出如下:

$ make
cc    -c -o aux.o aux.c
cc    -c -o main.o main.c
cc -o myprog aux.o main.o
2.3 预设规则

make 知道如何从 .c 文件生成 .o 文件,即使 .c 文件未在 Makefile 中明确列出,它也会遵循预设规则,执行 cc -c 命令来完成转换。

2.4 最终程序生成

生成 myprog 的最后一步,是在拥有 $(OBJS) 中的两个目标文件后,执行以下命令( $(CC) 会展开为编译器名称):

$(CC) -o myprog $(OBJS)

注意,命令前必须有一个制表符,否则会出现 Makefile:7: *** missing separator. Stop. 错误。

2.5 保持更新

make 的一个重要原则是目标要与其依赖保持同步。例如,连续两次执行 make ,第一次会生成 myprog ,第二次则会提示 make: Nothing to be done for 'all'. ,因为依赖文件未发生变化。若要测试更新机制,可按以下步骤操作:
1. 执行 touch aux.c
2. 再次执行 make ,此时 make 会判断 aux.c aux.o 新,从而重新编译 aux.c
3. 由于 myprog 依赖于 aux.o ,且 aux.o myprog 新,所以 make 会重新创建 myprog

2.6 命令行参数和选项
  • 指定单个目标 :可在命令行指定单个目标,如 make aux.o 仅生成 aux.o 文件。
  • 定义宏 :能在命令行定义宏,例如使用 clang 编译器:
$ make CC=clang
  • 无 Makefile 执行 :若 make 的预设规则能匹配目标,可直接执行 make 尝试创建目标,如 make blah 可处理简单的 blah.c 程序。不过,对于需要特殊库或包含目录的程序,通常需要创建 Makefile。
  • 重要选项
  • -n :显示构建所需命令,但不实际执行。
  • -f arquivo :让 make 从指定文件读取规则,而非默认的 Makefile 或 makefile。
2.7 常用宏和变量
  • 宏(macro) :通常在 Makefile 开头定义,常见的有:
    | 宏名称 | 说明 |
    | ---- | ---- |
    | CFLAGS | C 编译器选项 |
    | LDFLAGS | 链接器选项,用于从目标代码创建可执行文件 |
    | LDLIBS | 存放库名选项,避免与搜索路径选项混合 |
    | CC | C 编译器,默认是 cc |
    | CPPFLAGS | C 预处理器选项 |
    | CXXFLAGS | GNU make 中 C++ 编译器的标志 |
  • 变量(variable) :在生成目标过程中会发生变化,常见的有:
    | 变量名 | 说明 |
    | ---- | ---- |
    | $@ | 在规则中展开为当前目标 |
    | $* | 展开为当前目标的基本名称,如生成 blah.o 时展开为 blah |
2.8 常规目标

多数 Makefile 包含以下常规目标:
- clean :通常用于删除所有目标文件和可执行文件,以便重新开始或打包软件。例如:

clean:
        rm -f $(OBJS) myprog
  • distclean :用于移除所有不属于原始发行版的内容,包括 Makefile。
  • install :将编译好的文件和程序复制到系统中合适的位置。执行前建议先使用 make -n install 查看操作内容。
  • test 或 check :部分开发者提供此目标,用于确保构建后一切正常。
  • depend :通过 -M 选项调用编译器检查源代码来创建依赖关系,不过这种做法现在不太常见。
  • all :通常是 Makefile 的第一个目标,常作为可执行文件的引用。
2.9 Makefile 组织

虽然 Makefile 有多种风格,但多数程序员遵循一些通用规则:
- 宏定义 :将库和包含文件按包分组,例如:

MYPACKAGE_INCLUDES=-I/usr/local/include/mypackage
MYPACKAGE_LIB=-L/usr/local/lib/mypackage -lmypackage
PNG_INCLUDES=-I/usr/local/include
PNG_LIB=-L/usr/local/lib -lpng
CFLAGS=$(CFLAGS) $(MYPACKAGE_INCLUDES) $(PNG_INCLUDES)
LDFLAGS=$(LDFLAGS) $(MYPACKAGE_LIB) $(PNG_LIB)
  • 目标文件分组 :目标文件通常按可执行文件分组。例如,有 boring trite 两个可执行文件,每个都有自己的 .c 文件且依赖 util.c ,可这样组织:
UTIL_OBJS=util.o
BORING_OBJS=$(UTIL_OBJS) boring.o
TRITE_OBJS=$(UTIL_OBJS) trite.o
PROGS=boring trite
all: $(PROGS)
boring: $(BORING_OBJS)
        $(CC) -o $@ $(BORING_OBJS) $(LDFLAGS)
trite: $(TRITE_OBJS)
       $(CC) -o $@ $(TRITE_OBJS) $(LDFLAGS)

不建议将两个可执行目标合并为一个规则,否则可能导致依赖关系错误。

3. 调试器(Debuggers)

在 Linux 系统中,默认的调试器是 gdb ,同时也有用户友好的前端工具,如 Eclipse IDE 和 Emacs 系统。

3.1 调试准备

为了能对程序进行完整调试,需在编译时使用 -g 选项,将符号表和其他调试信息记录到可执行文件中。

3.2 gdb 基本操作
  • 启动 gdb
$ gdb programa
  • 执行程序并传递参数 :在 (gdb) 提示符下输入:
(gdb) run opções
  • 打印变量值 :使用 print 命令查看变量值,该命令也适用于 C 语言中的数组和结构体。
(gdb) print variável
  • 设置断点
(gdb) break arquivo:num_linha
  • 继续执行
(gdb) continue
  • 清除断点
(gdb) clear arquivo:num_linha
4. Lex 和 Yacc

在编译读取配置文件或命令文件的程序时,可能会用到 Lex 和 Yacc,它们是编程语言的构建块。
- Lex :是一个标记生成器(tokenizer),将文本转换为带标签的数字标记。GNU/Linux 版本为 flex ,可能需要 -ll -lfl 链接标志。
- Yacc :是一个解析器,尝试根据语法读取标记。GNU 解析器是 bison ,使用 bison -y 可与 Yacc 兼容,可能需要 -ly 链接标志。

5. 脚本语言

过去,Unix 系统管理员主要关注 Bourne shell 和 awk 脚本语言。如今,虽然 shell 脚本仍是 Unix 的重要组成部分,但 awk 在脚本领域的使用逐渐减少,取而代之的是许多功能强大的脚本语言。

5.1 脚本语言的基本信息

所有脚本语言的脚本首行都类似 Bourne shell 脚本的 shebang。例如,Python 脚本以如下内容开头:

#!/usr/bin/python

#!/usr/bin/env python

在 Unix 中,以 #! 开头的可执行文本文件就是脚本, #! 后面的路径名是脚本语言解释器的可执行文件。当 Unix 尝试执行以 #! 开头的文件时,会执行 #! 后面的程序,并将文件其余部分作为标准输入。

5.2 常见脚本语言
  • Python :拥有众多追随者,具备强大的功能,如文本处理、数据库访问、网络和多线程等。其可执行文件通常为 /usr/bin/python ,还常用于网站开发。
  • Perl :是 Unix 中较古老的第三方脚本语言,曾是编程工具的“瑞士军刀”。尽管近年来在某些方面被 Python 超越,但在文本处理、文件转换和操作方面表现出色。
  • 其他脚本语言
  • PHP :是超文本处理语言,常用于 Web 开发。

通过合理运用这些工具和脚本语言,开发者能在 Unix 系统上更高效地进行开发和调试工作。

Unix 开发工具与脚本语言全解析

5.3 脚本语言使用注意事项
  • 解释器路径问题 :脚本首行指定的解释器路径必须正确,否则会出现错误。例如,若脚本首行为 #!/usr/bin/tail -2 ,而系统中 tail 实际路径为 /bin ,执行脚本会报错:
bash: ./myscript: /usr/bin/tail: bad interpreter: No such file or directory
  • 命令行参数问题 :不建议在脚本首行添加多个参数,因为不同系统处理方式可能不同,容易导致意外结果。

下面通过一个 mermaid 流程图展示脚本执行的基本流程:

graph TD;
    A[开始] --> B{是否以 #! 开头};
    B -- 是 --> C[获取 #! 后路径];
    C --> D[执行对应程序];
    D --> E[将脚本其余部分作为输入];
    E --> F[程序处理并输出结果];
    B -- 否 --> G[非脚本文件,结束];
    F --> H[结束];
6. 总结与操作建议

为了更清晰地对比不同工具和脚本语言的特点及使用场景,我们整理了以下表格:
| 工具/语言 | 主要功能 | 使用场景 | 操作要点 |
| ---- | ---- | ---- | ---- |
| make | 编译管理 | 处理多源文件或特殊编译选项的程序 | 编写 Makefile,注意目标、依赖、规则的设定,命令前用制表符分隔 |
| gdb | 程序调试 | 查找程序中的错误 | 编译时加 -g 选项,掌握 run print break 等基本命令 |
| Lex(flex) | 标记生成 | 处理文本转换为标记的任务 | 可能需 -ll -lfl 链接标志 |
| Yacc(bison) | 语法解析 | 解析标记并根据语法处理 | 用 bison -y 与 Yacc 兼容,可能需 -ly 链接标志 |
| Python | 脚本编程 | 文本处理、数据库访问、网站开发等 | 脚本首行用 shebang 指定解释器路径 |
| Perl | 脚本编程 | 文本处理、文件转换和操作 | 学习其基本语法和常用函数 |
| PHP | 超文本处理 | Web 开发 | 搭建 Web 服务器环境进行开发 |

在实际开发中,可按以下步骤选择和使用这些工具和语言:
1. 确定需求 :明确开发任务的具体需求,如编译管理、调试、文本处理等。
2. 选择工具/语言 :根据需求从上述表格中选择合适的工具或语言。
3. 学习操作要点 :针对所选工具或语言,学习其操作要点和注意事项。
4. 实践应用 :在实际项目中运用所学知识,不断积累经验。

以下是一个简单的操作流程列表,展示如何使用 make gdb 进行程序开发和调试:
1. 编写源代码 :创建 .c 源文件,如 aux.c main.c
2. 编写 Makefile

# arquivos-objeto
OBJS=aux.o main.o
all: myprog

myprog: $(OBJS)
        $(CC) -o myprog $(OBJS)
  1. 编译程序
$ make
  1. 调试准备 :在编译时添加 -g 选项:
$ make CC="cc -g"
  1. 启动调试
$ gdb myprog
  1. 执行调试命令 :如设置断点、打印变量等。

通过以上对 Unix 开发工具和脚本语言的详细介绍,希望能帮助开发者更好地掌握这些工具和语言的使用,提高开发效率和质量。在实际应用中,不断探索和实践,将这些知识灵活运用到具体项目中。

一种基于有效视角点方法的相机位姿估计MATLAB实现方案 该算法通过建立三维空间点二维图像点之间的几何对应关系,实现相机外部参数的精确求解。其核心原理在于将三维控制点表示为四个虚拟基点的加权组合,从而将非线性优化问题转化为线性方程组的求解过程。 具体实现步骤包含以下关键环节:首先对输入的三维世界坐标点进行归一化预处理,以提升数值计算的稳定性。随后构建包含四个虚拟基点的参考坐标系,并通过奇异值分解确定各三维点在该基坐标系下的齐次坐标表示。接下来建立二维图像点三维基坐标之间的投影方程,形成线性约束系统。通过求解该线性系统获得虚拟基点在相机坐标系下的初步坐标估计。 在获得基础解后,需执行高斯-牛顿迭代优化以进一步提高估计精度。该过程通过最小化重投影误差来优化相机旋转矩阵和平移向量。最终输出包含完整的相机外参矩阵,其中旋转部分采用正交化处理确保满足旋转矩阵的约束条件。 该实现方案特别注重数值稳定性处理,包括适当的坐标缩放、矩阵条件数检测以及迭代收敛判断机制。算法能够有效处理噪声干扰下的位姿估计问题,为计算机视觉中的三维重建、目标跟踪等应用提供可靠的技术基础。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值