用脚本可靠地改变$ PATH

时间:2014-03-02 14:44:12

标签: shell sh

我有一个脚本可以改变另一个程序的一些东西,其中一个是用一组不同的标志来调用所述程序。

标志很长,容易出错,而且很难记住,所以我写的这个脚本想要覆盖那个可执行文件,这样当用户调用脚本时,它实际上是调用脚本加上额外复杂的参数。

我知道至少有3种方法可以实现上述目标:

  • 创建别名:alias foo=/usr/bin/foo --compicated-flag ComplexArgument
  • 创建一个函数:

    function foo {
        /usr/bin/foo --compicated-flag ComplexArgument
    }
    
  • 更改$PATH,以便在用户具有以下内容的实际foo之前调用foo文件的非标准位置:

    /usr/bin/foo --compicated-flag ComplexArgument
    

我的问题是我希望用户能够运行一个帮助脚本,用一个命令设置这些脚本。我不想向用户提示第二个操作,例如“现在您需要每次都提供此文件或导出$PATH”。

由于ComplexArgument是以编程方式计算的并且变化很大,因此aliasfunction方法都不起作用(例如,在bashrc或{{ 1}})。同样重要的是要注意,这些更改应该只是临时的,并且用户可能或可能不想设置它。更多理由不应将这些更改添加到RC shell文件中。

因此,我一直拒绝的唯一项目是改变zshrc

我知道要更改环境变量并影响子shell,我需要调用$PATH。类似的东西:

exec

这样 export PATH=/path/to/other/foo:$PATH exec $SHELL 会“粘住”子shell。

除此之外,在某些环境中,它肯定不会。

例如在OSX中,如果安装了HomeBrew,建议您更改$PATH以便$PATH首先出现,以便首先安装HomeBrew库。

如果用户在/usr/local/bin中定义了它:

.zshrc

这意味着无论我的脚本设置什么,ZSH都会读取 PATH=/usr/local/bin:$PATH 文件并首先获得.zshrc

如果我使用ZSH的一个标志来避免读取用户的RC文件,那么其他内容将停止工作,因为/usr/local/bin将不再正确设置而ZSH将始终调用$PATH在某些系统中有这个:

/etc/zshenv

由于更改了# system-wide environment settings for zsh(1) if [ -x /usr/libexec/path_helper ]; then eval `/usr/libexec/path_helper -s` fi 以确保某些路径出现,而不管之前的$PATH是什么,因此情况更糟。

所以我发现两个第一项($PATHalias)不合适,第三项(改变function)不可靠。

我知道必须有一个正确的方法来执行此操作,我了解子shell的限制并在一个脚本上更改内容并使它们保持不变,但是提示用户“使用此文件来更改{{1 }}或$PATH“使这个可靠的唯一方法?

2 个答案:

答案 0 :(得分:0)

第四个选项是复杂函数的包装器。因此,您可以将复杂的脚本从complicated重命名为complicated.orig,然后编写一个新的complicated来计算参数,然后使用新计算的参数执行complicated.orig。这样,您就不会依赖于所有用户都更新其登录配置文件以使用别名或功能,并且脚本的路径将与用户的路径相同。

答案 1 :(得分:0)

在部署软件包中提供帮助脚本是一种非常常见的技术。认为service apache2 restart完全符合您的描述。