我有一堆 ksh 和 csh 脚本需要更新才能在不同的 *nix 风格(red hat linux、hp ux、solaris)中运行。 shell 安装在我们每台服务器的本地,我们需要让它们在每个环境中工作。
我们遇到了一些在 Linux 下找不到的特定命令的问题。例如脚本使用nawk
,在 linux 上应替换为gawk
。
脚本也使用,/usr/xpg4/bin/grep
因为在Solaris上grep
不能采用-q(安静)选项,但Linux的grep可以,并且在这个环境中/usr/xpg4/bin/grep
不存在。
我不想接触每个脚本,所以我正在寻找更全局的解决方案。
我尝试过设置别名,有效。但仅限于交互模式。看起来不建议在脚本中使用别名......
我可以在系统目录中添加符号链接,但随后我需要管理员权限来管理这个“模拟”设置,并且我们的设置不再可移植......
我不习惯系统管理,所以我可能会错过满足这种需求的标准解决方案。
我该怎么做才能拥有可移植脚本而不需要重写它们?
答案1
正确的方法是坚持使用POSIX
兼容的命令(即使用awk
、 notnawk
或gawk
、grep
、 not )、选项和语法,并这样/usr/xpg4/bin/grep
设置:PATH
PATH=$(getconf PATH):$PATH
或者在 Solaris 上(如果使用旧版 Bourne shell):
PATH=`getconf PATH`:$PATH
就是这样,您在那里启动的脚本应该不加修改地运行。不过,请避免使用#!/bin/sh
shebang,尽管人们普遍认为这是不是 POSIX
符合。根本不使用shebang。您可能会使用command -v sh
,看看POSIX
您的机器上有什么 shell 可用。
但是,您似乎希望保持不可移植脚本不变。然后,您可以保留之前建议的使用语法的命令方法POSIX
,并添加一个前端以便在其他操作系统上处理非可移植命令。由于您的脚本使用 Bourne 或 Csh 风格的 shell,因此别名和函数不可移植,因此最好使用您自己的包装脚本库,将其放在PATH
.例如:
sh / ksh / bash / ...:
PATH=~/bin:`getconf PATH`:$PATH
命令行:
set path = ( ~/bin `getconf PATH` $path)
-
mkdir -p ~/bin
cd ~/bin
cat > awk <<%
#!/bin/sh
PATH=`getconf PATH`:$PATH awk "$@"
%
ln -s awk nawk
ln -s awk gawk
答案2
在这种情况下我使用变量
AWK=awk
GREP=grep
然后测试操作系统
if [ $(uname -s) == "SunOS" ]
then
AWK=/usr/bin/nawk
GREP=/usr/xpg4/bin/grep
fi
(对于 redhat、suse、hp-ux、aix 重复此操作)
并在之后使用变量
if $GREP -q whatever /some/file
then
$AWK -F: '{....}' /some/file
fi
这样我只有一个脚本,但可以在所有主机中使用。