为什么我不能在Ruby脚本中访问我的bash提示符?

时间:2016-05-23 22:05:57

标签: ruby bash

.bash_profile我有:

if [ -f $(brew --prefix)/etc/bash_completion ]; then
  source $(brew --prefix)/etc/bash_completion
  GIT_PS1_SHOWDIRTYSTATE=1
  git_prompt='$(__git_ps1)'
fi
export PS1="\[\e[33m\]  \d \t \w$git_prompt\n\[\e[m\]\\$ "
export MYTESTVAR="hello world"

我有一个Ruby脚本foo.rb,其中包含:

`source ~/.bash_profile`
puts `printenv`
puts `echo $PS1`
puts `echo $MYTESTVAR`

当我运行ruby foo.rb时,printenv命令会列出所有环境变量,而$MYTESTVAR行会正确返回hello world

但是,$PS1没有出现。这是为什么?

1 个答案:

答案 0 :(得分:3)

  

$ MYTESTVAR行正确返回hello world。   $ PS1没有出现。

确实,你是对的。大多数变量工作正常,但" PS1"特别是失败了:

$ PS1=ps1 TEST1=test1 ruby -e 'puts `echo $PS1 and $TEST1`'
and test1
  

为什么会这样?

在Ruby中,正如您可能已经意识到的那样,`somestring`在shell中执行somestring,就好像您在C中打开了管道execl("/bin/sh", "-c", somestring, NULL)一样。

在许多系统上,/bin/shbash提供。 Bash在its initialization code中有这个代码段:

  /* Execute the start-up scripts. */

  if (interactive_shell == 0)
    {
      unbind_variable ("PS1");
      unbind_variable ("PS2");
      interactive = 0;

换句话说,它明确地删除了" PS1"和" PS2"因为这些变量仅用于交互式shell。

/bin/bash提供dash的其他系统上,正如许多现代的基于Debian的发行版一样,您可以获得预期的结果:

$ PS1=ps1 TEST1=test1 ruby -e 'puts `echo $PS1 $TEST1`'
ps1 and test1

`source ~/.bash_profile`无法解决此问题的原因是每个`backtick command`都在单独的shell中运行。设置为一的变量不会反映在另一个中。

如果你只想让你的shell导出变量,你应该做@anujm建议的事情并直接用ENV['PS1']来获取它。这不仅更容易,更强大,而且速度也快了一千倍。

如果您想要.bash_profile中设置的变量,无论您如何运行脚本,您都可以在同一个shell中进行采购和打印:

puts `bash -c 'source ~/.bash_profile; printf "%s" "$PS1"'`