在多个 UNIX 环境中处理 PATH 的最佳/传统方法

发布于 2024-09-27 02:26:50 字数 1070 浏览 4 评论 0原文

这里的主要问题是:是否有一种编写可在多个 UNIX 平台上运行的 UNIX shell 脚本的标准方法。

例如,我们有许多主机运行不同风格的 UNIX(Solaris、Linux),并且不同版本的文件系统布局都略有不同。有些主机的 whoami 位于 /usr/local/gnu/bin/ 中,有些主机位于 /usr/bin/ 中。

我们所有的脚本似乎都以稍微不同的方式处理这个问题。有些在架构上有 case 语句:

case "`/script/that/determines/arch`" in 
  sunos-*) WHOAMI=`/usr/local/gnu/bin/whoami` ;;
  *)       WHOAMI=`/usr/bin/whoami` ;;
esac

通过这种方法,您可以确切地知道正在执行什么二进制文件,但如果正在执行大量命令,则非常麻烦。

有些只是设置 PATH (基于上面的 arch 脚本)并仅通过名称调用命令。这很方便,但是您失去了对运行哪个命令的控制,例如,如果您有:

/bin/foo
/bin/bar
/other/bin/foo
/other/bin/bar

您将无法同时使用 /bin/foo/other/bin/bar< /代码>。

我能想到的另一种方法是在每个主机上有一个本地目录,其中包含每个主机上所需的每个二进制文件的符号链接。例如:

Solaris 主机:

/local-bin/whoami -> /usr/local/gnu/bin/whoami
/local-bin/ps -> /usr/ucb/ps

Linux 主机:

/local-bin/whoami -> /usr/bin/whoami
/local-bin/ps -> /usr/ps

人们还使用哪些其他方法?请不要只说用 Python 编写脚本...在某些任务中,bash 是完成简单任务的最简洁、最实用的方法。

The main question here is: is there a standard method of writing UNIX shell scripts that will run on multiple UNIX platforms.

For example, we have many hosts running different flavours of UNIX (Solaris, Linux) and at different versions all with slightly different file system layouts. Some hosts have whoami in /usr/local/gnu/bin/, and some in /usr/bin/.

All of our scripts seem to deal with this in a slightly different way. Some have case statements on the architecture:

case "`/script/that/determines/arch`" in 
  sunos-*) WHOAMI=`/usr/local/gnu/bin/whoami` ;;
  *)       WHOAMI=`/usr/bin/whoami` ;;
esac

With this approach you know exactly what binary is being executed, but it's pretty cumbersome if there are lots of commands being executed.

Some just set the PATH (based on the arch script above) and call commands by just their name. This is convenient, but you lose control over which command you run, e.g. if you have:

/bin/foo
/bin/bar
/other/bin/foo
/other/bin/bar

You wouldn't be able to use both /bin/foo and /other/bin/bar.

Another approach I could think of would to have a local directory on each host with symlinks to each binary that would be needed on each host. E.g.:

Solaris host:

/local-bin/whoami -> /usr/local/gnu/bin/whoami
/local-bin/ps -> /usr/ucb/ps

Linux host:

/local-bin/whoami -> /usr/bin/whoami
/local-bin/ps -> /usr/ps

What other approaches do people use? Please don't just say write the script in Python... there are some tasks where bash is the most succinct and practical means of getting a simple task accomplished.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦初启 2024-10-04 02:26:50

我将所有这些委托给我的 .profile,它具有一系列精心设计的内部函数,可以尝试将可能的目录添加到 PATH 中。除了在 OSX 上,我认为这基本上是不可能的,因为 Darwin/Fink/Ports 都想控制你的 PATH,这种方法效果很好。

如果我关心歧义性(PATH 上不同目录中的多个 foo 实例),我会修改函数以识别所有歧义命令并需要手动解决。但对于我的环境来说,这从来都不是问题。我主要关心的是是否有一个可以在 Debian、Red Hat、Solaris、BSD 等上运行的 .profile。 “尝试每个可能有效的目录”方法效果很好。

I delegate all this to my .profile, which has an elaborate series of internal functions to try likely directories to add to the PATH. Except on OSX, which I believe is basically impossible because Darwin/Fink/Ports each wants to control your PATH, this approach works well enough.

If I cared about ambiguity (multiple instances of foo in different directories on my PATH), I would modify the functions so as to identify all ambiguous commands and require manual resolution. But for my environment, this has never been an issue. My main concern has been to have a single .profile that runs on Debian, Red Hat, Solaris, BSD, and so on. The 'try every directory that could possibly work' approach works well enough.

云醉月微眠 2024-10-04 02:26:50

要将 PATH 设置为 POSIX 兼容目录,您可以在 Bash 脚本的开头执行以下操作:

unset PATH
PATH="$(PATH=/bin:/usr/bin getconf PATH)"
export PATH

如果您知道可以在不同的 Unix 系统上使用 Bash,则可以使用 shell 内置命令而不是外部命令来提高可移植性。示例:

help type
type -a type

type -P ls  # replaces: which ls

要在 Bash 中禁用 find、ls、... 等命令的别名/函数查找,您可以使用内置命令。示例:

help command

command ls -l

如果您想 100% 确保执行位于特定目录中的特定命令,那么使用完整的可执行路径似乎是可行的方法。路径查找中的第一场比赛获胜!

To set PATH to POSIX-compliant directories you can do the following at the beginning of your Bash scripts:

unset PATH
PATH="$(PATH=/bin:/usr/bin getconf PATH)"
export PATH

If you know you can use Bash across different Unix systems, you may use shell builtins instead of external commands to improve portability as well. Example:

help type
type -a type

type -P ls  # replaces: which ls

To disable alias / function lookup for commands such as find, ls, ... in Bash you may use the command builtin. Example:

help command

command ls -l

If you want to be 100% sure to execute a specific command located in a specific directory, using the full executable path seems the way to go. First match wins in PATH lookup!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文