Solaris(64 位)开发者指南

Shell 脚本包装

在需要使用特定于 32 位和 64 位的应用程序版本的情况下,可以借助 shell 脚本包装使版本对于用户保持透明。如果 Solaris 操作环境中有许多工具需要使用 32 位和 64 位版本,则可以这样做。包装可以使用 isalist 命令来确定可在特定硬件平台上执行的本机指令集,并基于指令集来运行适当版本的工具。

以下是本机指令集包装的一个示例:

#! /bin/sh 

 

CMD=`basename $0`

DIR=`dirname $0`

EXEC=

for isa in `/usr/bin/isalist`; do	

	if [-x ${DIR}/${isa}/${CMD}]; then		

		EXEC=${DIR}/${isa}/${CMD}

		break	

	fi

done

if [-z "${EXEC}"]; then	

		echo 1>&2 "$0: no executable for this architecture"

		exit 1

 

fi

exec ${EXEC} "${@}"

此示例存在一个问题,即它要求 $0 参数是其可执行文件的全路径名。为此,创建了一个常规包装 isaexec(),以便解决特定于 32 位和 64 位应用程序的问题。下面将说明该包装。

/usr/lib/isaexec 二进制文件

isaexec(3C) 是一个 32 位可执行二进制文件,它执行上面刚介绍的 shell 脚本包装中概述的包装函数,但是具有准确完整的参数列表。该可执行文件的全路径名是 /usr/lib/isaexec,但是在执行时并不使用该名称,而是将该名称复制或链接(硬链接而不是软链接)到存在多个版本的程序的主名称,这些版本是通过 isalist(1) 进行选择的。

例如,在 SPARC 环境中,truss(1) 命令作为以下三个可执行文件存在:

/usr/bin/truss

/usr/bin/sparcv7/truss

/usr/bin/sparcv9/truss

sparcv7sparcv9 子目录中的可执行文件分别是实际的 32 位和 64 位 truss(1) 可执行文件。包装文件 /usr/bin/truss 是指向 /usr/lib/isaexec 的硬链接。

在 x86 环境中,truss(1) 命令作为以下三个可执行文件存在:

/usr/bin/truss

/usr/bin/i86/truss

/usr/bin/amd64/truss

isaexec(3C) 包装使用 getexecname(3C) 来确定它自己的经过完全解析的无符号链接路径名(与其 argv[0] 参数无关),sysinfo(SI_ISALIST, ...) 获取 isalist(1),并针对第一个可执行文件执行 exec(2),第一个可执行文件的名称可在为其所在的目录生成的子目录列表中找到。然后,该包装会按原样传递参数向量和环境向量。这样,传递给最后一个程序映像的 argv[0] 将显示为所指定的第一个参数,而不是转换成经修改以包含子目录名称的全路径名。


注 –

因为可能存在包装,所以在将可执行文件移到其他位置时,需要格外小心。您可能会移动包装而不是实际程序。


isaexec(3c) 接口

许多应用程序已经使用启动包装程序来设置环境变量、清除临时文件、启动守护进程等。 libc(3LIB) 中的 isaexec(3C) 接口允许直接从自定义包装程序调用以上基于 shell 的包装示例中所使用的算法。