Оставайтесь в каталоге с помощью popen

Я хочу написать программу на C++ и использую здесь функцию popen для отправки команд в командную строку в Unix. Он отлично работает, но когда я вызываю cd directory, каталог не меняется. Я думаю, что это то же самое, когда я пытаюсь запустить cd directory в каком-то скрипте, после завершения пути к каталогу скрипта обратно. Итак, скрипты, которые я должен запускать как . ./script.sh, а не ./sript.sh, но как это сделать с помощью функции popen? Я пытался добавить ". " перед первым аргументом popen, но запуск ". ls" приводит к ошибке.

Код:

cout << "@ Command from " << session->target().full() << ": " << message.body() << endl;
//cout << "Prisla zprava" << endl;
//m_session->send( "Hello World", "No Subject" );
//system( message.body().c_str() );
//if ( message.body() == "" )
FILE* outp;
char buffer[100];
string outps = "";
outp = popen( message.body().c_str(), "r" );
while ( !feof(outp) )
{
    fgets( buffer, 100, outp );
    outps = outps + buffer;
}
pclose(outp);
cout << "& Output from command: " << outps << endl;
m_session->send( outps.c_str(), "Output" );

В message.body(); есть string, который я хочу запустить (я получаю это от XMPP). Когда string, например, "ls", возвращается string со списком файлов в фактическом каталоге. Но когда сообщение "cd directory", ничего не происходит, например, попытка изменить каталог в сценариях.


person Garret Raziel    schedule 28.10.2009    source источник
comment
Как вы меняете директорию? (пример кода может быть полезен)   -  person mmmmmm    schedule 28.10.2009
comment
Как изменить каталог в программе?   -  person reko_t    schedule 28.10.2009
comment
Есть пример кода, где я его использую. Вот пытаюсь добавить. как при запуске скриптов, но . ls выдает ошибку. Без . каталог не изменится.   -  person Garret Raziel    schedule 28.10.2009


Ответы (2)


Как правило, команда popen() выполняет команду через оболочку. Итак, он открывает трубу и разветвляется. Дочерний элемент выполняет некоторую сантехнику (подключение трубы к стандартному вводу или стандартному выводу — в зависимости от флага), а затем выполняет

execl("/bin/sh", "/bin/sh", "-c", "what you said", (char *)0);

Итак, то, как все это будет себя вести, будет зависеть от ваших ключевых переменных среды, особенно от PATH.

Если вы хотите выполнить скрипт в текущем каталоге, то один из этих вариантов:

outp = popen("./script.sh", "r");
outp = popen("sh -x ./script.sh", "r");
outp = popen("sh -c './script.sh arg1 arg2'", "r");

Если вы хотите выполнить команду «ls»:

outp = popen("/bin/ls /the/directory", "r");

И если вы хотите изменить каталог перед запуском чего-либо:

outp = popen("cd /somewhere/else; ./script", "r");

И так далее...

Если вы хотите изменить каталог программы, использующей popen(), вам нужно использовать системный вызов 'chdir()' (или, возможно, fchdir()). Если вы думаете, что захотите вернуться к тому, с чего начали, используйте:

int fd = open(".", O_RDONLY);
chdir("/some/where/else");
...do stuff in new directory
fchdir(fd);

(Очевидно, вам нужна проверка ошибок в этой партии.)

person Jonathan Leffler    schedule 30.10.2009

Кажется, у вас есть немного кода, который вы не понимаете. Вы читаете из outp, канала. Присвоение имени входному каналу outp довольно запутанно. Затем вы берете прочитанную строку и передаете ее m_session->send().

Нигде во всем этом процессе вы не взаимодействуете с командной строкой Unix. В частности, popen() нет.

person MSalters    schedule 28.10.2009
comment
Нет, вы этого не понимаете. У меня есть строка в message.body();. Я создаю ФАЙЛ* с именем outp (это outp, потому что здесь я получаю вывод функции popen). Я вызываю функцию popen, функция popen берет строку из аргумента, передает ее в систему Unix, а вывод этой команды передает в outp. Поэтому, если я хочу вызвать ls в программе на C++, я вызову popen(ls,r), а вывод ls будет в файле, который возвращает popen. Оно работает. Но это не работает с каталогом cd, как если бы вы пытались вызвать каталог cd из какого-то bash-скрипта. - person Garret Raziel; 29.10.2009
comment
Если вы получаете вывод другой программы, это ввод для вас. - person MSalters; 30.10.2009