0

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" 

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

3 Comments

The pipe methods in Open3 would be another option.
Genius! What's the right way to read multiple lines of output? Everything I tried hangs when it reaches the end. Couldn't find a way to check if the output is done
You could use IO#read_nonblock or IO#select to check weather there is more in the pipe available to read. But if there is nothing to read does not mean there won't be more in the future. By only looking at the pipe you can not distuingish wheter the process inside the shell is terminated or takes some time before outputting more.
0

Would this work for you?

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

2 Comments

No. Looking for a way to do this with separate system commands.
@SamerAbukhait: Is it possible for you to expand on your goal a bit?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.