【问题标题】:How do you invoke alias from ruby code for zsh shell?如何从 ruby​​ 代码为 zsh shell 调用别名?
【发布时间】:2015-11-14 06:49:40
【问题描述】:

我想从 ruby​​ 代码中调用别名,以便测试我以编程方式插入到点文件中的别名。例如,别名如下:

alias something="echo somethingelse"

我在网上搜索并找到了bash的解决方案:

  #solution for bash
   system %(
     source ~/.bash_profile
     shopt -s expand_aliases
     something
   )

但是,这不适用于 zsh。

我尝试使用以下代码(以及其他命令的组合)调用别名,但无济于事。

  system %(
    exec zsh #this seems to source .zshrc 
    something #this does not work
  )

我希望它也适用于 zsh。我怎样才能让它为 zsh 工作?有人有建议吗?提前致谢!

我还测试了以下内容,但它们不起作用:

  system %(
     # exec /bin/zsh #this causes the subsequent lines to not run. 
     source ~/.zshrc #this causes the error lines to be printed
     # setopt aliases #don't think it helps
     something #trying to invoke this which is already in zshrc   
  )

错误信息:

  • /Users/ytbryan/.zprezto/init.zsh:第 14 行:自动加载:命令不 找到了
  • /Users/ytbryan/.zprezto/init.zsh:第 15 行:打印:命令不是 找到了
  • /Users/ytbryan/.zshrc:第 42 行:`@':不是有效标识符

【问题讨论】:

  • shopt 是内置的 bash,而不是内置的 zsh。在 zsh 中我们使用setopt。尝试用setopt aliases 代替shopt -s expand_aliases。 (当然你需要为 zsh 找到合适的 runco​​m。)
  • 回复exec zsh #this seems to source .zshrc:我对此表示怀疑。 .zshrc 仅用于交互式 shell。我对 Ruby 不是很熟悉,但我真的怀疑 system 调用会启动一个交互式 shell。只需手动来源.zshrc
  • 我刚刚尝试过,Ruby 系统调用中的exec zsh 并不能像您希望的那样工作。它在您当前的 shell 中执行 exec zsh。鉴于此,我认为您可能应该运行zsh -c。请注意,从 zsh -c 运行时别名可能不起作用,但您可以通过访问关联数组 aliases 来强制扩展(并执行分词)。例如,在您的 system 调用中尝试以下命令:zsh -c 'alias foo="echo bar"; ${=aliases[foo]}'(结果为 bar)。另一个带参数的例子:zsh -c 'alias foo=echo; ${=aliases[foo]} $@' -- 1 2 3(结果是1 2 3)。
  • 只是source 你的点文件。我定义了别名,以便您可以在没有任何先决条件的情况下轻松测试此方法,而不是必须的。例如,只需将 alias foo="echo bar" 替换为 source ~/.zshrc
  • 没问题。我会把它变成一个答案。

标签: bash shell alias zsh


【解决方案1】:

一种方法是通过zsh -c 运行 Zsh 代码。从zsh -c 运行时别名不会展开,但内置的aliases 数组仍然可以访问,因此仍然可以通过手动从数组中检索展开并手动执行分词来展开别名。这应该涵盖大多数常见的别名。对于更高级的别名(涉及进程替换、参数扩展、命令替换、算术扩展、大括号扩展、文件名扩展或文件名生成,或者不仅仅是一个简单的命令),可能需要使用eval(但需要在使用 eval 时要非常谨慎,并且当输入来自不受信任的来源或来自受信任但可能经过调整的来源时,切勿使用它。

可嵌入 Ruby system 调用的示例代码:

> zsh -c 'alias foo="print bar"; ${=aliases[foo]}'
bar
> zsh -c 'alias foo=print; ${=aliases[foo]} $@' -- 1 2 3
1 2 3
> zsh -c 'alias foo="print a b c | grep -o a"; ${=aliases[foo]}'  # simple case where naive expansion fails
a b c | grep -o a
> zsh -c 'alias foo="print a b c | grep -o a"; eval "$aliases[foo]"'  # eval comes to rescue, but be extra careful
a

注意sourcezsh -c 中有效,所以上面的别名定义可以来自任何文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-16
    • 2010-09-05
    • 2011-05-06
    • 1970-01-01
    • 1970-01-01
    • 2016-10-21
    相关资源
    最近更新 更多