Тильда в PATH может указывать не на ваш HOME
Don't Put Tilde In Your Path

В bash и zsh тильда раскрывается в домашний каталог только в неприкавыченных строках или сразу после = и : в присваиваниях. Если написать export PATH="$PATH:~/.local/bin/", то в PATH попадёт буквальная тильда, и оболочка будет искать программы в подкаталоге ./~/.local/bin/ относительно текущей директории. Автор показывает, как это приводит к запуску подставного бинарника, и советует заменить ~ на $HOME.
Bash проверяет каждое присваивание переменной на неприкавыченные тильда-префиксы сразу после ‘:’ или первого ‘=’, и выполняет раскрытие тильды в этих случаях.
- SoftTalker
Я никогда не использую тильду в скриптах, только для удобства при вводе команд в интерактивном режиме.
В остальных случаях $HOME, у которого тоже есть свои подводные камни, но они такие же, как у любой другой переменной окружения.
- amarshall
Или можно просто… не брать тильду в кавычки. Люди, кажется, всегда рефлекторно берут в кавычки «строки» в Bash, не осознавая, что (почти) всё является строкой, а большинство строк не заключается в кавычки, и это было бы странно (например, никто не пишет `"ls" "-a" "foo"`).
- thefilmore
Можно просто сделать:
PATH=~/.local/bin:$PATH
PATH уже экспортирована. Кавычки для присваиваний тоже не нужны.
- FeepingCreature
Вроде бы ты должен был заметить это по тому, что твой ~/.local/bin в PATH не работает?
- alexpotato
Не обязательно про тильды, но про некоторые безумства, которые могут происходить с bash в крупных организациях:
На прошлой работе я пытался выяснить, какая часть моего bashrc устанавливает конкретную переменную окружения. Я предположил, что это какая-то настройка по умолчанию в моём пользовательском профиле и/или наследуется из /etc/<что-то>.
Я довольно быстро понял, что мой bashrc импортирует какие-то другие файлы. Опять же, предполагалось, что это будет один файл на уровне импорта.
Оказалось, что там было 10+ уровней импорта, начиная с «ur-bashrc», а затем слой за слоем всё больше и больше импортов, чтобы в итоге добраться до профиля пользовательского уровня.
Это было настолько запутанно, что я сходил с ума, пока не нашёл этот пост на Stack Exchange: https://unix.stackexchange.com/questions/813/how-to-determin...
Он включает «трассировку» для импортов bash, чтобы затем можно было сузить круг поиска того, где устанавливается переменная окружения.
- dspillett
Я собирался сказать «у меня это всегда вроде бы работает», а потом увидел «… на самом деле работает в Bash и Zsh, потому что …».
Ещё один bash-изм, который мне нужно осторожно не использовать, когда я пытаюсь быть переносимым.
Стоит отметить, что во многих системах /bin/sh — это не bash (и не zsh), так что если вы хотите полагаться на bash-измы (или просто не хотите утруждать себя их поиском), будьте конкретны и используйте «#!/bin/bash» в качестве шебанга. В Debian и подобных системах это обычно dash, например.
- the__alchemist
Хотелось бы, чтобы дистрибутивы Linux поставляли программу «Терминал»/«CLI» и т.п., отделённую от скриптового языка. Имели универсальную переменную окружения Path, не привязанную к конкретной оболочке. Позволяли выполнять команды cd, запускать python/git/cargo/произвольные приложения и т.д., и имели хорошую систему закладок и автодополнения. Кажется, что смешение скриптового языка и CLI-приложения — корень этих сложностей и тонкостей.
Если вы используете shell-скриптинг (и предпочитаете Bash и т.п. вместо Python), вы бы продолжали использовать Bash/Fish/Zsh и т.д. Если вы используете CLI для запуска приложений без GUI, навигации по каталогам и выполнения операций с файловой системой, то вы бы использовали простой терминал.
- ligarota
Просто создайте файл ~, который является симлинком на домашний каталог :)
Вот это уровень большого мозга