Porcentagem na variável de ambiente $ PATH

16

Meu $ PATH fica assim:

/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

No bash, posso, sem problemas, chamar a varinha localizada em

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

gostar

$ 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

No entanto, no modo de compatibilidade do shell bourne, o wand não pode ser encontrado:

$ wand
sh: 2: wand: not found

Parece que o problema é o sinal de% nesses caminhos. Este sinal foi adicionado pela codificação de URL para que o nome "GNU / Linux" possa ser usado no nome do diretório, mesmo que não seja um nome de arquivo válido. É possível obter o nome trabalhando em sh ou fazer o comando sh funcionar como bash. Ou seja, faça o bash se comportar da mesma maneira, mesmo que tenha sido chamado com o comando / bin / sh, que simboliza o bash de qualquer maneira.

user877329
fonte
Boa pergunta. Parece que o caractere '%' não está funcionando corretamente no $ PATH de sh(é ok em bashe zshembora). Chamar diretamente o executável funciona sh; realmente estranho.
Rmano 28/04
O que acontece se você usar 2 %%?
mikeserv
Ou escapar do%?
Mdpc

Respostas:

15

Esse não é o shell Bourne, ou bashemular o shell Bourne, é o shell Almquist, no seu caso provavelmente o shell Debian Almquist (um fork Linux do Debian dos BSDs se baseia no shell Almquist original).

No shell Almquist (o original e as versões modernas), %é usado PATHpara recursos extras específicos ash. Citando a partir da documentação:

Pesquisa de caminho

Ao localizar um comando, o shell primeiro verifica se possui uma função de shell com esse nome. Então, se PATH não contiver uma entrada %builtin, ele procurará um comando interno com esse nome. Por fim, ele procura cada entrada no PATH, por sua vez, pelo comando.

O valor da variável PATH deve ser uma série de entradas separadas por dois pontos. Cada entrada consiste em um nome de diretório ou um nome de diretório seguido por um sinalizador começando com um sinal de porcentagem. O diretório atual deve ser indicado por um nome de diretório vazio. Se nenhum sinal de porcentagem estiver presente, a entrada fará com que o shell procure o comando no diretório especificado. Se o sinalizador for %builtin , a lista de comandos internos do shell será pesquisada. Se o sinalizador for %func , o diretório será procurado por um arquivo que seja lido como entrada no shell. Este arquivo deve definir uma função cujo nome é o nome do comando que está sendo pesquisado.

Os nomes de comando que contêm uma barra são simplesmente executados sem executar nenhuma das pesquisas acima.

Outros shells gostam kshou zshtêm um mecanismo de carregamento automático de funções semelhante, mas usam uma variável diferente ( $FPATH), mas você não pode definir quais funções ou executáveis ​​têm precedência.

No seu caso, /home/torbjorr/deployed/vector/x86_64-GNU%2fLinuxé interpretado como o /home/torbjorr/deployed/vector/x86_64-GNUdiretório com a 2fLinuxbandeira. Essa bandeira é ignorada, pois é desconhecida.

Não há jeito de contornar isso. Mesmo cinzas tinham um mecanismo de fuga para que esta %não ser tratado de forma especial, seria, então, não trabalho em outras conchas ou outras coisas que olhar para cima $PATHcomo execvp().

Você precisará remover os %caracteres $PATH, renomeie seu diretório ou adicione um link simbólico.

Ou não use ashpara o seu /bin/sh. Outras implementações leves de shell POSIX que não fazem isso incluem yashe mksh.

Stéphane Chazelas
fonte
Embora essa resposta dê uma explicação, ela não fornece uma solução. Existe uma maneira compatível de manter%.
user877329
@ user877329, não há solução real aqui. Veja minha edição.
Stéphane Chazelas 29/04
3
Em outras palavras, o Debian shviola o padrão POSIX. Dado que o ponto de separar shé exatamente que você deve ter certeza de não tropeçar em alguma extensão incompatível do shell (acho que ninguém usa /bin/shcomo shell de login atualmente), consideraria isso um bug.
Celtschk
11
@celtschk, concordou que o objetivo de usar ashpara / bin / sh é mais para evitar a penalidade de desempenho bash, portanto, usar yashou mksh(ou poshse você deseja excluir todas as extensões) ainda é uma opção melhor do que usar bash. Além disso, pode-se considerar um caso de canto. Normalmente, ninguém teria %um componente de caminho. A maioria dos shells possui casos de canto em que não são compatíveis com POSIX.
Stéphane Chazelas 29/04
11
@mtmiller, não é assim que leio o significado do conjunto de caracteres de nome de arquivo portátil (PFCS). O POSIX especifica APIs de programação, mas não implementações de sistema de arquivos. o PFCS é o mínimo de garantias do POSIX que funcionará independentemente do sistema de arquivos, independentemente do código do idioma atual, mas não é desculpa para uma ferramenta não aceitar um caractere em um nome de arquivo se ele for suportado pelo sistema de arquivos e válido no código do idioma atual. Observe que, por exemplo, o POSIX exige que exista um [comando, mesmo que esse caractere não esteja no PFCS.
Stéphane Chazelas