Expanding the PATH with a list of directories extracted from a text file, the '~' character not expanded to HOME

为君一笑 提交于 2019-12-13 01:42:45

问题


The PATH is expanded by a list of directories extracted from a text file;

$ 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

like so (The following can be found in one of the BASH's startup files):

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

Basic iteration over the array of PATH expansion entries extracted from the ~/.path file. The resultant PATH includes the '~' character (which is wrong hence the question):

$ echo $PATH
/usr/local/sbin:/usr/local/bin:~/.local/bin

Inside of the ~/.local/bin there exists a bl script I am able to invoke, like so:

$ 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!
$

However some undesired effects were briefly discussed in the 'sh' environment does not respect the PATH extensions, user's local PATH not in effect? question and include symptoms such as the following:

$ bl 1
$ sh -c 'bl 1'
sh: bl: command not found
$
$ bl 1
$ whereis bl
bl:
$

The consensus was that the '~' character should be expanded to the user's HOME before the PATH expansion. How can it be achieved, while also keeping an external file as a source of directories for the PATH expansion? Where lays the issue with the current approach? Help much appreciated :)


回答1:


TL;DR Just replace ~ yourself, something like:

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

The ~ is expanded during tilde expansion. The tilde ~ is then replaced by the content of the user variable HOME.

The shell expansions happen for example when shell interprets a line. So when a user types echo ~ it nicely prints echo /home/kamil.

Tilde expansion (or any other shell expansion) doesn't happen when interpreting the PATH variable. How PATH is interpreted is specified in POSIX environment variables 8.3. It has it's own rules, that are unrelated to shell expansions and unrelated to tilde expansion.

How can it be achieved

You have to create your own shell that doesn't conform to posix and does tilde expansion when searching the PATH variable during command search and execution. Such shell would be nonconforming. The easiest approach would be to take bash and patch it.

A more realistic approach is just to replace the ~ in the content of your file by $HOME content or while reading the stream with simple sed replacement.

Where lays the issue with the current approach?

The issue most probably comes from misinterpreting the way shell operates - where the expansions work.



来源:https://stackoverflow.com/questions/58918101/expanding-the-path-with-a-list-of-directories-extracted-from-a-text-file-the

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!