将 PATH 变量拆分为几行

将 PATH 变量拆分为几行

我已将文件中的 PATH 变量分成几行,以使它们更易于阅读,因为它很长,正如我所见这里。这就是我的更改/etc/profile

#  PATH="/usr/share/python-wheels:/usr/share/gcc/python/usr/lib/python3/dist-pa>
#  PATH="/usr/share/doc:/usr/lib/python3:/usr/lib/python3/dist-packages:/usr/lib/cups/backend:usr/lib/python3.11:/usr/src/python3.11:/sbin:/bin"

path+=(
/usr/local/bin
/usr/bin
/bin
/usr/local/games
/usr/games
/home/lm/local/pipx/venvs/esptool
/usr/share/python-wheels
/usr/share/gcc/python
/usr/lib/python3/dist-packages/pip/_vendor/pygments/lexers
/usr/share/doc
/usr/lib/python3
/usr/lib/python3/dist-packages
/usr/lib/cups/backend
/usr/lib/python3.11
/usr/src/python3.11
/sbin
/bin
)
export PATH

然后我跑了

source ~/.profile

并且echo $PATH没有改变:

root@debian:/home/lm# echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/home/lm/.local/bin:/root/.local/bin:/root/.local/bin:/root/.local/bin:/root/.local/bin:/root/.local/bin

root@debian:/etc/default# source /etc/profile
root@debian:/etc/default# echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/home/lm/.local/bin:/root/.local/bin

即使重新启动 XFCE 或重新启动后 PATH 仍然是默认值。

有什么问题以及如何修复此问题以使 PATH 新设置将被接受?

我的系统是 Debian 12 和 XFCE

答案1

首先,如果你使用 bash,path那不是问题。 Bash 只有PATH.现在,如果您只想格式化 shell 配置文件以使其更易于阅读,您可以执行以下操作:

path_dirs=(
/usr/local/bin
/usr/bin
/bin
/usr/local/games
/usr/games
/home/lm/local/pipx/venvs/esptool
/usr/share/python-wheels
/usr/share/gcc/python
/usr/lib/python3/dist-packages/pip/_vendor/pygments/lexers
/usr/share/doc
/usr/lib/python3
/usr/lib/python3/dist-packages
/usr/lib/cups/backend
/usr/lib/python3.11
/usr/src/python3.11
/sbin
/bin
)

for path in "${path_dirs[@]}"; do
  PATH="$PATH:$path"
done
export PATH

这只是创建一个数组path_dirs,存储您想要在PATH.然后,您迭代该数组并将每个条目附加到PATH.

请注意,如果您的任何目录包含空格,则需要将其加引号:

path_dirs=(
...
"/some/path/with a space/"
...
)

另外,您不能添加名称包含换行符的目录,但据我所知,无论如何您都不能这样做。

最后,您可能还想使用一个类似的功能pathmunge,我认为它是 Red Hat/Fedora 系统附带的功能。无论如何,我已经拥有它~/.profile近 20 年了,而且非常方便:

pathmunge () {
        if ! echo $PATH | /bin/grep -Eq "(^|:)$1($|:)" ; then
           if [ "$2" = "after" ] ; then
              PATH=$PATH:$1
           else
              PATH=$1:$PATH
           fi
        fi
}

该函数检查路径中是否已存在某些内容,如果不存在,则将其添加到变量的开头或结尾PATH。将函数粘贴到您的~/.profile文件中,然后您可以运行:

## add a directory to the beginning of the path (prepend)
pathmunge /some/dir after
## add a directory to the end of the path (append)
pathmunge /some/dir

这意味着您可以将您的更改~/.profile为:

for path in "${path_dirs[@]}"; do
  pathmunge "$path" after
done

答案2

path本质上并不是PATH同一件事。

另外, /etc/profile 内容确实应该与 /bin/sh 兼容,但事实并非如此。恐怕这一切都不会如你所愿。试试这个:复制您拥有的代码并sh从终端运行,粘贴代码,检查$path和“$PATH$”。

答案3

在处理“冒号分隔”列表(PATH就是一个例子)时,我使用 Stephen Collyer 的 bash_path_funcs,该函数早在 2000 年就在 Linux Journal 中描述过:

https://www.linuxjournal.com/article/3645 https://www.linuxjournal.com/article/376​​8 https://www.linuxjournal.com/article/3935

addpath仅当路径中最初不存在该条目时,该函数才会将其添加到路径中。delpath -n从路径中删除所有不存在的目录。listpath列出一个路径。

您可以pathfunc.tgz从以下位置获取该文件 https://web.archive.org/web/20061210054813/http://www.netspinner.co.uk:80/Downloads/pathfunc.tgz

答案4

您的代码是特定于 zsh 的。/etc/profile是系统范围的(所以对于每个用户)会议调用时由类似 Bourne 的 shell 解释的初始化文件登录shell(作为第 0-参数的第一个字符)。

zsh本身仅在shksh模拟时读取它,例如使用-sh-ksh作为第 0 个参数调用时。

所以该文件应该符合sh语法。 POSIXsh语法应该可以,除非在仍然具有 Bourne shell 的系统上,尽管这在当今时代非常罕见。

但如今,登录会话通常是图形化的,并且/etc/profile很少~/.profile用于设置环境。您可能会在~/.xsession~/.xinitrc或 之类的事情上有更多的运气~/.pam_environment

现在要在 POSIX sh 语法中添加元素$PATH,您可以定义一个函数,例如:

add_to_PATH() for _dir do
  case ":$PATH:" in
    (*:"$_dir":*) ;; # already there
    (*) PATH="$PATH${PATH:+:}$_dir";;
  esac
done

add_to_PATH     \
  /my/dir       \
  /my/other/dir \
  ...

该语法也是zsh- 兼容(尽管显然有更简单的方法可以在zsh)和bash- 兼容(大多数 POSIXsh代码是 bash 兼容的,因为bash与标准的偏差比 少得多zsh),因此代码可以由其中任何一个读取shell 以及所有 POSIX 兼容的 shell。

唯一与 Bourne 不兼容的是(*:"$_dir":*)and (*),需要将其更改为*:"$_dir":*)and *)(对于旧版本的 Bourne shell,# comments最初仅支持 csh(直到 80 年代中期))。

相关内容