首页 > 解决方案 > 为什么在从 C# 创建的进程中运行 bash 命令时我的 $PATH 不同?

问题描述

我在 CentOS 上有一个 .NET 5 程序,它使用 .service 文件从 systemd 服务启动。它需要通过命令行执行另一个程序,所以我写了这些代码:

var processStartInfo = new ProcessStartInfo()
{
    FileName = "/bin/bash",
    Arguments = "-c \"echo $PATH\"",
    WorkingDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
};

var process = Process.Start(processStartInfo);
process.WaitForExit();

从 CentOS 的终端执行时,echo $PATH返回/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/test_user/.local/bin:/home/test_user/bin. 但是echo $PATH使用上面的代码运行给了我/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin

为什么 2 个 $PATH 值不同?搜索 $PATH 给了我一些关于/etc/profile、和的结果~/.bash_profile,但我不确定如何解释这些文件。/etc/bash.bashrc~/.bashrc

标签: c#linuxbash.net-core

解决方案


问题是上面的代码调用了一个非交互式shell,而不是像使用系统控制台时那样的交互式shell。来自 GNU 的 Bash 参考手册,第 1.2 节:

Shell 可以交互或非交互方式使用。在交互模式下,它们接受从键盘输入的输入。当以非交互方式执行时,shell 执行从文件中读取的命令。

$PATH如第 6.2 节所述,交互式和非交互式 shell 在启动时检查值的方式不同。作为交互式 shell,Bash 可以从etc/profile~/.bash_profile~/.bash_login~/.profile中读取$PATH值,但作为非交互式 shell,Bash 只接受环境变量中的任何内容BASH_ENV作为$PATH值:

非交互调用

当 Bash 以非交互方式启动时,例如运行一个 shell 脚本,它会在环境中查找变量 BASH_ENV,如果它出现,则扩展其值,并将扩展值用作要读取和执行的文件的名称.


推荐阅读