Executing shell command from ruby using the same s

2019-08-16 01:17发布

问题:

In Ruby, is there a way to execute multiple shell commands forcing them to use the same shell process?

For example, something that would make `` (or system or popen) to behave like:

$ irb
> `echo $$`
=> "999\n" 
> `echo $$`
=> "999\n" 

回答1:

IO.popen

With IO.popen you can spawn a new process and use its stdin and stdout. The "r+" in this example is the access mode which is here read and write. Both echos will be interpreted by the same bash and will therefore yield the same process id.

IO.popen("/bin/sh", "r+") do |p|
    p.puts("echo $$")
    puts p.readline
    p.puts("echo $$")
    puts p.readline
    p.puts("exit")
end

Limitations

If you start a program inside this bash, you can not tell from reading stdout weather the program terminated or not. Especially if the started program simulates the bash prompt it can fool you into thinking it terminated. To distinguish such a program from your bash, you need to retrieve the process tree from the kernel. Reading this process tree is much more involved than the above code snippet.

exec

But be aware, if you execute programs inside this bash, they won't have the same pid, since the bash spawns a new process for each executed process. The only way in unix to start a new program is doing exec. With exec the instance of the new program has the same pid as the old. But the old program instance does not exist any more and therefore never regains control, after doing exec. To have the same id for two program instances you therefore need to tell the first program to exec into the second. This may work with self written or modified programs, but most programs do not contain such a feature.



回答2:

Would this work for you?

system "echo $$; echo $$" # => 5009
                               5009


标签: ruby shell