虽然这个话题属于askubuntu,但我还是回答了。
当我第一次打开 Ubuntu 时,Window $PATH 的值是从哪里来的?。
来自标准Windows %PATH% environment variable,因为ubuntu.exe 进程是conhost.exe(以及Windows 命令提示符cmd.exe)的子进程。
当我使用 sudo su - 时,为什么 root 用户无法获得 Windows $PATH 值?
在 wsl 提示符下检查 sudo sudo -V | grep PATH。阅读man sudo了解解释:
ENVIRONMENT
sudo utilizes … environment variables. The security policy
has control over the actual content of the command's environment.
…
PATH May be overridden by the security policy.
默认的安全策略是sudoers,通过以下方式配置
文件/etc/sudoers。
试试这个说明性示例(将以下三个命令分别粘贴到打开的cmd 命令提示符中):
wsl echo ${#PATH}
wsl sudo su -c 'echo ${PATH} ^&^& echo ${#PATH}'
wsl sudo su - -c 'echo ${PATH} ^&^& echo ${#PATH} ^&^& cat /etc/sudoers ^| grep Default'
结果(后面的命令也会查看/etc/sudoers):
d:\test> wsl echo ${#PATH}
1557
d:\test> wsl sudo su -c 'echo ${PATH} ^&^& echo ${#PATH}'
[sudo] password for user:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
88
d:\test> wsl sudo su - -c 'echo ${PATH} ^&^& echo ${#PATH} ^&^& cat /etc/sudoers ^| grep Default'
[sudo] password for user:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
70
Defaults env_reset
Defaults mail_badpass
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
阅读man sudoers 以进一步了解默认值 选项:
env_reset If set, sudo will run the command in a minimal environment containing
the TERM, PATH, HOME, MAIL, SHELL, LOGNAME, USER, USERNAME and SUDO_*
variables… If the secure_path option is set, its value will be used
for the PATH environment variable. This flag is on by default.
secure_path Path used for every command run from sudo. If you don't trust the people
running sudo to have a sane PATH environment variable you may want to use
this. Another use is if you want to have the “root path” be separate from
the “user path”. Users in the group specified by the exempt_group option
are not affected by secure_path. This option is not set by default.
-
当我使用sudo su - 时,如何配置bash 使$PATH 包含窗口路径值,以便我可以运行cmd.exe 之类的命令?
- 您可以通过
sudoedit 使用env_keep 选项(不推荐用于security reasons)来保留用户的环境变量。
- 为了快速前进,请将以下内容复制并粘贴到
root 提示符中。它将当前 Windows %path% 变量中的所有文件夹路径添加到 $PATH。您可以考虑将其设为.sh 脚本并添加一些高级逻辑:
cmd.exe /c echo works! # merely for documentation
echo "${#PATH}" # merely for documentation
cmd_path=`/mnt/c/Windows/System32/cmd.exe /C echo "%path:\\\\=\\\\\\\\%"`
OIFS="$IFS" # backup $IFS
IFS=';'
read -a c_p_n <<< "${cmd_path}"
IFS="$OIFS" # restore $IFS
OPATH="${PATH}" # backup $PATH
for i in "${!c_p_n[@]}"; do PATH=${PATH%/}:$(sed -e 's#^\(.\):#/mnt/\L\1#' -e 's#\\#/#g' <<< "${c_p_n[$i]}"); done
echo "${#PATH}" # merely for documentation
cmd.exe /c echo works! # merely for documentation
结果:
user@COMP:~$ sudo su -
root@COMP:~# cmd.exe /c echo works! # merely for documentation
cmd.exe: command not found
root@COMP:~# echo "${#PATH}" # merely for documentation
70
root@COMP:~# cmd_path=`/mnt/c/Windows/System32/cmd.exe /C echo "%path:\\\\=\\\\\\\\%"`
root@COMP:~# OIFS="$IFS" # backup $IFS
root@COMP:~# IFS=';'
root@COMP:~# read -a c_p_n <<< "${cmd_path}"
root@COMP:~# IFS="$OIFS" # restore $IFS
root@COMP:~# OPATH="${PATH}" # backup $PATH
root@COMP:~# for i in "${!c_p_n[@]}"; do PATH=${PATH%/}:$(sed -e 's#^\(.\):#/mnt/\L\1#' -e 's#\\#/#g' <<< "${c_p_n[$i]}"); done
root@COMP:~# echo "${#PATH}" # merely for documentation
1555
root@COMP:~# cmd.exe /c echo works! # merely for documentation
works!