# String to array as command line

**URL:** <https://www.ruby-forum.com/t/string-to-array-as-command-line/87327>\
**Category:** Ruby\
**Created:** [March 26, 2006, 6:04pm UTC](https://www.ruby-forum.com/t/string-to-array-as-command-line/87327 "2006-03-26T18:04:44Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 26, 2006, 6:04pm UTC](https://www.ruby-forum.com/t/string-to-array-as-command-line/87327/1 "2006-03-26T18:04:44Z")

</div>

Hello,

I can’t find a function that takes a string as an input, parses it and  
returns an array in the exactly same way as command line is parsed into  
ARGV array variable.  
Could you give me a hint?

Thanks in advance  
Lubos

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 26, 2006, 6:13pm UTC](https://www.ruby-forum.com/t/string-to-array-as-command-line/87327/2 "2006-03-26T18:13:40Z")

</div>

On Mar 26, 2006, at 6:03 PM, removed\_email\_address@domain.invalid wrote:

> Hello,
> 
> I can’t find a function that takes a string as an input, parses it and  
> returns an array in the exactly same way as command line is parsed  
> into  
> ARGV array variable.  
> Could you give me a hint?
> 
> Thanks in advance  
> Lubos

require ‘shellwords’  
args = Shellwords.shellwords(‘foo\ bar “another shellword”’) # =\>  
[“foo bar”, “another shellword”]

– Daniel

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 26, 2006, 6:24pm UTC](https://www.ruby-forum.com/t/string-to-array-as-command-line/87327/3 "2006-03-26T18:24:26Z")

</div>

On Mon, 27 Mar 2006, Daniel H. wrote:

> > Thanks in advance  
> > Lubos
> 
> require ‘shellwords’  
> args = Shellwords.shellwords(‘foo\ bar “another shellword”’) # =\> [“foo bar”,  
> “another shellword”]
> 
> – Daniel

but that will only be similar to sh-like shells. i think a portable way  
to do  
it would be

harp:~ \> cat a.rb  
def command\_line string  
Marshal::load(IO::popen(“ruby -r yaml -e’ print Marshal::dump(ARGV)  
’ #{ string }”){|io| io.read})  
end

p command\_line(’ foo bar foobar ‘)  
p command\_line(’ “foo bar” “foobar” ‘)  
p command\_line(’ foo $bar ‘)  
p command\_line(’ foo “$bar” ')  
p command\_line(" foo ‘$bar’ ")

harp:~ \> ruby a.rb  
[“foo”, “bar”, “foobar”]  
[“foo bar”, “foobar”]  
[“foo”]  
[“foo”, “”]  
[“foo”, “$bar”]

this may be overkill but it should work regardless of the shell in use.

-a

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 26, 2006, 6:44pm UTC](https://www.ruby-forum.com/t/string-to-array-as-command-line/87327/4 "2006-03-26T18:44:01Z")

</div>

Thank you…  
The behavior is not exactly the same (at least on Win) but I think I  
can live with it ;-)…

Lubos

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$  
ARGV.each {|ch|  
puts ch  
}  
puts ‘\*\*\*\*\*\*\*\*’  
args = Shellwords.shellwords(’-v “”\"’)  
args.each {|ch|  
puts ch  
}  
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

> > prog.rb -v “”\" “foo\ bar” “another shellword”  
> > -v  
> > "\

* * *

c:/ruby/lib/ruby/1.8/shellwords.rb:39:in `shellwords': Unmatched double quote: (ArgumentError) from c:/ruby/lib/ruby/1.8/shellwords.rb:35:in`loop’  
from c:/ruby/lib/ruby/1.8/shellwords.rb:35:in `shellwords’

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 26, 2006, 6:54pm UTC](https://www.ruby-forum.com/t/string-to-array-as-command-line/87327/5 "2006-03-26T18:54:47Z")

</div>

The following error raised:

test.rb:503:in `load’: incompatible marshal file format (can’t  
be read) (TypeError) format version 4.8 required; 114.117 given

I use:

> ruby --version  
> ruby 1.8.2 (2004-12-25) [i386-mswin32]

Could this be a problem?

L.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 26, 2006, 7:44pm UTC](https://www.ruby-forum.com/t/string-to-array-as-command-line/87327/6 "2006-03-26T19:44:08Z")

</div>

I have found the problem:  
the correct version is :

def command\_line string  
Marshal::load(IO::popen(“ruby -r yaml -e’ print  
Marshal::dump(ARGV) ’ – #{ string }”){|io| io.read})  
end

the problem was that I put the “-v” parameter in the string and it was  
used by ruby itself and thus destroyed the marshaled stream…  
the added “–” parametr avoid this behavior.

Thanks, this is exactly what I was looking for…

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 26, 2006, 7:56pm UTC](https://www.ruby-forum.com/t/string-to-array-as-command-line/87327/7 "2006-03-26T19:56:19Z")

</div>

On Mon, 27 Mar 2006, lubos wrote:

> the added “–” parametr avoid this behavior.
> 
> Thanks, this is exactly what I was looking for…

ah - yes - good catch. i guess it goes without saying that this is  
somewhat  
expensive… but it should be portable. about the only other thing  
would be  
to dynamically determine which ruby to run instead of relying on the  
PATH  
setting

require “yaml”  
require “rbconfig”

def command\_line string  
cline = lambda{|ruby| Marshal::load(IO::popen("#{ ruby } -r yaml  
-e’ print Marshal::dump(ARGV) ’ – #{ string }"){|io| io.read}) }  
c = ::Config::CONFIG  
ruby = File::join(c[“bindir”], c[“ruby\_install\_name”]) \<\<  
c[“EXEEXT”]  
begin  
cline[ruby] # don’t depend on PATH  
rescue  
cline[“ruby”] # depend on PATH as fallback  
end  
end

regards.

-a
