PATH由从文本文件中提取的目录列表展开;
$ cat ~/.path
~/.local/bin
~/W-space/esp/esp-open-sdk/xtensa-lx106-elf/bin
~/W-space/research/recognition/voxforge/bin
~/W-space/research/recognition/voxforge/bin/julius-4.3.1/bin
像这样(以下可以在BASH的一个启动文件中找到(:
declare -a BATH_ARRAY=($(cat ~/.path)) 2>/dev/null # extend path
for BATH in "${BATH_ARRAY[@]}"
do
case ":${PATH}:" in
*:${BATH}:*) ;;
*) PATH=${PATH}:$BATH && export PATH;;
esac
done
从~/.path
文件中提取的PATH扩展项数组的基本迭代。生成的PATH包括"~"字符(这是错误的,因此有问题(:
$ echo $PATH
/usr/local/sbin:/usr/local/bin:~/.local/bin
在~/.local/bin
内部有一个我可以调用的bl
脚本,如下所示:
$ ls -l ~/.local/bin/bl
-rwxr-xr-x 1 romeo romeo 6304 Nov 17 09:06 /home/romeo/.local/bin/bl*
$ bl 1 #no error!
$
然而,在"sh"环境中简要讨论了一些不希望的影响。是否不尊重PATH扩展,用户的本地PATH是否有效?问题并包括以下症状:
$ bl 1
$ sh -c 'bl 1'
sh: bl: command not found
$
$ bl 1
$ whereis bl
bl:
$
一致认为,在PATH扩展之前,应该将"~"字符扩展到用户的HOME。如何做到这一点,同时保留一个外部文件作为PATH扩展的目录源?当前方法的问题在哪里?非常感谢您的帮助:(
TL;DR只需自己更换~
,类似于:
while IFS=$'n' read -r BATH; do
# also ex. readlink -m could be added to shorten the path
case ":${PATH}:" in
*:${BATH}:*) ;;
*) PATH=${PATH}:$BATH ;;
esac
done < <(sed 's~^~~'"$HOME"'~' .path)
export PATH
~
在波浪号展开过程中展开。波浪号CCD_ 6随后被用户变量CCD_。
shell展开发生在例如shell解释一行时。因此,当用户键入echo ~
时,它会很好地打印echo /home/kamil
。
在解释PATH
变量时,不会发生颚化符展开(或任何其他shell展开(。如何解释PATH
在POSIX环境变量8.3中指定。它有自己的规则,这些规则与shell展开无关,也与波浪形展开无关。
如何实现
您必须创建自己的shell,该shell不符合posix,并且在命令搜索和执行期间搜索PATH变量时进行波浪形扩展。这样的外壳是不合格的。最简单的方法是抨击并修补它
更现实的方法是用$HOME
内容替换文件内容中的~
,或者在读取流时用简单的sed
替换。
当前方法的问题在哪里?
这个问题很可能是由于误解了shell的操作方式——扩展的工作方式。