本节将重点分析commands部分的用例。

Command主要用例

主要case包括:

case 包含子case
ade ar file ld ldd nm objdump size
at at
cpio cpio
cron cron
df df
du du
eject eject
fileutils cp ln mkdir mv
gzip gzip
insmod insmod
logrotate logrotate
lsmod lsmod
mail mail
mkfs mkfs
mkswap mkswap
sssd sssd
su su
tar tar
tpm-tools tmp tpmtoken
unzip unzip
wc wc
which which

ade

ade包括对ar、file、ld、ldd、nm、objdump、size命令的验证测试。

ar

ar命令是Linux的一个备份压缩命令,可以创建、修改备存文件(archive),或从备存文件中抽取成员文件。备存文件以一定的结构打包一个至多个其它文件(即成员文件),且成员文件的内容、模式、时间戳等信息将被保存在备存文件中。常见的应用是,使用ar命令将多个目标文件(.o)打包为静态链接库文件(.a)。

引出一个问题,库是什么?本质上讲库是一种可执行代码的二进制形式,可以被操作系统加载到内存执行。linux库分为两种:静态库和动态库。区别在于,静态库是在编译过程中已经被载入可执行程序,可执行程序一般较大;共享库(动态库)是可执行程序运行时才加载到内存,编译时仅简单的引用,因此可执行程序较小。库是如何产生的呢?静态库的后缀是.a,它的产生分为两步:1.由源码编译生成一堆.o,每个.o包含这个编译单元的符号表;2.ar命令将很多.o文件打包转换为.a,形成静态库。

ar命令的常用参数

在 ar 命令中,可以从集 cClosTv 中指定任何数量的可选标志。必须从标志集 dhmopqrstwx 中指定一个标志。如果选择-m 或 -r 标志,您可能还要指定一个位置标志(-a 、-b 或-i );对于 -a 、-b 或-i 标志,您必须还指定在 ArchiveFile (PositionName )中一个文件的名称,此名称紧跟在标志列表后,并由空格隔开。

-a PositionName 在 PositionName 参数标识的现有文件后安置指定的文件。
-b PositionName 在 PositionName 参数标识的现有文件前安置指定的文件。
-c  禁止在创建库 时产生的正常消息。 
-C  阻止解压缩的文件替换文件系统中同名的文件。
-d  从库中删除指定的文件。
-g  对压缩文档成员进行排序以确保用最小数量的未用空间获得最大的加载效率。在几乎所有情况下,-g 标志以压缩文档成员的逻辑链接顺序物理地安置它们。最终生成的压缩文档通常写成小格式,这样该标志可用来将大格式压缩文档转换成小格式压缩文档。包含 64 位XCOFF 对象的压缩文档不能创建成或转换至小格式。
-h  将指定的文件的成员报头中的修改时间设置为当前日期和时间。如果不指定任何文件名称,则 ar 命令设置所有成员报头的时间戳记。此标志不能和-z 标志一起使用。
-i PositionName 在 PositionName 参数标识的现有文件前安置指定的文件(和 -b 相同)。
-l  将临时文件置于当前(本地)目录中,而非 TMPDIR 目录中(缺省为 /tmp )。
-m  将指定的文件移动到库中的某个其它位置。缺省情况下,它将指定的文件移动到库的末尾。使用位置标志(abi )来指定某个其它位置。
-o  对压缩文档成员进行排序以确保用最小数量的未用空间获得最大的加载效率。在几乎所有情况下,-o 标志以压缩文档成员的逻辑链接顺序物理地安置它们。最终生成的压缩文档通常写成大格式,这样该标志可用来将小格式压缩文档转换成大格式压缩文档。
-p  将 Files 参数中指定的文件的内容或在 ArchiveFile 参数中指定的所有文件(如果您不指定任何文件)都写至标准输出。
-q  将指定的文件添加到库的末尾。另外,如果指定同一个文件两次,它可能被放入库中两次。
-r  如果指定的文件已经存在于库中,则替换它。因为指定的文件在库中占据它们替换的文件的同一个位置,位置标志没有任何附加的影响。当和 -u 标志(更新)一起使用时,-r 标志仅替换自从最后一次添加到库中以后修改的文件。
如果指定的文件不存在于库中,则 ar 命令添加它。在这种情况下,位置标志影响放置。如果不指定位置,则将新文件置于库的末尾。如果指定同一个文件两次,它可能被放入库中两次。

-s  无论 ar 命令是否修改了库内容都强制重新生成库符号表。请在库上使用 strip 命令之后,使用此标志来恢复库符号表。
-t  将库的目录写至标准输出。如果指定文件名称,则仅显示指定的那些文件。如果不指定任何文件,-t 标志列出库中的所有文件。
-T  如果压缩文档成员名称比文件系统支持的长,则允许文件名称截短。此选项无效,因为文件系统支持的名称长度等于 255 个字符的最大压缩文档成员名称。
-u  仅复制自它们最后一次复制起更改的文件(请参阅先前讨论过的 -r 标志)。
-v  将建立新库的详细的逐个文件的描述写至标准输出。当和 -t 标志一起使用时,它给出类似于 ls -l 命令给出的长列表。当和 -x 标志一起使用时,它在每个文件前加一个名称。当和 -h 标志一起使用,它列出成员名称和更新的修改时间。
-w  显示压缩文档符号表。每个符号和其中定义此符号的文件的名称一起列出。
-x  通过将指定的文件复制到当前目录来解压缩它们。这些副本和原始文件(保留在库中)具有相同的名称。如果不指定任何文件,-x 标志复制库中的所有文件。此过程不会更改库。
-Xmode  指定 ar 应检查的目标文件的类型。mode 必须是以下项之一:
32
仅处理 32 位目标文件
64
仅处理 64 位目标文件
32_64
处理 32 位 和 64 位目标文件
缺省值是处理 32 位目标文件(忽略 64 位对象)。mode 还可以用 OBJECT_MODE 环境变量来设置。例如,OBJECT_MODE=64 使 ar 处理任何 64 位对象并忽略 32 位对象。-X 标志覆盖 OBJECT_MODE 变量。
-z  创建压缩文档的临时副本并对副本执行所有要求的修改。当所有操作成功完成时,压缩文档的工作副本覆盖原始副本。此标志不能和 -h 标志一起使用。
ArchiveFile 指定压缩文档文件名称;必需。
MemberName ...  各压缩文档成员的名称。

示例1.ar rcs libxxxx.a xx1.o xx2.o

参数r: 在库中插入模块(替换)。当插入的模块名已经在库中存在,则替换同名的模块。如果若干模块中有一个模块在库中不存在,ar显示一个错误消息,并不替换其他同名模块。默认的情况下,新的成员增加在库的结尾处,可以使用其他任选项来改变增加的位置。

参数c: 创建一个库。不管库是否存在,都将创建。

参数s: 创建目标文件索引 这在创建较大的库时能加快时间。(补充:如果不需要创建索引,可改成大写S参数;如果。a文件缺少索引,可以使用ranlib命令添加)

示例2.创建一个库

ar -v -q lib.a strlen.o strcpy.o

如果 lib.a 库不存在,则此命令创建它,并将文件 strlen.o 和 strcpy.o 的副本输入其中。如果 lib.a 库存在,则此命令在不检查相同成员的情况下,将新的成员添加到末尾。v 标志设置详细方式,在此方式中ar 命令在其进行时显示进程报告。

示例3.显示库的目录

ar -v -t lib.a

此命令列出了 lib.a 库的目录,显示类似于 ls -l 命令的输出的长列表。要只列出成员文件名称,则省略-v 标志。

示例4. 替换或添加新成员到库中

ar -v -r lib.a strlen.o strcat.o

此命令替换成员 strlen.o 和 strcat.o 。如果 lib.a 如示例 1 中显示的那样创建,则替换strlen.o 成员。因为不存在名为 strcat.o 的成员,所以它被添加到库的末尾。

示例5. 指定在何处插入新成员

ar -v -r -b strlen.o lib.a strcmp.o

此命令添加 strcmp.o 文件,并将该新成员置于 strlen.o 成员之前。

示例6.要更新一个已经更改过的成员

ar -v -r -u lib.a strcpy.o

此命令替换现有 strcpy.o 成员,但仅当文件 strcpy.o 自从最后一次添加到库后已经修改时才替换它。

示例7 要更改库成员的顺序

ar -v -m -a strcmp.o lib.a strcat.o strcpy.o

此命令将成员 strcat.o 和 strcpy.o 移动到紧跟在 strcmp.o 成员之后的位置。保留 strcat.o 和 strcpy.o 成员的相对顺序。换句话说,如果在移动之前strcpy.o 成员在 strcat.o 成员之前,那么(移动后)它依旧如此。

示例8 要解压缩库成员

ar -v -x lib.a strcat.o strcpy.o

此命令将成员 strcat.o 和 strcpy.o 分别复制到名为 strcat.o 和 strcpy.o 的文件。

示例9 要解压缩并重命名一个成员

ar -p lib.a strcpy.o >stringcopy.o
此命令将成员 strcpy.o 复制到一个名为 stringcopy.o 的文件。

示例10 要删除一个成员

ar -v -d lib.a strlen.o

此命令从 lib.a 库中删除成员 strlen.o 。

示例11 要从多个用 ld 命令创建的共享模块中创建一个压缩文档库

ar -r -v libshr.a shrsub.o shrsub2.o shrsub3.o ...

此命令从名为 shrsub.o 、shrsub2.o 、shrsub3.o 等等的共享模块中创建名为libshr.a 的压缩文档库。要编译并链接使用 libshr.a 压缩文档库的 main 程序,请使用以下命令:

cc -o main main.c -L/u/sharedlib -lshr
main 程序现在是可执行的。main 程序引用的任何符号(包含在libshr.a 压缩文档库中)已经因延迟分辨率而作了标记。-l 标志指定应在libshr.a 库中搜索这些符号。

示例12 要列出 lib.a 的内容(忽略任何 32 位目标文件)

ar -X64 -t -v lib.a
要从 lib.a 解压缩所有 32 位的目标文件
ar -X32 -x lib.a
要列出 lib.a 中的所有文件,无论是 32 位、64 位或非对象,请输入:
ar -X32_64 -t -v lib.a

示例13 在shell脚本中使用    Bash代码 OS=uname -r ar rcs libhycu.a.$OS *.o

示例14 在makefile中使用

Makefile代码
$(BIN1): $(BIN1_OBJS)
ar rcs $@ $^

示例15 创建并使用静态库

第一步:编辑源文件,test.h test.c main.c。其中main.c文件中包含main函数,作为程序入口;test.c中包含main函数中需要用到的函数。

vi test.h test.c main.c

第二步:将test.c编译成目标文件。

gcc -c test.c
如果test.c无误,就会得到test.o这个目标文件。

第三步:由。o文件创建静态库。

ar rcs libtest.a test.o

第四步:在程序中使用静态库。

gcc -o main main.c -L. -ltest
因为是静态编译,生成的执行文件可以独立于。a文件运行。

第五步:执行。

./main

示例16 创建并使用动态库    第一步:编辑源文件,test.h test.c main.c。其中main.c文件中包含main函数,作为程序入口;test.c中包含main函数中需要用到的函数。

vi test.h test.c main.c

第二步:将test.c编译成目标文件。

gcc -c test.c
前面两步与创建静态库一致。

第三步:由。o文件创建动态库文件。

gcc -shared -fPIC -o libtest.so test.o

第四步:在程序中使用动态库。

gcc -o main main.c -L. -ltest
当静态库和动态库同名时,gcc命令将优先使用动态库。

第五步:执行。

LD_LIBRARY_PATH=. ./main

接下来,看一下ltp是如何测试ar命令的。

ar文件下包括:

ar01 file0.in file10.in file1.in file2.in file3.in file4.in file5.in file6.in file7.in file8.in file9.in Makefile等文件,其中ar01是shell编写的测试脚本。 测试目的,测试ar命令的不同选项的功能。测试策略,通过比较单独指定参数和组合参数测试结果进行判断,如果相同测试通过,如果不同,测试失败。

ar测试项的参数为: export TCdat=$LTPROOT/testcases/bin; ar01 直接执行ar01即可。

测试条件,系统存在ar命令。在运行config时,会进行check:如 

configure:4165: checking for ar
configure:4181: found /bin/ar
configure:4192: result: ar

程序分析:

创建用到的临时文件

LIST="file1.in file2.in file3.in file4.in file5.in file6.in file7.in file8.in file9.in file10.in"
LIST="$LIST $LIST $LIST $LIST $LIST $LIST $LIST $LIST $LIST $LIST"

#Setup function

setup(){
    for i in $LIST;do
        touch $i
    done
}

结果判定,判断子case的返回值是否为0,TCRESULT为标志位,初始值为0,出错TCRESULT置为1,不同测试内容分别返回不同的编号。

#Cleanup funciton
cleanup(){
    if [ $TCRESULT = 0 ];then
        echo "-----------ar command passed the system test --------"
        exit 0
    else
        echo "-----------ar command failed the system test --------"
        exit 1
    fi
}

crtest() {
    if [ $? -ne 0]
    then
        TCRESULT=1
        echo "FAIL - could not create lib.a"
        cleanup
    fi
    }

ttest() {
if [ $? -ne 0 ]
then
    TCRESULT=1
    echo "FAIL - could not output table from lib.a to lib.a.stdout"
    cleanup
fi
}

rtest() {
    if [ $? -ne 0 ]
    then
        TCRESULT=1
        echo "FAIL - could not add file into lib.a"
        cleanup
    fi
}

mtest() {
    if [ $? -ne 0 ]
    then
        TCRESULT=1
        echo "FAIL - could not move file into lib.a"
        cleanup
    fi
}

通过结果判定的设置来看,主要验证ar命令的库的创建、库列表信息导出、往库中添加文件、移除库中的文件。

测试代码片段:

标志“a":在 PositionName 参数标识的现有文件后安置指定的文件。

ar -cr $TCtmp/lib.a file1.in file3.in
crtest

ar -ra file1.in $TCtmp/lib.a file2.in
rtest

ar -t $TCtmp/lib.a > $TCtmp/lib.a.stdout
tttest

if diff -b $TCtmp/lib.a.exp $TCtmp/lib.a.stdout > /dev/null 2>&1
then
    echo "-)1"
else
    TCRESULT=1
    echo "FAIL -ar with -a option does not place file after "posname"
fi

具体测试内容列表:

(1)The 'a' flag causes files to be placed after 'posname'.

(2)The 'a' flag with the 'm' option causes files to be moved after 'posname'

(3)The 'b' flag causes files to be placed before 'posname'.

(4)The 'b' flag with 'm' option causes files to be moved before 'posname'.

(5)-c option suppress the messages

(6)The 'qc' option causes suppresion of the default message when 'afile' is created

(7)The -d option deletes files from archive when names are specified.

(8)The -d option does not delete files from archive when no names are specified.

(9)The -d does not affect behaviour of -s option.

(10)The 'i' flag causes files to be placed before 'posname'.

(11) The 'i' flag with 'm' option causes files to be moved before 'posname'.

(12) m option moves the files to end of the archive

(13) The -p option causes only printing of contents of file contained in archive.

(14) The -p does not affect behaviour of -s option.

(15) The command 'ar -q afile name' appends name to the end of 'afile'.

(16) q option does not affect the behaviour of option s

(17) The -s causes regeneration of symbol table even if a symbol table exists.

(18) ar with -t print as desired

(19) The -t does not affect behaviour of -s option.

(20)The 'u' flag causes files only with later modification date than in archive are replaced.

(21) ar with -v flag to print a line for each file

(22) The -v option produces a verbose listing like ls -n

(23) The 'v' option causes the 'x' option to display a filename for each file extracted.

(24) The command 'ar -x afile ' causes all files from the archive to be extracted.

(25) The command 'ar -x afile name name' causes only named files from the archive to be extracted.

(26) This test will fail under pan, so it's commented out by default.

(27) Signal SIGHUP

(28) Signal SIGQUIT

(29) Signal SIGHUP; ar should not remove archive that existed before invocation.

(30) Signal SIGINIT; ar should not remove archive that existed before invocation.

(31) Signal SIGQUIT; ar should not remove archive that existed before invocation.

by 李鹏