中国风网站怎么配色,中国建设教育协会的网站,深圳seo优化多少钱,怎么开发软件app软件author: hjjdebug date: 2025年 02月 14日 星期五 17:16:12 CST description: ffmpeg configure 研究1 ./configure 命令行参数的分析 文章目录 1 configure 对命令行参数的分析,在4019行1.1 函数名称: is_in1.2. 函数名称: enable1.3. 函数名称: set_all 2 执行退出判断的关键…
author: hjjdebug date: 2025年 02月 14日 星期五 17:16:12 CST description: ffmpeg configure 研究1 ./configure 命令行参数的分析 文章目录 1 configure 对命令行参数的分析,在4019行1.1 函数名称: is_in1.2. 函数名称: enable1.3. 函数名称: set_all 2 执行退出判断的关键代码:2.1. 函数名称: map2.2 函数名称: die_license_disabled2.3 函数名称 enabled() 3. 小测试代码4.执行结果 $ ./1.sh5.小结:小结1: 命令行参数分析过程概括.小结2: bash脚本的本质是什么? 详细分析了 ffmpeg 下执行 ./configure --enable-libx264 libx264 is gpl and --enable-gpl is not specified. 程序退出的过程 如果说在命令行上有 --enable-libx264 而没有 --enable-gpl 就退出, 用c 写也就寥寥几句, libx264_enablefalse,gpl_enablefale; for(int i0;iargc;i) { if(strcmp(arg[i],“–enable-libx264”)0) libx264_enabletrue; if(strcmp(arg[i],“–enable-gpl”)0) gpl_enabletrue; } if(libx264_enabletrue gpl_enablefalse) exit(1)
如果用bash 又应该怎么写呢 如果只是实现上边的功能,bash 也可以写的很简单, 但在configure 文件中就不是那样写了. 而是有一个复杂的架构, 为什么因为它要支持一些复杂的功能.
所以该博客就是来了解这个简单的功能是如何在复杂的架构上实现的. 让我们能窥斑见豹. 别被它庞大的架构吓唬注了. 这些是bash编程最基本的东西, 就从此开始吧.
1 configure 对命令行参数的分析,在4019行
for opt do 因为 opt 后面没有 in 参数, 实际上就是 in “ , 代码处于顶层 , ,代码处于顶层, ,代码处于顶层,就是命令行参数,此时 $opt --enable-libx264 case 语句会匹配到4087行 –enable-?|–disable-?) eval ( e c h o (echo (echoopt” | sed ‘s/–/action/;s/-/ option/;s/-/_/g’) if is_in $option $COMPONENT_LIST; then test $action disable actionunset eval $action $$(toupper ${option%s})_LIST elif is_in $option $CMDLINE_SELECT; then $action $option else die_unknown $opt fi
bash 在每次执行命令前要进行8大变换. 其是也是很简单的. 大括号扩展 {} , 把形如 {1…5} 扩展为 1 2 3 4 5 波浪线扩展 ~ , 把~扩展为你的家目录 变量扩展 , 简单方式就是 {} , 简单方式就是 ,简单方式就是var样式, 就是变量引用和变量替换 算术扩展 $(()) , 数学运算在这里进行 命令替换 $()或 , 这里可以调用命令先执行命令 分词分割 IFS , 按照空格,tab,回车来分割成单词 路径扩展 * ? [] , 把*展开匹配任意字符,?匹配0或1个字符,[]匹配指定字符 引号去除 , 去除其中的双引号,单引号
把该行信息都收拾一遍叫扫描然后再交给bash去执行命令, eval ( e c h o (echo (echoopt | sed ‘s/–/action/;s/-/ option/;s/-//g’) eval 语句会进行2次扫描. 即扩展了一遍还要再扩展一遍,所以有$$(…)之类的写法 执行第一遍扫描,进行变量扩展 eval $(echo --enable-libx264 | sed s/–/action/;s/-/ option/;s/-//g’) ,进行命令替换 eval actionenable optionlibx264
运行eval命令执行第二遍扫描(此例第一遍已经扩展干净了,第二遍没有要改变的.) actionenable optionlibx264 这条语句交给bash执行,就是定义了2个变量,并赋值. elif is_in $option $CMDLINE_SELECT; then $action o p t i o n l i b x 264 在 option libx264 在 optionlibx264在CMDLINE_SELECT 中被发现会执行 enable libx264 函数 1.1 函数名称: is_in
输入参数: 列表 输出参数: 返回值: 0(成功), 1(失败,假) 描述: 把第一个参数作为值, 依次与后续参数做比较,如果想等返回成功全部不成功,返回失败. is_in(){ value$1 # 第一个参数为value shift for var in KaTeX parse error: Expected EOF, got # at position 7: *; do #̲ 后续参数与value相比 [ $var KaTeX parse error: Expected EOF, got at position 9: value ] ̲ return 0 # 相同…value被扩展为libx264, $CMDLINE_SELECT 被扩展为一堆字符串, 其中包含libx264, 所以其返回为成功. $action $option 被扩展为: enable libx264 1.2. 函数名称: enable
输入参数: 列表 输出参数: 无 返回值: 无 描述: 把参数都做为变量其值设置为yes enable(){ set_all yes $* } 执行结果, 把libx264 设置为了 yes, 等价与 libx264yes 1.3. 函数名称: set_all
输入参数: 列表 输出参数: 无 返回值: 无 描述: 把第一个参数作为value, 其余的参数都作为变量用$value赋值 set_all(){ value$1 # 第一个参数为value, shift # 移除第一个参数 for var in $*; do eval v a r var varvalue # 其余参数都设置为$value done }
注意: 调试时打印pr value 是没有意义的, pr $value才是对变量的引用.
2 执行退出判断的关键代码:
map “die_license_disabled gpl” $EXTERNAL_LIBRARY_GPL_LIST $EXTERNAL_LIBRARY_GPLV3_LIST $EXTERNAL_LIBRARY_GPL_LIST 变量在1721行有定义,包括libx264,libx265及其它模块 该语句功能. 检查一系列模块如果enable 了模块而没有enable gpl, 就退出. 2.1. 函数名称: map
输入参数: 列表 输出参数: 无 描述: 把第一个参数作为命令, 后续参数依次作为$v参数,来执行第一条命令 map(){ m$1 # 把die_license_disabled gpl 赋值给m shift for v; do eval $m; done # 把后面的参数依次送给v, 执行 $m,即执行die_license_disabled gpl 函数 } 2.2 函数名称: die_license_disabled
输入参数: 函数调用参数 1 , 全局参数 1, 全局参数 1,全局参数v 输出参数: 无 功能描述: 判断第1个参数对应“gpl”“nonfree”是否enabled如果已经enabled则正常退出 否则判断$v 参数是否 enabled, 如果为真则打印错误信息并退出(die 函数 注意: 不满足条件时会退出程序. die_license_disabled() { enabled $1 || { enabled KaTeX parse error: Expected EOF, got at position 3: v ̲ die v is $1 and --enable-$1 is not specified.; } } 命令可以作为map 的第一个参数. 该命令接受的参数是$1 和 $v 2.3 函数名称 enabled()
输入参数: 一个参数 输出参数: 无 返回值: 0或1 描述: 对参数$1 判断其值是否是yes enabled(){ test “${1#!}” “$1” op“” || op“!” # 该句设置op为等号或不等号 eval test “x$${1#!}” $op “xyes” # 运行test返回真值或假值. } ${1#!}是$1变量去除从开始到!止部分,$1无!则不会去除任何东西.
3. 小测试代码
为了对enabled() 函数,die() 及颜色设置有更深入理解我写了如下测试函数
$ cat 1.sh
#!/bin/bash
enabled(){test ${1#!} $1 op || op! # 根据第一个参数是否首字符为!为op赋值或者!eval test x\$${1#!} $op xyes # 测试变量的值是否为yes
}
if test -t 1 which tput /dev/null 21; thenncolors$(tput colors)if test -n $ncolors test $ncolors -ge 8; thenbold_color$(tput bold)warn_color$(tput setaf 3) # 设置前景色为黄(3)error_color$(tput setaf 1) # 设置前景色为红(1) , set attr foregroudreset_color$(tput sgr0) # 恢复颜色, set groud 0fi# 72 used instead of 80 since thats the default of prncols$(tput cols)
fi
: ${ncols:72} # :就是空操作, 退出总是成功 ${var:}, 如果ncols 没有值就给72,否则保持不变logfile1.log
log(){echo $ $logfile
}
die(){log $echo $error_color$bold_color$$reset_color # 设置红色,加重的颜色,显示$ 然后颜色再恢复
}abcyes
enabled abc echo abc enabled || echo abc not enabled
enabled abb echo abb enabled || echo abb not enableddie I hope this is red4.执行结果 $ ./1.sh
abc enabled abb not enabled I hope this is red
5.小结:
小结1: 命令行参数分析过程概括.
对于 --enable-libx64 参数而言,它是一个动词-名词的结构,首先用sed将它分为2部分. 把动词作为函数,把名字作为参数执行函数, 实现把名词作为变量进行赋值. 命令行参数分析完后, 对变量进行数值判断,不满足条件则退出程序.
小结2: bash脚本的本质是什么?
bash脚本命令. 就是一个命令的集合体. 命令就是你在控制台下与机器交互输入的命令 你在命令行下所做的操作, 用bash脚本都可以完成. 命令是带参数的. 参数是可以用变量来存储的. 参数经过8大扩展再传递给命令 引入变量和函数可以简化人机的接口,使少敲几个字符就给计算机说明白了. 函数也是由命令集合来构成,支持参数传递,为完成特定功能而编写. 变量和函数的灵活性也增加了代码的复杂性.
所以bash脚本就是不断的执行预定的命令. 不用你在控制台下手敲了. 常在bash下工作的人, 用脚本编程简化维护等工作也是很自然的了.