Как назначить вывод команды оболочки для переменной на языке Си - PullRequest
1 голос
/ 09 октября 2010

Я хочу, чтобы выходные данные команды оболочки (echo free | grep Mem| awk '{print $2}') были собраны в переменную, чтобы я мог использовать ее в программе на Си. Итак, у меня есть код здесь.

 system("TOTAL=$(echo `free | grep Mem| awk '{print $2}'`)");
 popen("grep -v procs $1 | grep -v free | awk '{USED=TOTAL-$4-$5-$6;print USED}'", "r");

Могу ли я использовать переменную TOTAL в той же программе внутри вызова popen (), как показано выше?

Ответы [ 4 ]

2 голосов
/ 09 октября 2010

Вам нужно будет создать строку, содержащую полный сценарий, который вы хотите запустить, или вам нужно будет создать сценарий, который можно просто запустить, а затем организовать чтение результата этого сценария с помощью popen().Любой возможен;что проще, зависит от уровня ваших навыков написания сценариев по сравнению с вашими навыками программирования на C.

char command[4096];

strcpy(command, "TOTAL=$(free | grep Mem| awk '{print $2}')\n");
strcat(command, "grep -v procs $1 | grep -v free |\n");
strcat(command, "awk '{USED=TOTAL-$4-$5-$6;print USED}' TOTAL=$TOTAL\n");

FILE *in = popen(command, "r");

...read the results, etc...

Строковые операции упрощают первый сценарий оболочки, а затем передают значение TOTAL, вычисленное в awk.

Другой способ сделать это - прочитать выходные данные из free | grep Mem | awk '{print $2}' - значения TOTAL - из одного использования popen(), а затем встроить это значение во вторую команду:

char command[4096];

strcpy(command, "free | grep Mem| awk '{print $2}'");
char total[20];
FILE *in1 = popen(command, "r");
...read TOTAL into total...

strcpy(command, "grep -v procs $1 | grep -v free |\n");
strcat(command, "awk '{USED=TOTAL-$4-$5-$6;print USED}' TOTAL=");
strcat(command, total);

FILE *in2 = popen(command, "r");
0 голосов
/ 09 октября 2010

Вам нужно обрабатывать настройку TOTAL в той же подоболочке, где вы ее используете;Переменные среды не передаются между подпроцессами (единственное, что работает, это подпроцесс, наследующий env-переменные своего родительского процесса).Вы можете сделать это следующим образом (я удалил немного бесполезной путаницы):

FILE *f = popen("TOTAL=$(free | grep Mem | awk '{print $2}');"
        "grep -v procs $1 | grep -v free | "
        "awk '{USED=TOTAL-$4-$5-$6;print USED}'",
        "r");

Обратите внимание на многострочную строковую константу.Тем не менее, я подозреваю, что даже это не сработает, так как это путаница разных языков.(Например, $1 выглядит очень подозрительно, поскольку он не находится внутри контекста, который обычно работает с этими вещами.) Возможно, вам будет проще поместить все эти сложные сценарии в надлежащий сценарий оболочки, который вы сможете запустить, посколькуВы будете работать с меньшим количеством языков одновременно и сможете отлаживать все этапы, а не все сразу ...

0 голосов
/ 09 октября 2010

Вы можете использовать FIFO или, по крайней мере, использовать простой временный файл.

0 голосов
/ 09 октября 2010

Я не думаю, что это возможно, поскольку system разветвляет оболочку для запуска команды и возвращается после ее завершения, по существу убивая оболочку, которую она также разветвила.Таким образом, любая заданная переменная окружения также будет потеряна.

...