问题
I am using Ubuntu and boost v1.50.
Previously I used boost program_options to feed a set of options into a program like so:
#!/bin/bash
./prog --arg1 1 --arg2 "2" --arg3 {1,2,3} --arg4 {1,2} --arg5 5
So I am dealing with a mix of single integers, strings and integer arrays. This worked fine.
However, after "improving" the code by introducing local variables in bash, I have:
#!/bin/bash
a1=1
a2="2"
a3={1,2,3}
a4={1,2}
a5=5
./prog --arg1 $a1 --arg2 $a2 --arg3 $a3 --arg4 $a4 --arg5 $a5
Executing this results in an error:
error: the argument ('{1,2,3}') for option '--arg3' is invalid
I have set up the boost program_options like this:
namespace po = boost::program_options;
using namespace std;
try{
po::options_description desc("Allowed options");
desc.add_options()
("help", "produce help message")
("arg1", po::value<int>(&arg1)->required(), "doc1")
("arg2", po::value<string>(&arg2)->default_value("test"), "doc2")
("arg3", po::value<vector<int> >(&arg3)->multitoken(), "doc3")
("arg4", po::value<vector<int> >(&arg4)->multitoken(), "doc4")
("arg5", po::value<int>(&arg5)->default_value(1), "doc5")
;
po::variables_map vm;
po::store(po::parse_command_line(ac, av, desc), vm);
po::notify(vm);
if(vm.count("help")) cout << desc << "\n";
}
catch(exception& e){
cerr << "error: " << e.what() << "\n";
errorflag=1;
}
catch(...){
cerr << "Exception of unknown type!\n";
errorflag=1;
}
Where did I go wrong? Is multitoken not appropriate in this context? What can I use instead? Is it not possible to read integer arrays?
I tried omitting multitoken but then it fails also. Using quotation marks around the local variable in the bash script does not help either.
If I change the array input from {a,b,c} to "a b c", it is ok. However, I already have a large number of entries in the other format and I am would like to continue using it as other programs depend on it too.
I think it should be doable, since it worked without the local variables. Does someone know how?
EDIT: I have been mistaken. "a b c" does NOT work as input :(
EDIT 2: I came up with a little workaround: I convert {a,b,c} -> a b c using
argnew=`echo ${arg:1:-1} | tr ',' ' '`
and the feeding it to the program works fine. Is that the best solution?
回答1:
Changing your original script to add the -x
bash debugging option, like this:
#!/bin/bash -x
./prog --arg1 1 --arg2 "2" --arg3 {1,2,3} --arg4 {1,2} --arg5 5
and then running it shows this output:
+ ./prog --arg1 1 --arg2 2 --arg3 1 2 3 --arg4 1 2 --arg5 5
So your curly brace groupings aren't working they way you think they're working, because bash command line processing is expanding them before invoking ./prog
.
You can get it working if in your second script, if you change the assignments for a3
and a4
to be like this:
a3='1 2 3'
a4='1 2'
and then double-quote all your variables when you call ./prog
:
./prog --arg1 "$a1" --arg2 "$a2" --arg3 "$a3" --arg4 "$a4" --arg5 "$a5"
来源:https://stackoverflow.com/questions/27891139/how-to-use-boost-program-options-to-read-an-integer-array