1

I want to pass array in argument in such a way suppose process.rb is my script and the argument will be like:

i/p

process.rb server{1..4} 
process.rb prodserver{2..3} 
process.rb devserver3

The process.rb should accept all the inputs and parse it in such a way that when I print the variable which holds the arguments give me below result.

o/p
    puts arguments

    server1
    server2
    server3
    server4
    or
    prodserver2
    prodserver3
    or
    devserver3

I have a shell script which does the same:

for i in "$@"
do
echo $i
done

i/p
server{1..4} 
o/p
server1server2server3server4

I wanted to have the same logic in the ruby. Since I am a new bie in ruby I am not able to find the same on google. Please let me know how I can get this output or any article about the related to my question

4 Answers 4

4

The list is expanded by the shell before it ever hits your script. In other words, both your shell script and your Ruby script do not receive a single argument server{1..4} but rather they receive four arguments server1 server2 server3 server4, before they even start interpreting the arguments themselves.

You can simply just iterate over those, there is no need to parse the {1..4} shell expansion syntax yourself because you will never see it! It is already parsed and expanded by the shell before the shell passes off the arguments to your script.

ruby -e 'p ARGV' -- server{1..4}
# ["server1", "server2", "server3", "server4"]
Sign up to request clarification or add additional context in comments.

Comments

3
#!ruby

ARGV.each do |i|
  puts i
end

Basically ARGV holds all arguments passed to program, and puts prints string with new line added (the same as echo without -n flag in shell).

4 Comments

Sorry to say but its wrong. Let me explain you again what I am expecting. Suppose I have 12 servers names server1,2,3....12 and I want to pass the server name in indexed parameter for e.x. i/p server{1..5} than I should get server1, server2, server3, server4, server5 as a value in a variable. Consider another example. I/P: server{3..3} Than I will get server3 only I/P server{1..2,5..9} Than I will get server1, server2, server5, server6,server7 server8,server9. I think these examples will help you to understand the problem
@A_01 So you pass range in {} which is expanded by default in shell, show example which takes advantage of this automatic expansion, and as I understand works for you, but obviously not for your new examples, but you want something else? Then yes, my answer is incorrect.
That's correct, invoking your script with process.rb server{1..4} will pass 4 parameters and set ARGV to ["server1", "server2", "server3", "server4"]
My apologies. I got distracted yes @MBO its correct. Thanks.
3

Command-line arguments in Ruby end up in ARGV. You can duplicate your shell script's functionality by iterating over that:

ARGV.each do |a|
    puts a
end

3 Comments

Thanks 4 reply. But unfortunetely your anser is incorrect. If you read the question correctly you will understand what o/p I am expecting. sorry to say you answer incrorect
Oops, thanks. Fixed. That's what happens when you're forced to switch from Ruby to Python for a year. :)
@A_01: Yes, the question clearly says what output you are expecting and this answer produces exactly that output. What's incorrect about that?
1

If I understand you correctly you want to expand the range that comes in string form from your argument ARGV[0] ? My samples use a string to demonstrate it workd, replace the string by ARGV[0]

def expand_range arg
  string, range = arg.split("{") #split arg in string part and rangestring part
  if range #if a range is given
    # parse the rangestring to an range by splitting the string on .. 
    # and splash this array to both its elements, convert them to integer
    # and transform into a real range
    # and enumerate each number in the range
    Range.new(*range.split("..").map(&:to_i)).each do |val|
      #concatenate the string part with the number
      p "#{string}#{val}"
    end
  else #else just pass the string
    p string
  end
end

expand_range 'server{1..4}'
# "server1"
# "server2"
# "server3"
# "server4"

expand_range 'devserver3' 
#"devserver3"

Personally I would return an array and print that instead of printing in the method itself, that would be more multifunctional.

11 Comments

It is perfect man thanks a lot. Also can you please give a little idea about whats going on in between line 2-4.
sure: i'll ad it to my answer
@peter I don't get it either, could you explain it?
The OP want to run process.rb server{1..4}, right? The shell expands this for you and passes 4 parameters to the ruby script.
@peter Have you tested it? I even copied his "script" to test inputs, and my answer does exactly what his shell script which "does the same thing" he want to get, as OP says.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.