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

标签 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世界

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

最佳答案

$MYTESTVAR line correctly returns hello world. $PS1 does not show up.

的确,你是对的。大多数变量工作正常,但“PS1”尤其失败:

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

Why is this?

在 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/bashdash 提供的其他系统上,正如许多基于 Debian 的现代发行版默认设置的那样,您会得到预期的结果:

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

您的 `source ~/.bash_profile` 没有解决这个问题的原因是每个 `backtick command` 在单独的 shell 中运行。一个中设置的变量不会反射(reflect)在另一个中。

如果您只想要由您的 shell 导出的变量,您应该按照@anujm 的建议并直接使用 ENV['PS1'] 获取它。这不仅更容易、更健壮,而且速度也快了一千倍。

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

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

关于ruby - 为什么我不能在 Ruby 脚本中访问我的 bash 提示符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37401331/

相关文章:

linux - Shell:将带有参数的函数作为函数参数传递

linux - 根据文件名创建目录名

linux - 使 Bash 模块化

bash - 将参数正确传递给 docker 入口点

ruby - 不运行 mongodb 的 mongoid 单元测试

ruby - 我可以阻止 Bundler 将 RUBY VERSION 添加到 Gemfile.lock 吗

ruby-on-rails - 查找表的 Rails 关联

ruby - 插入标签时的 Nokogiri 和 XML 格式化

ruby - 如何编写一个方法来计算 ruby​​ 中字符串中最常见的子字符串?

c - 为什么 bash 在分配时不自动导出 PATH?