Ubuntu Linux下运行VS2019开发的C#调用Shell命令代码的解决方法
Linux环境下C#调用系统命令的调整方案
核心问题根因
当前修改后的代码无法在Ubuntu 20.04正常运行,是和Windows环境的行为逻辑差异直接相关的两类常见问题:
- 执行单次bash命令必须传入
-c参数,作用等价于Windows下cmd的/c参数:将后续字符串作为待执行命令传入shell,执行完成后自动退出。漏写该参数时,bash会将后续的ls识别为待打开的脚本文件路径查找,根本不会执行列目录操作。 - 跨平台.NET运行时中,当以直接启动子进程的方式运行程序时,子进程的标准输出、错误输出默认不会关联到当前父进程的控制台,会被直接丢弃,即使命令执行成功,也看不到任何打印结果。
具体调整步骤
- 补全bash的必填执行参数
替换原来仅写ls的Arguments值,将待执行命令包裹在-c后的字符串中,注意转义内层引号。如果要对应原Windows环境下列桌面目录的逻辑,可替换为bash识别的Linux路径写法:// 基础执行当前目录列文件的写法 myProcess.Arguments = "-c \"ls\""; // 对应列用户桌面的写法 myProcess.Arguments = "-c \"ls ~/Desktop\""; - 配置进程输出绑定,保证执行结果可见
关闭系统Shell启动的关联逻辑,开启标准输出、错误输出的重定向,主动读取子进程的输出内容并打印:myProcess.UseShellExecute = false; // 跨平台必须显式配置,避免触发兼容问题 myProcess.RedirectStandardOutput = true; myProcess.RedirectStandardError = true; - 补全代码语法结构
原代码缺失Main方法的结束大括号,需补全对应语法保证正常编译。
修正后的完整可运行代码
using System; using System.Diagnostics; namespace CrossPlatformProcessDemo { class Program { static void Main(string[] args) { ProcessStartInfo myProcess = new ProcessStartInfo("/bin/bash"); myProcess.Arguments = "-c \"ls ~/Desktop\""; myProcess.UseShellExecute = false; myProcess.RedirectStandardOutput = true; myProcess.RedirectStandardError = true; Process runningProcess = Process.Start(myProcess); string output = runningProcess.StandardOutput.ReadToEnd(); string error = runningProcess.StandardError.ReadToEnd(); runningProcess.WaitForExit(); Console.WriteLine("命令执行结果:"); Console.WriteLine(output); if (!string.IsNullOrWhiteSpace(error)) { Console.WriteLine("执行报错信息:"); Console.WriteLine(error); } } } }
常见排查点
- 若提示“没有那个文件或目录”:检查bash路径是否正确,Ubuntu 20.04默认bash路径为
/bin/bash,不存在的话可直接写bash让系统从环境变量自动查找。同时确认目标路径是否存在——纯命令行版的Ubuntu没有图形化环境时,不会自动创建~/Desktop目录,可先执行ls列主目录验证基础功能是否正常。 - 若遇到权限报错:检查当前运行程序的用户,对要访问的路径是否具备读取权限。
- 发布时的注意事项:你使用的
dotnet publish -c release -r ubuntu.20.04-x64命令没有问题,不需要额外调整,只要保证目标Ubuntu系统的glibc版本和20.04匹配即可正常运行。
注意:漏写bash的
-c参数是跨平台迁移时的最高发问题,表现和Windows下漏写cmd的/c参数完全一致,排查时可优先检查该配置。
内容的提问来源于stack exchange,提问作者zainmaster
相关产品推荐
相关产品推荐

