След известно експериментиране това изглежда вероятно е това, от което се нуждаете:
snprintf(command, sizeof(command), "ssh %s@%s grep -c \\\"%s\\\" %s%s",
username, hostname, search_string, directory, file);
Имате нужда от няколко обратни наклонени черти, защото са включени множество интерпретатори на обратни наклонени черти.
- Компилаторът C: третира първите две обратни наклонени черти във всяка последователност от три като една обратна наклонена черта. Третата обратна наклонена черта избягва двойната кавичка, като вгражда двойна кавичка в низа
command
. Тогава командният низ съдържа \"
два пъти.
- Има друг процес, обработващ обратните наклонени черти и е малко трудно да се реши къде е той, но те са необходими, за да се получи правилният резултат, както се вижда от експеримента.
Работещ код — отдалечено изпълнение, точен резултат
Ето някакъв работещ демо код. Локалната програма се нарича pop
. Всичко там е твърдо свързано, защото съм мързелив (но сравних името на отдалечения хост с това, с което всъщност тествах). Програмата /u/jleffler/linux/x86_64/bin/al
изброява аргументите си така, както е получена, по един на ред. Намирам го за много полезен инструмент за ситуации като тази. Имайте предвид, че аргументите на al
са внимателно изработени с двойни интервали, за да покажат кога аргументите се третират като един срещу много.
$ ./pop
Command: <<ssh [email protected] /u/jleffler/linux/x86_64/bin/al \"x y z\" \"pp qq rr\">>
[email protected]'s password:
Response: <<x y z>>
Response: <<pp qq rr>>
$
Код
#include <stdio.h>
#include <string.h>
int main(void)
{
char command[512];
char const *arg1 = "x y z";
char const *arg2 = "pp qq rr";
char const *cmd = "/u/jleffler/linux/x86_64/bin/al";
char const *hostname = "remote.example.com";
char const *username = "jleffler";
snprintf(command, sizeof(command), "ssh %s@%s %s \\\"%s\\\" \\\"%s\\\"",
username, hostname, cmd, arg1, arg2);
printf("Command: <<%s>>\n", command);
FILE *fp = popen(command, "r");
char line[512];
while (fgets(line, sizeof(line), fp) != 0)
{
line[strlen(line)-1] = '\0';
printf("Response: <<%s>>\n", line);
}
pclose(fp);
return(0);
}
Вариант 1 — Дистанционно изпълнение, грешен резултат
$ ./pop1
Command: <<ssh [email protected] /u/jleffler/linux/x86_64/bin/al "x y z" "pp qq rr">>
[email protected]'s password:
Response: <<x>>
Response: <<y>>
Response: <<z>>
Response: <<pp>>
Response: <<qq>>
Response: <<rr>>
$
Код
#include <stdio.h>
#include <string.h>
int main(void)
{
char command[512];
char const *arg1 = "x y z";
char const *arg2 = "pp qq rr";
char const *cmd = "/u/jleffler/linux/x86_64/bin/al";
char const *hostname = "remote.example.com";
char const *username = "jleffler";
snprintf(command, sizeof(command), "ssh %s@%s %s \"%s\" \"%s\"",
username, hostname, cmd, arg1, arg2);
printf("Command: <<%s>>\n", command);
FILE *fp = popen(command, "r");
char line[512];
while (fgets(line, sizeof(line), fp) != 0)
{
line[strlen(line)-1] = '\0';
printf("Response: <<%s>>\n", line);
}
pclose(fp);
return(0);
}
Вариант 2 — Локално изпълнение, (различен) грешен резултат
$ ./pop2
Command: <<al [email protected] /u/jleffler/linux/x86_64/bin/al \"x y z\" \"pp qq rr\">>
Response: <<[email protected]>>
Response: <</u/jleffler/linux/x86_64/bin/al>>
Response: <<"x>>
Response: <<y>>
Response: <<z">>
Response: <<"pp>>
Response: <<qq>>
Response: <<rr">>
$
Локалната обвивка не се нуждае от обратната наклонена черта преди двойните кавички; всъщност добавянето му прави грешка.
Код
#include <stdio.h>
#include <string.h>
int main(void)
{
char command[512];
char const *arg1 = "x y z";
char const *arg2 = "pp qq rr";
char const *cmd = "/u/jleffler/linux/x86_64/bin/al";
char const *hostname = "remote.example.com";
char const *username = "jleffler";
snprintf(command, sizeof(command), "al %s@%s %s \\\"%s\\\" \\\"%s\\\"",
username, hostname, cmd, arg1, arg2);
printf("Command: <<%s>>\n", command);
FILE *fp = popen(command, "r");
char line[512];
while (fgets(line, sizeof(line), fp) != 0)
{
line[strlen(line)-1] = '\0';
printf("Response: <<%s>>\n", line);
}
pclose(fp);
return(0);
}
Вариант 3 — Локално изпълнение, правилен резултат
$ ./pop3
Command: <<al [email protected] /u/jleffler/linux/x86_64/bin/al "x y z" "pp qq rr">>
Response: <<[email protected]>>
Response: <</u/jleffler/linux/x86_64/bin/al>>
Response: <<x y z>>
Response: <<pp qq rr>>
$
Код
#include <stdio.h>
#include <string.h>
int main(void)
{
char command[512];
char const *arg1 = "x y z";
char const *arg2 = "pp qq rr";
char const *cmd = "/u/jleffler/linux/x86_64/bin/al";
char const *hostname = "remote.example.com";
char const *username = "jleffler";
snprintf(command, sizeof(command), "al %s@%s %s \"%s\" \"%s\"",
username, hostname, cmd, arg1, arg2);
printf("Command: <<%s>>\n", command);
FILE *fp = popen(command, "r");
char line[512];
while (fgets(line, sizeof(line), fp) != 0)
{
line[strlen(line)-1] = '\0';
printf("Response: <<%s>>\n", line);
}
pclose(fp);
return(0);
}
person
Jonathan Leffler
schedule
03.12.2012
sprintf
обаждане. А може би и обажданетоpopen
. - person AnT   schedule 03.12.2012