Pourcentage dans la variable d'environnement $ PATH

16

Mon $ PATH ressemble à ceci:

/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

En bash, je peux sans problème invoquer la baguette située dans

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

comme

$ 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

Cependant, en mode de compatibilité shell bourne, la baguette est introuvable:

$ wand
sh: 2: wand: not found

Il semble que le problème soit le signe% dans ces chemins. Ce signe a été ajouté par codage URL afin que le nom "GNU / Linux" puisse être utilisé dans le nom du répertoire même s'il ne s'agit pas d'un nom de fichier valide. Est-il possible de faire fonctionner le nom dans sh, ou de faire fonctionner la commande sh comme bash. C'est-à-dire, faire en sorte que bash se comporte de la même manière, même s'il a été invoqué avec la commande / bin / sh, qui crée quand même un lien symbolique avec bash.

user877329
la source
Bonne question. Il semble que le caractère '%' ne fonctionne pas correctement dans $ PATH à partir de sh(il est correct dans bashet zshcependant). L'appel direct de l'exécutable fonctionne dans sh; vraiment étrange.
Rmano
Que se passe-t-il si vous utilisez 2 %%?
mikeserv
Ou échapper au%?
mdpc

Réponses:

15

Ce n'est pas le shell Bourne, ou bashémuler le shell Bourne, c'est le shell Almquist, dans votre cas probablement le shell Debian Almquist (un fork Linux par Debian de BSDs sh lui-même basé sur le shell Almquist original).

Dans la coque Almquist (l'original et les versions modernes), %est utilisé PATHpour des fonctionnalités supplémentaires spécifiques à ash. Citant de la documentation:

Recherche de chemin

Lors de la localisation d'une commande, le shell cherche d'abord à voir s'il a une fonction shell de ce nom. Ensuite, si PATH ne contient pas d'entrée pour %builtin, il recherche une commande intégrée portant ce nom. Enfin, il recherche tour à tour chaque entrée de PATH pour la commande.

La valeur de la variable PATH doit être une série d'entrées séparées par des deux-points. Chaque entrée se compose d'un nom de répertoire ou d'un nom de répertoire suivi d'un indicateur commençant par un signe de pourcentage. Le répertoire courant doit être indiqué par un nom de répertoire vide. Si aucun signe de pourcentage n'est présent, l'entrée oblige le shell à rechercher la commande dans le répertoire spécifié. Si l'indicateur est %builtin alors la liste des commandes intégrées du shell est recherchée. Si l'indicateur est %func alors le répertoire est recherché pour un fichier qui est lu comme entrée dans le shell. Ce fichier doit définir une fonction dont le nom est le nom de la commande recherchée.

Les noms de commandes contenant une barre oblique sont simplement exécutés sans effectuer aucune des recherches ci-dessus.

D'autres shells aiment kshou zshont un mécanisme de chargement automatique des fonctions similaire, mais ils utilisent une variable différente ( $FPATH), mais vous ne pouvez pas définir lesquelles des fonctions ou des exécutables ont la priorité.

Dans votre cas, /home/torbjorr/deployed/vector/x86_64-GNU%2fLinuxest interprété comme le /home/torbjorr/deployed/vector/x86_64-GNUrépertoire avec le 2fLinuxdrapeau. Ce drapeau est ignoré car il est inconnu.

Il n'y a pas de chemin aux alentours. Même si les cendres avait un mécanisme d'échappement pour que ce %ne soit pas traité spécialement, il travaillerait alors pas dans d' autres coquilles ou d' autres choses qui admirent $PATHcomme execvp().

Vous devrez supprimer les %caractères de $PATH, alors renommez votre répertoire ou ajoutez un lien symbolique.

Ou ne l'utilisez pas ashpour votre /bin/sh. D'autres implémentations de shell POSIX légères qui ne font pas cela incluent yashet mksh.

Stéphane Chazelas
la source
Bien que cette réponse donne une explication, elle ne donne pas de solution. Existe-t-il un moyen compatible de conserver%.
user877329
@ user877329, il n'y a pas de vraie solution ici. Voir mon montage.
Stéphane Chazelas
3
En d'autres termes, Debian shviole le standard POSIX. Étant donné que le point d'avoir un séparé shest exactement que vous devriez être sûr de ne pas trébucher sur une extension de shell incompatible (je suppose que personne n'utilise /bin/shcomme shell de connexion ces jours-ci), je considérerais cela comme un bug.
celtschk
1
@celtschk, d'accord, bien que l'utilisation ashde / bin / sh soit plus pour éviter la pénalité de performance de l'utilisation bash, donc l'utilisation de yashou mksh(ou poshsi vous souhaitez exclure toutes les extensions) est toujours une meilleure option que l'utilisation bash. En outre, on peut le considérer comme un cas d'angle. Personne n'aurait normalement %dans un composant de chemin d'accès. La plupart des coques ont des boîtiers d'angle où ils ne sont pas conformes à POSIX.
Stéphane Chazelas
1
@mtmiller, ce n'est pas ainsi que j'ai lu la signification du jeu de caractères de nom de fichier portable (PFCS). POSIX spécifie les API de programmation mais pas les implémentations du système de fichiers. le PFCS est la garantie POSIX minimale qui fonctionnera quel que soit le système de fichiers, quel que soit l'environnement local actuel, mais ce n'est pas une excuse pour qu'un outil n'accepte pas un caractère dans un nom de fichier s'il est pris en charge par le système de fichiers et valide dans l'environnement local actuel. Notez que par exemple POSIX nécessite qu'il y ait une [commande même si ce caractère n'est pas dans le PFCS.
Stéphane Chazelas