我已将文件中的 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/3768 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
本身仅在sh
或ksh
模拟时读取它,例如使用-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 年代中期))。