Procent zmiennej środowiskowej $ PATH


16

Moja $ PATH wygląda następująco:

/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

W bashu mogę bez problemu wywołać różdżkę znajdującą się w

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

lubić

$ 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

Jednak w trybie zgodności z powłoką Bourne'a nie można znaleźć różdżki:

$ wand
sh: 2: wand: not found

Wygląda na to, że problemem jest znak% na tych ścieżkach. Ten znak został dodany przez kodowanie URL, więc nazwa „GNU / Linux” może być używana w nazwie katalogu, nawet jeśli nie jest to poprawna nazwa pliku. Czy to możliwe, aby nazwa działała w sh, lub sprawić, aby polecenie sh działało jako bash. Oznacza to, że bash zachowuje się tak samo, mimo że został wywołany za pomocą polecenia / bin / sh, które i tak łączy dowiązania symboliczne.


Fajne pytanie. Wygląda na to, że znak „%” nie działa poprawnie w $ PATH od sh(jest w porządku bashi zshmimo to). Bezpośrednie wywołanie pliku wykonywalnego działa w sh; naprawdę dziwne.
Rmano

Co się stanie, jeśli użyjesz 2 %%?
mikeserv

Lub uciec od%?
mdpc

Odpowiedzi:


15

To nie jest powłoka Bourne'a, ani bashemulująca powłoka Bourne'a, to powłoka Almquista, w twoim przypadku prawdopodobnie powłoka Debiana Almquist (rozwidlenie Linuksa autorstwa samego Debiana z BSDs oparte na oryginalnej powłoce Almquist).

W skorupie Almquist (oryginalna i współczesna wersja) %zastosowano PATHdodatkowe funkcje charakterystyczne dla ash. Cytowanie z dokumentacji:

Wyszukiwanie ścieżki

Podczas lokalizowania polecenia powłoka najpierw sprawdza, czy ma funkcję powłoki o tej nazwie. Następnie, jeśli PATH nie zawiera pozycji dla %builtin, szuka wbudowanej komendy o tej nazwie. Na koniec przeszukuje kolejno każdy wpis w PATH w poszukiwaniu polecenia.

Wartość zmiennej PATH powinna być serią wpisów oddzielonych dwukropkami. Każda pozycja składa się z nazwy katalogu lub nazwy katalogu, po której następuje flaga rozpoczynająca się znakiem procentu. Bieżący katalog powinien być oznaczony pustą nazwą katalogu. Jeśli nie ma znaku procentu, wpis powoduje, że powłoka szuka polecenia w określonym katalogu. Jeśli flaga jest, %builtin wówczas przeszukiwana jest lista wbudowanych poleceń powłoki. Jeśli flaga jest, %func wówczas katalog jest przeszukiwany w poszukiwaniu pliku, który jest czytany jako dane wejściowe do powłoki. Ten plik powinien definiować funkcję, której nazwa jest nazwą szukanego polecenia.

Nazwy poleceń zawierające ukośnik są po prostu wykonywane bez wykonywania żadnego z powyższych wyszukiwań.

Inne pociski lubią kshlub zshmają podobny mechanizm funkcje automatyczne ładowanie, ale użyć innej zmiennej ( $FPATH), ale nie można określić, która z funkcji lub pliki wykonywalne mają pierwszeństwo.

W twoim przypadku /home/torbjorr/deployed/vector/x86_64-GNU%2fLinuxjest interpretowany jako /home/torbjorr/deployed/vector/x86_64-GNUkatalog z 2fLinuxflagą. Ta flaga jest ignorowana, ponieważ nie jest znana.

Nie można tego obejść. Nawet jeśli popiół miał mechanizm ucieczki, tak, że ten %nie może być traktowany specjalnie, byłoby to nie praca w innych skorup lub innych rzeczy, które wyglądają się $PATHjak execvp().

Musisz usunąć %znaki z $PATH, więc zmień nazwę katalogu lub dodaj dowiązanie symboliczne.

Lub nie używaj ashdo swojego /bin/sh. Inne lekkie implementacje powłoki POSIX, które tego nie robią, obejmują yashi mksh.


Chociaż ta odpowiedź zawiera wyjaśnienie, nie daje rozwiązania. Czy istnieje kompatybilny sposób przechowywania%.
user877329,

@ user877329, nie ma tutaj prawdziwego rozwiązania. Zobacz moją edycję.
Stéphane Chazelas

3
Innymi słowy, Debian shnarusza standard POSIX. Biorąc pod uwagę, że oddzielne shjest dokładnie to, że powinieneś być pewien, że nie potkniesz się o jakieś niekompatybilne rozszerzenie powłoki (chyba nikt nie używa obecnie /bin/shpowłoki logowania), uważam to za błąd.
celtschk

1
@celtschk, zgodziło się jednak, że celem użycia ashfor / bin / sh jest więcej, aby uniknąć obniżenia wydajności bash, więc używanie yashlub mksh(lub poshjeśli chcesz wykluczyć wszystkie rozszerzenia) jest nadal lepszą opcją niż używanie bash. Można również uznać to za przypadek narożny. Nikt normalnie nie miałby %elementu ścieżki. Większość powłok ma narożne przypadki, w których nie są zgodne z POSIX.
Stéphane Chazelas

1
@mtmiller, nie tak czytam znaczenie zestawu znaków przenośnej nazwy pliku (PFCS). POSIX określa API programowania, ale nie implementacje systemu plików. PFCS to minimalne gwarancje POSIX, które będą działać bez względu na system plików, niezależnie od bieżących ustawień narodowych, ale nie jest usprawiedliwieniem dla narzędzia, które nie przyjmuje znaku w nazwie pliku, jeśli jest obsługiwany przez system plików i jest ważny w bieżących ustawieniach narodowych. Zauważ, że na przykład POSIX wymaga [polecenia, mimo że tego znaku nie ma w PFCS.
Stéphane Chazelas
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.