How to call bash(not shell) from ruby
Serhii Potapov September 21, 2013 #ruby #bash #shellFew days ago I was writing a ruby wrapper for SoX command line tool. To reduce disk IO I wanted to use process substitution. It's a cool shell feature which allows to use command output as an input file for another command. It's pretty useful if the second command doesn't work with standard input or you need to pass more than 1 input.
Let me show the classic example(works in bash and zsh):
# => Saluton! Kiel vi fartas?
So statement <(echo 'Saluton!')
is treated like a file which contains line Saluton!
.
Underhood bash(zsh) creates a named pipeline where output of echo 'Saluton!'
is written.
Then the named pipeline is passed to cat
command.
You can see it:
# => /dev/fd/63
So I wanted to use it in ruby:
cmd =
system(cmd)
But unfortunately it doesn't work:
sh: 1: Syntax error: "(" unexpected
The problem is that ruby's system
method and back quotes usesh
not your current shell (which in my case is bash
).
system
# => sh
In shells $0
points to the current script or to interpreter if you're running it interactively.
Fortunately there is a way to create a workaround to run bash:
= Shellwords.escape(command)
system
end
escaped_command
Bash has option -c
which takes bash script to execute.
Shellwords
is a standard ruby library which provides a method to escape shell commands.
So now it works as we want it to be:
bash() # => bash
cmd =
bash(cmd) # => Saluton! Kiel vi fartas?
Thanks for reading!