Давайте посмотрим на ваш код:
parameter[0] = malloc(255);
Поскольку strtok()
разделяет исходный массив command
, вам не нужно выделять дополнительное пространство с помощью malloc()
;Вы можете просто указать указатели parameter[n]
на соответствующие разделы исходной командной строки.Однако, как только вы выйдете за пределы разделенных пробелами команд (в реальной оболочке символ |
не обязательно должен быть окружен пробелами, а в вашей), вам, вероятно, потребуется скопировать части командной строкипримерно, так что это не совсем неправильно.
Вы должны проверить успешность выделения памяти.
cp = strtok(command, " "); //Get the initial string (the command)
strncpy(parameter[0], cp, 50);
Вы выделили 255 символов;вы копируете максимум 49. Возможно, лучше подождать, пока у вас не будет выделен параметр, а затем продублировать его, выделив только необходимое пространство.Обратите внимание: если имя команды (путь, ведущий к) составляет 50 символов или более, строка с нулевым символом в конце не будет иметь места - пространство, выделенное malloc()
, не обнуляется, а strncpy()
не записывает завершающий ноль вслишком длинная строка.
for (i = 1; i < MAX_ARG; i++)
Не ясно, что у вас должен быть верхний предел количества аргументов, который так прост, как этот.Существует верхний предел, но обычно он равен общей длине всех аргументов.
{
parameter[i] = malloc(255);
Аналогичные комментарии о распределении памяти и проверке.
cp = strtok(NULL, " ");
parameter[i] = cp;
Упс!Там идет память.Извините за утечку.
if (strcmp(parameter[i], "|") == 0)
Я думаю, что было бы лучше сделать это сравнение перед копированием ... Кроме того, вам не нужен канал в списке аргументов любой команды;это запись оболочки, а не часть списков аргументов команды.Вы также должны убедиться, что список аргументов первой команды завершается указателем NULL, тем более что i
чуть ниже MAX_ARG
, поэтому вы не будете знать, сколько аргументов было указано.
{
i = MAX_ARG;
cp = strtok(NULL, " ");
parameter2[0] = malloc(255);
strncpy(parameter2[0], cp, 50);
Это кажется странным;Вы изолируете команду и затем обрабатываете ее аргументы отдельно.Установка i = MAX_ARG
тоже кажется забавной, поскольку ваше следующее действие - разорвать петлю.
break;
}
if(parameter[i] == NULL)
{
break;
}
}
//Find the second set of commands and parameter
//strncpy(parameter2[0], cp, 50);
for (j = 1; j < MAX_ARG; j++)
{
parameter2[j] = malloc(255);
cp = strtok(NULL, " ");
parameter2[j] = cp;
}
Возможно, вам следует войти в эту петлю, только если вы нашли трубу.Затем этот код теряет память, как и другой (так что вы последовательны - и согласованность важна; но также правильность).
Вам необходимо проверить свой код, чтобы убедиться, что он правильно обрабатывает символ «нет канала»и «труба, но не следующая команда».В какой-то момент вы должны рассмотреть многоступенчатые конвейеры (три, четыре, ... команды).Обобщение вашего кода для обработки этого возможно.
При написании кода для Bash или эквивалентной оболочки я часто использую нотации, такие как этот скрипт, который я использовал сегодня несколько раз.
ct find /vobs/somevob \
-branch 'brtype(dev.branch)' \
-version 'created_since(2011-10-11T00:00-00:00)' \
-print |
grep -v '/0$' |
xargs ct des -fmt '%u %d %Vn %En\n' |
grep '^jleffler ' |
sort -k 4 |
awk '{ printf "%-8s %s %-25s %s\n", $1, $2, $3, $4; }'
Не имеет большого значения, что он делает (но он находит все проверки, которые я сделал с 11 октября в определенной ветке в ClearCase);важно, что я использовал обозначение.(Да, возможно, его можно было бы оптимизировать - это не стоило того.) Точно так же, это не обязательно то, с чем вам нужно сейчас иметь дело - но оно дает вам представление о том, куда вам нужно идти.