【问题标题】:run bash command from .NetCore with arguments从 .Net Core 运行带有参数的 bash 命令
【发布时间】:2017-12-06 01:34:07
【问题描述】:

我正在尝试从另一个运行一个 .NetCore 程序。

        ProcessStartInfo psi = new ProcessStartInfo();
        psi.FileName = "sh";
        psi.Arguments = "-c dotnet /home/myuser/PublishOutput/myprogram.dll";
        psi.UseShellExecute = false;
        psi.RedirectStandardOutput = true;
        psi.RedirectStandardError = true;

        Process proc = new Process
        {
            StartInfo = psi
        };


        proc.Start();

        string error = proc.StandardError.ReadToEnd();

        if (!string.IsNullOrEmpty(error))
            return "error: " + error;

        string output = proc.StandardOutput.ReadToEnd();

        proc.WaitForExit();

        return output;

作为输出我得到:

Microsoft .NET Core 共享框架主机

版本:1.1.0 构建: 928f77c4bc3f49d892459992fb6e1d5542cb5e86

用法:dotnet [common-options] [[options] path-to-application]

常用选项:--help 显示 .NET Core 共享框架主机帮助。 --version 显示 .NET Core 共享框架主机版本。

选项:--fx-version 安装的版本 用于运行应用程序的共享框架。
--additionalprobingpath 包含要探测的探测策略和程序集的路径。

应用程序路径:.NET Core 托管应用程序的路径, dll 或 exe 文件来执行。

如果您正在调试共享框架主机,请设置“COREHOST_TRACE” 在您的环境中设置为“1”。

要开始为 .NET Core 开发应用程序,请安装 SDK来自:http://go.microsoft.com/fwlink/?LinkID=798306&clcid=0x409

所以我看起来完全像运行命令 dotnet 没有 dll 路径参数。

【问题讨论】:

  • ProcessStartInfo 来自哪个命名空间?

标签: c# .net bash sh .net-core


【解决方案1】:

您需要将参数转义为 -c,使其成为一个参数:

psi.Arguments = "-c \"dotnet /home/myuser/PublishOutput/myprogram.dll\"";

【讨论】:

  • 还是同样的问题。我加了引号,得到了同样的答案。
  • 是完全相同的错误信息吗?我尝试了该示例代码并且它有效。如果 dll 路径错误,您应该收到类似 No executable found matching command 的消息
  • 是的。完全一样。
  • 如果路径中有空格,因此参数中需要引号怎么办?切换到单引号?
  • @formicini 我会先尝试双重转义 - \\\"
【解决方案2】:

如果您想从您的 c# .net 核心应用程序中运行带有特定命令(例如find / -name image.png)的 Linux 程序,您可以使用以下 sn-p:

            try
            {
                var process = new Process();
                var processStartInfo = new ProcessStartInfo()
                {
                    WindowStyle = ProcessWindowStyle.Hidden,
                    FileName = $"/bin/bash",
                    WorkingDirectory = workingDirectory = "/mnt",
                    Arguments = $"-c \"find / -name image.png\"",
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    UseShellExecute = false
                };
                process.StartInfo = processStartInfo;
                process.Start();

                String error = process.StandardError.ReadToEnd();
                String output = process.StandardOutput.ReadToEnd();

            }
            catch(Exception ex)
            {
                //_logger.LogError(ex.Message, ex);
                throw;
            }

参数说明:

  • FileName = $"/bin/bash" 用于您可能使用的所有 shell 命令
  • WorkingDirectory = workingDirectory = "/mnt" 只是一个示例,如果您正在运行的命令需要文件(例​​如 file.png),则此目录很重要,它会相对于工作目录来获取文件
  • Arguments = $"-c "find / -name image.png"" 在 cli 中运行以下命令:/bin/bash -c "find / -name image.png"

-c 是强制它工作的必要条件,如manpage 中所写:

-c 字符串
如果存在 -c 选项,则从字符串中读取命令。如果在字符串之后有参数>,则将它们分配给位置参数,从 $0 开始。

【讨论】:

    【解决方案3】:

    我改变了一些东西,使消息可以输出同步

    using System;
    using System.Diagnostics;
    using System.Threading.Tasks;
    
    namespace ExecuteCommandX
    {
     /// <summary>
    ///  sample by linkanyway@gmail.com
    /// </summary>
    /// <param name="args"></param>
    internal static class Program
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="args"></param>
        // ReSharper disable once UnusedParameter.Local
        private static void Main(string[] args)
        {
            var psi = new ProcessStartInfo
            {
                FileName = "ping",
                Arguments = "-c 3 8.8.8.8",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true
            };
    
            var proc = new Process
            {
                StartInfo = psi
            };
    
            proc.Start();
    
    
    
            Task.WaitAll(Task.Run(() =>
            {
                while (!proc.StandardOutput.EndOfStream)
                {
                    var line = proc.StandardOutput.ReadLine();
                    Console.WriteLine(line);
                }
            }), Task.Run(() =>
            {
                while (!proc.StandardError.EndOfStream)
                {
                    var line = proc.StandardError.ReadLine();
                    Console.WriteLine(line);
                }
            }));
    
    
            proc.WaitForExit();
            Console.WriteLine(proc.ExitCode);
        }
    }
    

    }

    【讨论】:

      猜你喜欢
      • 2011-08-23
      • 1970-01-01
      • 2018-02-15
      • 2022-08-18
      • 1970-01-01
      • 2021-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多