将环境变量传递给exec shell命令的正确方法

Kow*_*hik 23 ruby

我正在使用ruby 1.8.7补丁249.以下是将环境变量传递给我需要从我的ruby程序执行的shell命令的最佳/唯一方法吗?

fork do       
   ENV['A'] = 'A'
   exec "/bin/bash -c 'echo $A'"
end

Process.wait
Run Code Online (Sandbox Code Playgroud)

Joh*_*rug 31

有一个非常简单的方法:

system({"MYVAR" => "42"}, "echo $MYVAR")
Run Code Online (Sandbox Code Playgroud)

所有这些都归功于Avdi:https://stackoverflow.com/a/8301399/171933

  • 值得注意的是,`popen3`具有与控制stdin,stdout,stderr相同的行为,请参见[https://ruby-doc.org/stdlib-2.4.0/libdoc/open3/rdoc/Open3.html#method- c-popen3](https://ruby-doc.org/stdlib-2.4.0/libdoc/open3/rdoc/Open3.html#method-c-popen3) (2认同)
  • 代码是 `system({ "DENO_BUILD_MODE" => "release" }, "python", "tools/test.py")`,它是用于 [homebrew-core](https://github.com/Homebrew/homebrew -core/pull/35645/commits/f842d1d31caf59975295662da45c9c1a1776b457)。我想知道他们是否会覆盖“系统”? (2认同)

Dav*_*son 12

Ruby exec方法文档似乎不完整,但它确实说有一个可选的第一个参数被调用env,所以可能是指定了环境.通过有根据的猜测和一些实验,我发现使用它的正确方法是这样的:

exec({"A"=>"A"}, "/bin/bash -c 'echo $A'")
Run Code Online (Sandbox Code Playgroud)

编辑1:对不起,不适用于旧版本的Ruby.

  • 我还想提一下,如果你只是试图运行一个程序并且不需要任何花哨的shell功能,你就不需要涉及`bash`.例如,`exec({},"ls")`工作正常,应该快一点,因为我们没有启动bash. (2认同)
  • 但是,`exec`用被调用的进程替换当前进程.有没有办法可以像`system`这样的命令做类似的事情? (2认同)

小智 1

我会用一行来做

exec "/bin/bash -c 'A=hello; echo $A'"
Run Code Online (Sandbox Code Playgroud)

  • 我更喜欢我的方式,因为这样你就不必担心转义分号、单引号以及 bash 会以特殊方式解释的任何其他内容。 (2认同)