如何在.NET Core中跨平台执行shell命令?

Luk*_* Vo 6 c# shell console console-application .net-core

在我的 .NET Core 控制台应用程序中,我收到字符串数组形式的多个命令,并希望将它们作为控制台命令执行(如果可能,但不是硬要求,并在我自己的应用程序中显示它们的输出)。

首先,我尝试解析每个命令以分离它们的名称和参数并将它们放入ProcessStartInfo. 但是,某些命令不起作用(即使是简单的命令,如echo "Hello")。

现在我转而调用 Powershell,如下所示:

    static IEnumerable<ProcessStartInfo> ParseCommands(string[] args)
    {
        return args
            .Skip(1)
            .Select(q => new ProcessStartInfo()
            {
                FileName = "powershell",
                Arguments = q,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                UseShellExecute = false,
            }).ToList();
    }

    static void RunCommand(ProcessStartInfo processInfo)
    {
        Console.WriteLine($"{processInfo.Arguments}");

        var process = new Process()
        {
            StartInfo = processInfo,
        };
        process.Start();

        while (!process.StandardOutput.EndOfStream)
        {
            Console.WriteLine(process.StandardOutput.ReadLine());
        }

        process.WaitForExit();
    }
Run Code Online (Sandbox Code Playgroud)

问题是我不认为这个可以在 Linux 或 MacOS 上运行。是否有任何“标准”方法来告诉我的应用程序“像控制台命令一样运行它”?


这是我当前的代码通过使用Platform来确定控制台命令,请随时告诉我是否有更好的方法:

    static IEnumerable<ProcessStartInfo> ParseCommands(string[] args)
    {
        var argsPrepend = "";
        var shellName = "/bin/bash";
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            shellName = "cmd";
            argsPrepend = "/c ";
        }

        return args
            .Skip(1)
            .Select(q => new ProcessStartInfo()
            {
                FileName = shellName,
                Arguments = argsPrepend + q,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                UseShellExecute = false,
            }).ToList();
    }

    static void RunCommand(ProcessStartInfo processInfo)
    {
        Console.WriteLine($"{processInfo.Arguments.Substring(processInfo.FileName == "cmd" ? 3 : 0)}");

        var process = new Process()
        {
            StartInfo = processInfo,
        };
        process.Start();

        while (!process.StandardOutput.EndOfStream)
        {
            Console.WriteLine(process.StandardOutput.ReadLine());
        }

        process.WaitForExit();
    }
Run Code Online (Sandbox Code Playgroud)