Ame*_*ina 21 shell cron zsh path
我有一个脚本,希望能够在两台机器上运行。这两台机器从同一个 git 存储库中获取脚本的副本。脚本需要使用正确的解释器(例如zsh)运行。
不幸的是,这两个 env和zsh住在本地和远程计算机不同的位置:
$ which env
/bin/env
$ which zsh
/some/long/path/to/the/right/zsh
Run Code Online (Sandbox Code Playgroud)
$ which env
/usr/bin/env
$which zsh
/usr/local/bin/zsh
Run Code Online (Sandbox Code Playgroud)
如何设置shebang以便像/path/to/script.sh往常一样运行脚本使用Zsh可用的PATH?
And*_*ese 22
你不能直接通过 shebang 解决这个问题,因为 shebang 是纯静态的。如果这个 LCM 不是 zsh,你可以做的是在 shebang 中有一些“最不常见的乘数”(从 shell 的角度来看),然后用正确的 shell 重新执行你的脚本。换句话说:让您的脚本由在所有系统上找到的 shell 执行,测试一个zsh-only 功能,如果测试结果为 false,则让脚本exec带有zsh,测试将成功,您只需继续。
zsh例如, 中的一个独特特征是$ZSH_VERSION变量的存在:
#!/bin/sh -
[ -z "$ZSH_VERSION" ] && exec zsh - "$0" ${1+"$@"}
# zsh-specific stuff following here
echo "$ZSH_VERSION"
Run Code Online (Sandbox Code Playgroud)
在这个简单的例子中,脚本首先由/bin/sh(所有 80 年代后类 Unix 系统都理解#!并有一个/bin/sh,Bourne 或 POSIX 但我们的语法兼容两者)。如果$ZSH_VERSION是没有设置,脚本exec的本身通过zsh。如果$ZSH_VERSION设置了(相应的脚本已经运行zsh),则简单地跳过测试。瞧。
这只会在zsh根本不存在的$PATH情况下失败。
编辑:要确保,你只有exec一个zsh在平时的地方,你可以使用类似
for sh in /bin/zsh \
/usr/bin/zsh \
/usr/local/bin/zsh; do
[ -x "$sh" ] && exec "$sh" - "$0" ${1+"$@"}
done
Run Code Online (Sandbox Code Playgroud)
这可以避免您意外地exec在您的东西中出现$PATH不是zsh您所期望的东西。
多年来,我一直使用类似的方法来处理需要运行脚本的系统上 Bash 的不同位置。
#!/bin/sh
# Determines which OS and then reruns this script with approp. shell interp.
LIN_BASH="/bin/sh";
SOL_BASH="/packages/utilities/bin/sun5/bash";
OS_TYPE=`uname -s`;
if [ $OS_TYPE = "SunOS" ]; then
$SOL_BASH -c "`sed -n '/\#\#\# BEGIN/,$p' $0`" $0 $*;
elif [ $OS_TYPE = "Linux" ]; then
$LIN_BASH -c "`sed -n '/\#\#\# BEGIN/,$p' $0`" $0 $*;
else
echo "UNKNOWN OS_TYPE, $OS_TYPE";
exit 1;
fi
exit 0;
### BEGIN
...script goes here...
Run Code Online (Sandbox Code Playgroud)
以上可以很容易地适应各种口译员。关键是这个脚本最初作为 Bourne shell 运行。然后它再次递归调用自己,但### BEGIN使用sed.
这是 Perl 的类似技巧:
#!/bin/sh
LIN_PERL="/usr/bin/perl";
SOL_PERL="/packages/perl/bin/perl";
OS_TYPE=`uname -s`;
if [ $OS_TYPE = "SunOS" ]; then
eval 'exec $SOL_PERL -x -S $0 ${1+"$@"}';
elif [ $OS_TYPE = "Linux" ]; then
eval 'exec $LIN_PERL -x -S $0 ${1+"$@"}';
else
echo "$OS_TYPE: UNSUPORRTED OS/PLATFORM";
exit 0;
fi
exit 0;
#!perl
...perl script goes here...
Run Code Online (Sandbox Code Playgroud)
该方法利用 Perl 的能力,当给定一个文件运行时,将跳过该行之前的所有行来解析所述文件#! perl。
| 归档时间: |
|
| 查看次数: |
2305 次 |
| 最近记录: |