LinuxQuestions.org
Latest LQ Deal: Linux Power User Bundle
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 07-22-2013, 01:23 PM   #1
LiquoriceHats
LQ Newbie
 
Registered: Jul 2013
Location: United Kingdom
Posts: 7

Rep: Reputation: Disabled
Shell script defining for loops of parameters of separate program


Hello everyone,

I've written a program in c++ (program.cpp)that needs to be run multiple times for all combinations of two parameters p1, p2 which are currently manually defined before each run. What I'd like to do is something to the effect of:

for(p1=0; p1<p1max; p1++){
for(p2=0; p2<p2max; p2++){
run program.cpp
}
}
where I can change the limits of the maximum values so the whole thing can be parallelized. After some searching a shell script seems the best way to do this, but I'm new to unix and so would appreciate some help getting started. Thank you.
 
Old 07-22-2013, 01:32 PM   #2
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,246

Rep: Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684
Assuming bash (that's a type of shell) if you ditch the braces for 'do' and 'done' and add a second set of round brackets your set
Obviously you would also need to set your max values prior:
Code:
p1max=10
p2max=5

for (( p1 = 0; p1 < p1max; p1++ ))
do
    for (( p2 = 0; p2 < p2max; p2++ ))
    do
        run program.cpp
    done
done
 
Old 07-22-2013, 01:41 PM   #3
LiquoriceHats
LQ Newbie
 
Registered: Jul 2013
Location: United Kingdom
Posts: 7

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by grail View Post
Assuming bash (that's a type of shell) if you ditch the braces for 'do' and 'done' and add a second set of round brackets your set
Yes, I do mean bash. Does that mean that
Code:
p1max=10
p2max=20
for(( p1 = 0; p1 < p1max; p1++ ))
do
    for (( p2 = 0; p2 < p2max; p2++ ))
    do
        make
    done
done
will do what I want (my code presently compiles and runs using a makefile)?
 
Old 07-23-2013, 10:48 AM   #4
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,246

Rep: Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684
Yes, although if you simply wanted to run a single command 200 times then a single loop is all that is required.
 
Old 07-23-2013, 12:40 PM   #5
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,602

Rep: Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241
Note: the example given runs make - which unless something in the source has changed, will do nothing after the first time.

Normally, such parameters would be passed on the command line, so instead of make, you would put "progname $p1 $p2".

And if you were going to run multiple of these in parallel, you need to have different output files... So assuming the output is sent to stdout, that would make the command something like "progname $p1 $p2 >$p1_$p2.result&"

Where the trailing & will put each invocation in the background. This COULD (depending on the parameters) overload your system.

Last edited by jpollard; 07-23-2013 at 12:41 PM.
 
Old 07-23-2013, 02:26 PM   #6
LiquoriceHats
LQ Newbie
 
Registered: Jul 2013
Location: United Kingdom
Posts: 7

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by jpollard View Post
Note: the example given runs make - which unless something in the source has changed, will do nothing after the first time.
Normally, such parameters would be passed on the command line, so instead of make, you would put "progname $p1 $p2".
Well, I have two parameters in my program called p1 and p2, and I want the code to run for those parameters being changed according to the values in the for loops. Would the below overwrite the value of p1 and p2 in program.cpp and run it with those specified in the for loop? Do I need to do change anything in the c++ code itself to allow this?
Code:
#!/bin/sh
p1max=10
p2max=20
for(( p1 = 0; p1 < p1max; p1++ ))
do
    for (( p2 = 0; p2 < p2max; p2++ ))
    do
        program.cpp $p1 $p2
    done
done
 
Old 07-23-2013, 09:20 PM   #7
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,602

Rep: Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241
Yes - they have to be evaluated by the program and set in the appropriate place.

It is just the normal practice. The only times that can get difficult is if they are used to define array dimensions in static structures, which isn't necessary.

I only bring the subject up because you indicated you wanted to run them in parallel, and the first scrip could not do that.
 
Old 07-23-2013, 09:37 PM   #8
evo2
LQ Guru
 
Registered: Jan 2009
Location: Japan
Distribution: Mostly Debian and Scientific Linux
Posts: 5,753

Rep: Reputation: 1288Reputation: 1288Reputation: 1288Reputation: 1288Reputation: 1288Reputation: 1288Reputation: 1288Reputation: 1288Reputation: 1288
Hi,

you will need to modify your program so that it can take the values of p1 and p2 as arguments on the command line. So your program would look something like
Code:
#include <iostream>
#include <string>
#include <cstdlib>
int main(int argc, char** argv )
{
	if ( argc < 3) {
		std::cerr << "Error: must provide two arguments on the command line."
			  << std::endl;
		exit(1);
	}
	std::string p1 = argv[1];
	std::string p2 = argv[2];
	std::cout << "p1 = " << p1 << ", p2 = " << p2 << std::endl;
}
Compile...
Code:
g++ -o program program.cpp
Then you could run it using a shell script like:
Code:
for par1 in x y z ; do
  for par2 in a b c ; do
    ./program $par1 $par2
  done
done
Evo2.
 
Old 07-24-2013, 01:57 AM   #9
LiquoriceHats
LQ Newbie
 
Registered: Jul 2013
Location: United Kingdom
Posts: 7

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by jpollard View Post
Yes - they have to be evaluated by the program and set in the appropriate place.

It is just the normal practice. The only times that can get difficult is if they are used to define array dimensions in static structures, which isn't necessary.

I only bring the subject up because you indicated you wanted to run them in parallel, and the first scrip could not do that.
That's not a problem as I'm working with vectors, but thanks for the heads up.
 
Old 07-24-2013, 02:05 AM   #10
LiquoriceHats
LQ Newbie
 
Registered: Jul 2013
Location: United Kingdom
Posts: 7

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by evo2 View Post
Hi,

you will need to modify your program so that it can take the values of p1 and p2 as arguments on the command line. So your program would look something like
Code:
#include <iostream>
#include <string>
#include <cstdlib>
int main(int argc, char** argv )
{
	if ( argc < 3) {
		std::cerr << "Error: must provide two arguments on the command line."
			  << std::endl;
		exit(1);
	}
	std::string p1 = argv[1];
	std::string p2 = argv[2];
	std::cout << "p1 = " << p1 << ", p2 = " << p2 << std::endl;
}
Thank you for being so specific and helpful. Your suggestion is pretty much the same result I got to after some more reading on command line parsing. I don't understand why you're setting p1 and p2 to be strings when I want them to have numerical values, though. Why is that?
 
Old 07-24-2013, 02:25 AM   #11
evo2
LQ Guru
 
Registered: Jan 2009
Location: Japan
Distribution: Mostly Debian and Scientific Linux
Posts: 5,753

Rep: Reputation: 1288Reputation: 1288Reputation: 1288Reputation: 1288Reputation: 1288Reputation: 1288Reputation: 1288Reputation: 1288Reputation: 1288
Hi,

Quote:
Originally Posted by LiquoriceHats View Post
I don't understand why you're setting p1 and p2 to be strings when I want them to have numerical values, though. Why is that?
Because the command line arguments are passed to main() as char* which convert trivially to std::string. If you want to use some sort of floaing point you will need to convert them. There are a number of ways to do this. For example you could use a function like:

Code:
#include <string>
#include <sstream>
float s2f( std::string s )
{
        std::stringstream istr(s);
        float x;
        istr >> x;
        return x;
}
or you could use one of the old C style methods.

Evo2.
 
Old 07-24-2013, 04:07 AM   #12
LiquoriceHats
LQ Newbie
 
Registered: Jul 2013
Location: United Kingdom
Posts: 7

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by evo2 View Post
Because the command line arguments are passed to main() as char* which convert trivially to std::string.
I see, that makes sense. Thank you. However, when the script starts, I get a segmentation error when not even halfway through the program which I don't when just running the program directly. Why might this be?

Last edited by LiquoriceHats; 07-24-2013 at 05:19 AM. Reason: Found a better way of phrasing the question
 
Old 07-24-2013, 07:40 AM   #13
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,602

Rep: Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241
Depends on the code.
 
Old 07-24-2013, 07:52 AM   #14
LiquoriceHats
LQ Newbie
 
Registered: Jul 2013
Location: United Kingdom
Posts: 7

Original Poster
Rep: Reputation: Disabled
I found the mistake. Thank you very much to all of you for your help.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] there is one name 4 for command-line-parameters in shell script miillerje Linux - Newbie 3 10-21-2012 08:25 AM
Shell script that reads from parameters file carters2 Linux - Newbie 4 11-04-2009 09:24 AM
shell script (sending parameters to scripts) qrshat Programming 4 12-05-2007 01:15 PM
Passing parameters to a shell script neocookie Linux - General 5 10-20-2005 12:44 PM
Brian cramp with shell script for loops SheldonPlankton Programming 4 07-16-2004 07:45 AM


All times are GMT -5. The time now is 10:17 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration