John Bachir
John Bachir

Reputation: 22711

Why is Open3.popen3 wrapping my command in `sh -c` on linux but not on macos?

This code

Open3.popen3('mydir/myscript')

is being wrapped in sh -c on linux, but not on macos. Why?

ruby 3.3

Upvotes: 0

Views: 43

Answers (1)

Amadan
Amadan

Reputation: 198294

I cannot replicate your results.


The rules for when Ruby is using the shell or not are precised in the documentation:

The single required argument is one of the following:

  • command_line if it is a string, and if it begins with a shell reserved word or special built-in, or if it contains one or more metacharacters.
  • exe_path otherwise.

It is impossible to answer further without knowing more about what exactly mydir/myscript is, and whether it triggers the condition equally on both systems.


However, it is easy to show that in the general case, the scenario you describe is not happening (or at least, I have been unable to elicit it). Using the following to test:

In test.rb:

#!/usr/bin/env ruby

require 'open3'

i, o, e, t = Open3.popen3('./test.sh')
puts o.read

In test.sh:

#!/bin/bash

echo -n "  PID: "
ps -o command= -p $$
echo -n " PPID: "
ps -o command= -p $PPID
pppid=$(ps -o ppid= -p $PPID)
echo -n "PPPID: "
ps -o command= -p $pppid

Output of ruby test.rb on OSX (in bash):

  PID: /bin/bash ./test.sh
 PPID: ruby test.rb
PPPID: -bash --posix

Output of ruby test.rb on Ubuntu (in bash):

  PID: /bin/bash ./test.sh
 PPID: ruby test.rb
PPPID: -bash

The two outputs only seem to differ in trivial details; I cannot spot an extra process in one that does not exist in the other. In both, Ruby did not use a shell but invoked the executable directly (./test.sh is a string, but it does not begin with a shell reserved word or a built-in, and it contains no metacharacters); then the OS invoked /bin/bash because of the shebang line in the executable.

Upvotes: 1

Related Questions