Процент в переменной окружения $ PATH

16

Мой $ PATH выглядит так:

/home/torbjorr/deployed/vector/x86_64-GNU%2fLinux:/home/torbjorr/deployed/typewriter/x86_64-GNU%2fLinux:/home/torbjorr/deployed/mustudio/x86_64-GNU%2fLinux:/home/torbjorr/deployed/mathext/x86_64-GNU%2fLinux:/home/torbjorr/deployed/doxymax/x86_64-GNU%2fLinux:/home/torbjorr/deployed/c2tex/x86_64-GNU%2fLinux:/home/torbjorr/deployed/x86_64-GNU%2fLinux/wand:/home/torbjorr/deployed/x86_64-GNU%2fLinux/spellesc:/home/torbjorr/deployed/x86_64-GNU%2fLinux/projinit:/home/torbjorr/deployed/x86_64-GNU%2fLinux/herbs:/home/torbjorr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

В bash я могу без проблем вызвать палочку, расположенную в

/home/torbjorr/deployed/x86_64-GNU%2fLinux/wand

нравиться

$ wand
(i) Mål från "main.cpp" har registrerats
(i) Skapar katalog "__wand_targets_dbg"
(i) Kör g++ "main.cpp" -fpic -L"/home/torbjorr/deployed"  -g -Wall -std=c++11 -I"/home/torbjorr/deployed" -o "__wand_targets_dbg/cb-template

Однако в режиме совместимости с оболочкой Bourne палочка не может быть найдена:

$ wand
sh: 2: wand: not found

Кажется, проблема в том, что знак% в этих путях. Этот знак был добавлен путем кодирования URL, поэтому имя «GNU / Linux» можно использовать в имени каталога, даже если это недопустимое имя файла. Можно ли заставить имя работать в sh или заставить команду sh работать как bash. То есть make bash ведет себя так же, даже если он был вызван с помощью команды / bin / sh, которая в любом случае ссылается на bash.

user877329
источник
Хороший вопрос Кажется, что символ '%' не работает правильно в $ PATH из sh(это нормально bashи zshхотя). Прямой вызов исполняемого файла работает в sh; действительно странно.
Rmano
Что произойдет, если вы используете 2 %%?
mikeserv
Или избежать%?
mdpc

Ответы:

15

Это не оболочка Bourne или bashэмуляция оболочки Bourne, это оболочка Almquist, в вашем случае, вероятно, оболочка Debian Almquist (форк Linux от Debian BSD, основанный на оригинальной оболочке Almquist).

В оболочке Almquist (оригинальной и современной версиях), %используется PATHдля дополнительных функций, специфичных для ash. Цитирование из документации:

Поиск пути

При нахождении команды оболочка сначала проверяет, есть ли у нее функция оболочки с таким именем. Затем, если PATH не содержит записи для %builtin, он ищет встроенную команду с таким именем. Наконец, он ищет каждую запись в PATH по очереди для команды.

Значение переменной PATH должно быть последовательностью записей, разделенных двоеточиями. Каждая запись состоит из имени каталога или имени каталога, за которым следует флаг, начинающийся со знака процента. Текущий каталог должен указываться пустым именем каталога. Если знак процента отсутствует, то запись заставляет оболочку искать команду в указанном каталоге. Если флаг установлен, %builtin то ищется список встроенных команд оболочки. Если флаг установлен, %func то в каталоге выполняется поиск файла, который читается как ввод в оболочку. Этот файл должен определять функцию, имя которой является именем искомой команды.

Имена команд, содержащие косую черту, просто выполняются без выполнения какого-либо из вышеуказанных поисков.

Другие оболочки любят kshили zshимеют похожий механизм автозагрузки функций, но они используют другую переменную ( $FPATH), но вы не можете определить, какая из функций или исполняемых файлов имеет приоритет.

В вашем случае /home/torbjorr/deployed/vector/x86_64-GNU%2fLinuxинтерпретируется как /home/torbjorr/deployed/vector/x86_64-GNUкаталог с 2fLinuxфлагом. Этот флаг игнорируется, поскольку он неизвестен.

Обойти это невозможно. Даже если бы у золы был механизм сброса, чтобы с ним %не обращались специально, он не работал бы в других оболочках или других вещах, которые выглядят $PATHкак execvp().

Вам нужно удалить %символы $PATH, поэтому переименуйте каталог или добавьте символическую ссылку.

Или не используйте ashдля своего /bin/sh. Другие легкие реализации оболочки POSIX, которые этого не делают, включают yashи mksh.

Стефан Шазелас
источник
Хотя этот ответ дает объяснение, он не дает решения. Есть ли совместимый способ хранения%.
user877329
@ user877329, здесь нет реального решения. Смотрите мое редактирование.
Стефан Шазелас
3
Другими словами, Debian shнарушает стандарт POSIX. Учитывая, что смысл иметь отдельное sh- именно то, что вы должны быть уверены, что не перепутали какое-то несовместимое расширение оболочки (я думаю, что никто не использует в /bin/shкачестве оболочки для входа в систему в наши дни), я бы посчитал это ошибкой.
celtschk
1
@celtschk, согласился, хотя смысл использования ashfor / bin / sh больше, чтобы избежать снижения производительности при использовании bash, поэтому использование yashили mksh(или poshесли вы хотите исключить все расширения) все же лучше, чем использование bash. Также можно считать это угловым случаем. Никто обычно не имеет %в компоненте пути. У большинства оболочек есть угловые случаи, когда они не соответствуют POSIX.
Стефан Шазелас
1
@mtmiller, я не так понял значение переносимого набора символов имени файла (PFCS). POSIX определяет API программирования, но не реализации файловой системы. PFCS - это минимальные гарантии POSIX, которые будут работать независимо от файловой системы, независимо от текущей локали, но не являются оправданием для инструмента, не принимающего символ в имени файла, если он поддерживается файловой системой и действителен в текущей локали. Обратите внимание, что, например, POSIX требует наличия [команды, даже если этот символ отсутствует в PFCS.
Стефан Шазелас