Грешка при изпълнение на perl команда с помощта на popen в C++

В моята c++ програма искам да изпълня perl команда и да прочета резултата, върнат от изпълнението. Използвам popen за това, но получавам грешка при изпълнение на моята команда:

команда:

string cmd = "perl -ne 's/^\\S+\\s//; if ((/" +
            pattern1+ " START/ .. /" + pattern2+ " END/) && /find/)"
            " { print \"$_\"}' file";
stream = popen(cmd.c_str(),"r");

Ако изпълня тази команда в командния ред, тя работи, но в C++ получавам тази грешка:

Search pattern not terminated at -e line 1.

Командата, която работи в командния ред, е, че в C++ вече избягах '\' и '"':

perl -ne 's/^\\S+\\s//; if ((/aaa START/ .. /bbb END/) && /find/) { print "$_"}' file

Ако изпълня тази команда, тя работи: "perl -ne print $_ file". Но първоначалната ми команда не го прави. Какво правя грешно. Благодаря.


person georgiana_e    schedule 21.11.2013    source източник
comment
Ако cout този низ изглежда ли така, както очаквате?   -  person Tom Fenech    schedule 21.11.2013
comment
Да, изглежда както искам и ако копирам и поставя отпечатаната команда в terminl, тя работи.   -  person georgiana_e    schedule 21.11.2013
comment
Не мисля, че е така, вижте липсващите наклонени черти в моя пример   -  person Tom Fenech    schedule 21.11.2013
comment
Как изглежда file?   -  person Tom Fenech    schedule 21.11.2013
comment
Работеше в командния ред, за да изпълни тази команда. Така че командата е добра.   -  person georgiana_e    schedule 21.11.2013
comment
Ако изтрия s/^\\S+\\s//; командата работи от c++.   -  person georgiana_e    schedule 21.11.2013


Отговори (3)


Това са вашите герои за бягство \. Ще трябва да ги удвоите в C++ низа, тъй като \\ се превръща в \. След това обвивката извършва обработката, както виждате в командния ред. т.е. друг кръг от \\ се превърна в \.

person Paul Evans    schedule 21.11.2013

Трябва да избегнете обратните наклонени черти (като добавите още обратни наклонени черти!).

std::string cmd = "perl -ne 's/^\\\\S+\\\\s//; if ((/" +
                  pattern1 + " START/ .. /" + 
                  pattern2+ " END/) && /find/)"
                  " { print \"$_\"}' file";

В C++0x можете да използвате необработен R"(strings)", за да избегнете добавянето на наклонени черти. Компилирайте с GCC като

g++ -std=c++0x -Wall popen.cpp

пример:

std::string cmd_raw = R"(perl -ne 's/^\\S+\\s//; if ((/)" +
                      pattern1 + R"( START/ .. /)" + 
                      pattern2 + R"( END/) && /find/))"
                      R"( { print \"$_\"}' file)";
person Tom Fenech    schedule 21.11.2013
comment
Но ако стартирам cmd, първият ред от изхода ви работи. И това е командата, която използвах. Ако използвам R, получавам грешка: cmd не е намерен. Благодаря. - person georgiana_e; 21.11.2013
comment
Вече избягах от символите в моята команда c++. Редактирах публикацията си и поставих командата, която работи в командния ред и трябва да бъде преведена на c++. - person georgiana_e; 21.11.2013
comment
Не мога да добавя -std=c++0x, за да използвам функцията R(). Не мога да редактирам проекта на makefile. - person georgiana_e; 21.11.2013
comment
@georgiana_e в такъв случай нямате друг избор освен да използвате опцията обратна наклонена черта - person Tom Fenech; 21.11.2013

Това проработи:

cmd = "perl -ne 's/^\\\\S+\\\\s//; if ((/" +
            pattern1+ " START/ .. /" + pattern2+ " END/) && /find/)"
            " { print \"$_\"}' file";
stream = popen(cmd.c_str(),"r");
person georgiana_e    schedule 21.11.2013