Как я запускаю подпроцесс в C# с argv? (Или преобразуйте agrv в легальную строку аргумента),

У меня есть приложение командной строки C#, которое я должен запустить в окнах и под моно в Unix. В какой-то момент я хочу запустить подпроцесс, данный ряд произвольных параматерей, переданных на пути командная строка. Например:

Usage: mycommandline [-args] -- [arbitrary program]

К сожалению, Система. Диагностика. ProcessStartInfo только берет строку для args. Это - проблема для команд, таких как:

./my_commandline myarg1 myarg2 -- grep "a b c" foo.txt

В этом случае argv похож:

argv = {"my_commandline", "myarg1", "myarg2", "--", "grep", "a b c", "foo.txt"}

Обратите внимание, что кавычки вокруг "b c" разделяются оболочкой поэтому, если я просто связываю аргументы для создания строки аргумента для ProcessStartInfo, который я получаю:

args = "my_commandline myarg1 myarg2 -- grep a b c foo.txt"

Который не является тем, что я хочу.

Существует ли простой способ или передать argv, чтобы подобработать запуск под C# ИЛИ преобразовать произвольный argv в строку, которая законна для оболочки Linux и окон?

Любая справка значительно ценилась бы.

7
задан lucas 2 June 2010 в 17:42
поделиться

5 ответов

Спасибо всем за предложения. В итоге я использовал алгоритм из shquote ( http://www.daemon-systems.org/man/shquote.3.html ).

/**
 * Let's assume 'command' contains a collection of strings each of which is an
 * argument to our subprocess (it does not include arg0).
 */
string args = "";
string curArg;
foreach (String s in command) {
    curArg = s.Replace("'", "'\\''"); // 1.) Replace ' with '\''
    curArg = "'"+curArg+"'";          // 2.) Surround with 's
    // 3.) Is removal of unnecessary ' pairs. This is non-trivial and unecessary
    args += " " + curArg;
}

Я тестировал это только на Linux. Для окон вы можете просто объединить аргументы.

1
ответ дан 7 December 2019 в 16:39
поделиться

В windowsland это действительно просто ... добавьте лишние кавычки в строку, которую вы передаете объекту System.Diagnostics.ProcessStartInfo.

например. "./my_commandline" "myarg1 myarg2 - grep \" a b c \ "foo.txt"

1
ответ дан 7 December 2019 в 16:39
поделиться

Вам нужно запустить новый подпроцесс, используя grep и все аргументы, которые потребуются grep.

void runProcess(string processName, string args)
{
    using (Process p = new Process())
    {
        ProcessStartInfo info = new ProcessStartInfo(processName);
        info.Arguments = args;
        info.RedirectStandardInput = true;
        info.RedirectStandardOutput = true;
        info.UseShellExecute = false;
        p.StartInfo = info;
        p.Start();
        string output = p.StandardOutput.ReadToEnd();
        // process output
    }
}

затем сделайте вызов runProcess("grep", "a", "b", "c", "foo.txt");

Edit: Обновлена обработка аргументов.

0
ответ дан 7 December 2019 в 16:39
поделиться

Просто используйте Regex для проверки наличия пробелов в строке и замените исходную строку новой с кавычками:

using System.Text.RegularExpressions;
// ...
for(int i=0; i<argv.Length; i++) {
    if (Regex.IsMatch(i, "(\s|\")+")) {
        argv[i] = "\"" + argv[i] + "\"";
        argv[i].Replace("\"", "\\\"");
    }
}
0
ответ дан 7 December 2019 в 16:39
поделиться

В MSDN есть описание того, как среда выполнения MS Visual C анализирует строку , возвращаемую GetCommandLine () в массив argv .

Возможно, вас заинтересует функция list2cmdline () из стандартной библиотеки Python, которая используется модулем Python subprocess для имитации поведения Unix argv . в среде Win32.

1
ответ дан 7 December 2019 в 16:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: