используя exec только с некоторыми параметрами argv (используя C)

Мне нужно иметь вход, который выглядит как

./a.out <exe> <arg1> ... <argn> <others_stuff>

где <exe> <arg1> ... <argn> — это ввод, который я должен выполнить как отдельный процесс (цель состоит в том, чтобы сохранить вывод exe в txt).

Сохранение вывода в txt-файл не проблема, мне просто нужно перенаправить stdout (используя dup2, freopen или что-то подобное).

Проблема в том, чтобы выполнить только часть argv! Потому что функции семейства exec (а их так много!) позволяют отдавать на вход весь argv или указывать каждый arg. Я пишу здесь, потому что не могу решить проблему, поэтому надеюсь, что вы мне поможете (я везде безуспешно гуглил).

РЕДАКТИРОВАТЬ: я забыл сказать, что я не могу использовать систему для выполнения команды!


person Andrea    schedule 28.05.2012    source источник
comment
@unwind OP упомянул некоторые неудовлетворительные поиски в Google.   -  person gcbenison    schedule 28.05.2012


Ответы (2)


Поскольку exec принимает аргумент argv в виде массива char*, заканчивающегося указателем NULL, вы можете просто использовать существующий argv и установить элемент после последнего, который вы хотите передать в NULL.

Это уничтожает argv - если это проблема, вы можете сначала скопировать его (вам придется выделить немного памяти для новой копии...)

person gcbenison    schedule 28.05.2012

Если вы хотите использовать непрерывную часть argv, у вас есть два варианта: вы можете (как вы пытались) создать новый массив arg, правильно заполнив его следующим образом:

  char *params[argc-2];
  memcpy(params, argv+1, sizeof params);
  params[argc-3] = NULL;

  execvp(*params, params);

Вы могли бы просто разбить argv

  argv[argc-3] = NULL;
  execvp(argv[1], argv+1);

Или, если у вас не слишком много аргументов, вы можете использовать execlp:

  execlp(argv[0], argv[0], argv[3], argv[2], argv[4], NULL);
person Dave    schedule 28.05.2012
comment
Я использовал второй, потому что после этого мне больше не нужен argv. С командой ls все работало правильно, а с mkdir — нет. Пишет, что отсутствует аргумент для mkdir или что-то в этом роде (английский не мой родной язык) - person Andrea; 28.05.2012
comment
Разбить argv выглядит проще всего. разбить звучит плохо, но выполнение этого действия после fork и перед execvp означает, что оно не может сломать никакое другое использование argv. - person ugoren; 28.05.2012
comment
@ Black27 используйте простую программу printargs, чтобы убедиться, что вы используете нужные аргументы. - person Dave; 28.05.2012
comment
Спасибо за ответ, я решил проблему! Просто я сделал небольшую итерацию от 1 к argc-2 вместо argc-1... Какая глупая ошибка! - person Andrea; 28.05.2012
comment
@dave Есть ли в этом подходе какое-либо требование, чтобы params находилась в куче, или params может быть локальной переменной? - person gcbenison; 28.05.2012
comment
@gcbenison params может находиться где угодно. Однако, как упоминал Угорен, разбить argv легче, если вы находитесь между fork и exec. - person Dave; 28.05.2012