Caracteres válidos do nome da função do shell

13

O uso de caracteres Unicode estendidos é (sem dúvida) útil para muitos usuários.

Os shells mais simples (ash (busybox), traço) e o ksh falham com:

tést() { echo 34; }

tést

Mas , , e parecem permitir isso.

Estou ciente de que os nomes de funções válidas do POSIX usam essa definição de Nomes . Isso significa esta regex:

[a-zA-Z_][a-zA-Z0-9_]*

No entanto, no primeiro link também é dito:

Uma implementação pode permitir outros caracteres em um nome de função como uma extensão.

As perguntas são:

  • Isso é aceito e documentado?
  • Onde?
  • Para quais conchas (se houver)?

Perguntas relacionadas:
É possível usar caracteres especiais em um nome de função shell?
Não estou interessado em usar meta-caracteres (>) em nomes de funções.

Nomes de funções iniciantes e bash contendo “-”
Não acredito que um operador (subtração "-") deva fazer parte de um nome.

Comunidade
fonte
você pode achar aliasque é um pouco mais branda. e, assim, você pode escrever a função com um nome apropriado e abotoado e definir um alias com um nome mais elegante para chamar a função. em dashtambém há algumas coisas que você pode fazer com $PATHe %func.
mikeserv

Respostas:

16

Como a documentação do POSIX permite isso como uma extensão, nada impede a implementação desse comportamento.

Uma verificação simples (executada zsh):

$ for shell in /bin/*sh 'busybox sh'; do
    printf '[%s]\n' $shell
    $=shell -c 'á() { :; }'
  done
[/bin/ash]
/bin/ash: 1: Syntax error: Bad function name
[/bin/bash]
[/bin/dash]
/bin/dash: 1: Syntax error: Bad function name
[/bin/ksh]
[/bin/lksh]
[/bin/mksh]
[/bin/pdksh]
[/bin/posh]
/bin/posh: á: invalid function name
[/bin/yash]
[/bin/zsh]
[busybox sh]
sh: syntax error: bad function name

mostram que bash, zsh,yash , ksh93(que kshligada no meu sistema), pdkshe sua derivação permitir multi-bytes caracteres como nome da função.

yash foi desenvolvido para suportar caracteres multibyte desde o início, portanto não é surpresa que funcionou.

A outra documentação que você pode consultar é ksh93:

Um espaço em branco é uma guia ou um espaço. Um identificador é uma sequência de letras, dígitos ou sublinhados começando com uma letra ou sublinhado. Identificadores são usados ​​como componentes de nomes de variáveis. Um vname é uma sequência de um ou mais identificadores separados por a. e opcionalmente precedido por um .. Vnames são usados ​​como nomes de função e variável. Uma palavra é uma sequência de caracteres do conjunto de caracteres definido pelo código de idioma atual , excluindo metacaracteres não citados.

Então, definindo para Clocalidade:

$ export LC_ALL=C
$ á() { echo 1; }
ksh: á: invalid function name

faça com que falhe.

cuonglm
fonte
poshnão vale a pena ser listado nessa lista. Depende de erros específicos do Linux libce não funcionará em outras plataformas.
schily
Não posso repetir suas alegações sobre o ksh93uso de um ksh93 auto compilado de fontes originais. Embora ksh88pareça aceitar letras não ASCII de 7 bits para nomes de funções, apenas o ksh93binário do Ubuntu parece aceitá-las.
schily
@schily ksh I utilizado neste teste é o binário em Debian (por isso pode ser o mesmo com um no Ubuntu)
cuonglm
9

Observe que as funções compartilham o mesmo espaço de nome que outros comandos, incluindo comandos no sistema de arquivos, que na maioria dos sistemas não têm limitações nos caracteres ou mesmo bytes que podem conter em seu caminho.

Portanto, enquanto a maioria das conchas restringe os caracteres de suas funções, não há uma boa razão para fazer isso. Isso significa que, nesses shells, existem comandos que você não pode substituir por uma função.

zshe rcpermitir qualquer coisa para seus nomes de função, incluindo alguns com /e a string vazia. zshpermite até NUL bytes.

$ zsh
$ $'\0'() echo nul
$ ^@
nul
$ ""() uname
$ ''
Linux
$ /bin/ls() echo test
$ /bin/ls
test

Um comando simples no shell é uma lista de argumentos, e o primeiro argumento é usado para derivar o comando a ser executado. Portanto, é lógico que esses argumentos e nomes de funções compartilhem os mesmos valores possíveis ezsh argumentos de built-in e funções, pode haver qualquer sequência de bytes.

Não há problema de segurança aqui, pois as funções que você (o autor do script) define são as que você chama.

Onde pode haver problemas de segurança é quando a análise é afetada pelo ambiente, por exemplo, com shells em que os nomes válidos para funções são afetados pelo código do idioma.

Stéphane Chazelas
fonte
Pode-se jogar jogos em festa também, começando com function /bin/sh { echo "$0: $FUNCNAME: Permission denied"; return 126; }, e potencialmente coisas úteis também com funções nomeadas --, //, @ou %etc.
mr.spuratic
mas as conchas não costumam ignorar uma pesquisa de tabela de hash quando /é encontrada em um nome? e uma função não é apenas um nome executável - seu código. eu pensaria que uma implementação simples poderia encontrar muitos problemas de análise se os nomes de funções armazenadas incluíssem metacaracteres.
mikeserv
Sim, eu estou ciente da incapacidade do bash de conter nulos nos vars, que poderiam ser razoavelmente estendidos aos nomes das funções. Não tenho um exemplo específico, mas sinto que esse jogo de permitir quase qualquer coisa a nomes é mais uma violação potencial de segurança do que uma "maneira fácil de trabalhar". Espero estar errado.