Я использую Ubuntu и boost v1.50.
Раньше я использовал boost program_options для подачи набора параметров в такую программу:
#!/bin/bash
./prog --arg1 1 --arg2 "2" --arg3 {1,2,3} --arg4 {1,2} --arg5 5
Поэтому я имею дело с комбинацией одиночных целых чисел, строк и целых массивов. Это отлично работает.
Однако после "улучшения" кода путем введения локальных переменных в bash у меня есть:
#!/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
Выполнение этого приводит к ошибке:
error: the argument ('{1,2,3}') for option '--arg3' is invalid
Я настроил boost_options boost следующим образом:
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;
}
Где я неправ? Является ли мультитокен не подходящим в этом контексте? Что я могу использовать вместо этого? Невозможно ли читать целые массивы?
Я попытался пропустить мультитокен, но потом он тоже не работает. Использование кавычек вокруг локальной переменной в сценарии bash тоже не помогает.
Если я изменю вход массива от {a, b, c} до "abc", это нормально. Тем не менее, у меня уже есть большое количество записей в другом формате, и я хотел бы продолжать использовать его, так как другие программы тоже зависят от него.
Я думаю, что это должно быть выполнимым, поскольку оно работало без локальных переменных. Кто-нибудь знает, как?
EDIT: Я ошибся. "abc" НЕ работает как вход :(
EDIT 2: я придумал небольшое обходное решение: я конвертирую {a, b, c} → abc, используя
argnew='echo ${arg:1:-1} | tr ',' ' ''
и подача его в программу отлично работает. Это лучшее решение?
Изменение исходного сценария для добавления -x
bash отладки, например:
#!/bin/bash -x
./prog --arg1 1 --arg2 "2" --arg3 {1,2,3} --arg4 {1,2} --arg5 5
а затем его запуск показывает этот вывод:
+ ./prog --arg1 1 --arg2 2 --arg3 1 2 3 --arg4 1 2 --arg5 5
Таким образом, ваши фигурные скобки не работают так, как вы думаете, они работают, потому что обработка командной строки bash расширяет их до вызова ./prog
.
Вы можете заставить его работать, если в вашем втором скрипте, если вы измените назначения для a3
и a4
выполните следующие действия:
a3='1 2 3'
a4='1 2'
а затем дважды укажите все ваши переменные при вызове ./prog
:
./prog --arg1 "$a1" --arg2 "$a2" --arg3 "$a3" --arg4 "$a4" --arg5 "$a5"