как сохранить windows $ PATH, когда sudo su - в windows-subsystem-for-linux - PullRequest
0 голосов
/ 12 октября 2018

Я запускаю Ubuntu (версия 1804.2018.817.0) из Магазина Windows поверх Windows 10 (версия 1803, сборка 17134.345) с использованием Windows Subsystem для Linux.

Когда я впервые открываю консоль, я 'Я вошел в систему с учетной записью, которую я создал при первом запуске Ubuntu.В этом контексте я могу выполнять такие вещи в пути Windows, как cmd.exe.

Однако, когда я переключаюсь в root с помощью sudo su -, переменная $ PATH больше не содержит информацию о пути Windows.Поэтому, когда я набираю cmd.exe, он говорит cmd.exe: command not found.

Мои вопросы:

  1. Откуда берутся значения Window $ PATH, когда я впервые открываю Ubuntu?
  2. Почему пользователь root не получает значения Windows PATH для Windows, когда я использую sudo su -?
  3. Как настроить bash таким образом, чтобы $ PATH содержал значения пути Windows, когда я использую sudo su -, поэтомучто я могу запускать такие команды, как cmd.exe?

1 Ответ

0 голосов
/ 22 ноября 2018

Я отвечаю, хотя эта тема скорее относится к askubuntu .

  1. Откуда берутся значения Window $ PATH, когда я впервые открываю Ubuntu? .
    Из стандартной Windows% PATH% переменная среды , поскольку ubuntu.exe процесс является дочерним для conhost.exe (как и для командной строки Windows cmd.exe).

  2. Почему пользователь root не получает значения Windows $ PATH, когда я использую sudo su -?
    Проверьте sudo sudo -V | grep PATH из wsl приглашения.Прочитайте объяснение 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'

Result (последняя команда смотрит на /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.

Как настроить bash таким образом, чтобы $ PATH содержал значения путей к окну при использовании sudo su -, чтобы я мог запускать такие команды, как cmd.exe?

  • Вы можете использовать опцию env_keep через sudoedit (не рекомендуется по соображениям безопасности ), чтобы сохранить переменные среды вашего пользователя.
  • Для быстрого продвижения скопируйте и вставьте следующее в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!
...