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

11

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

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

tést() { echo 34; }

tést

Mas , , e parecem permitir isso.

Estou ciente de que nomes de função válidos usam essa definição de Nomes . Isso significa que este regex:

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

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

An implementation may allow other characters in a function name as an extension.

As perguntas são:

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

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

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

    
por Community 25.11.2015 / 08:07

2 respostas

15

Como a documentação POSIX permite isso como uma extensão, não há nada que impeça a implementação desse comportamento.

Uma simples verificação (executada em 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

mostra que bash , zsh , yash , ksh93 (a qual ksh está vinculada no meu sistema), pdksh e sua derivação permitem caracteres com vários bytes como nome da função.

O

yash foi projetado para oferecer suporte a caracteres de vários bytes desde o começo, por isso não é surpresa que funcionou .

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

A blank is a tab or a space. An identifier is a sequence of letters, digits, or underscores starting with a letter or underscore. Identifiers are used as components of variable names. A vname is a sequence of one or more identifiers separated by a . and optionally preceded by a .. Vnames are used as function and variable names. A word is a sequence of characters from the character set defined by the current locale, excluding non-quoted metacharacters.

Então, definindo como C locale:

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

falha.

    
por 25.11.2015 / 09:19
8

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

Então, enquanto a maioria dos shells restringe os caracteres de suas funções, não há uma boa razão para eles fazerem isso. Isso significa que, naqueles shells, existem comandos que você não pode substituir por uma função.

zsh e rc permitem qualquer coisa para seus nomes de função, incluindo alguns com / e a string vazia. zsh até permite bytes NUL.

$ zsh
$ $'
$ zsh
$ $'%pre%'() echo nul
$ ^@
nul
$ ""() uname
$ ''
Linux
$ /bin/ls() echo test
$ /bin/ls
test
'() 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 e, em zsh , argumentos para builtins e funções podem ser qualquer sequência de bytes.

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

Onde pode haver problemas de segurança é quando a análise é afetada pelo ambiente, por exemplo, com shells, onde os nomes válidos para funções são afetados pela localidade.

    
por 27.11.2015 / 18:11