Eu não posso alias def $? = “type $? || eco 'varible not defined' ”

1

Eu quero criar um apelido chamado def, que usa uma variável e verifica se está definido. Se não é def impressões 'a variante não está definida.

    
por user255774 16.09.2014 / 06:28

3 respostas

2

A seguinte função imprimirá uma mensagem de erro se o nome de uma variável for nulo ou indefinido:

def() { : "${!1:? "Variable not defined."}" ; }

Exemplos:

$ def PATH
$ def NONESUCH
bash: !1:  Variable not defined.

Esta função requer bash .

Explicação:

O corpo da função consiste em um comando que recebe um argumento. O comando é : , que age como um não funcionamento. O argumento para esse comando é "${!1:? "Variable not defined."}" . Em bash, , a construção ${!1} retorna o valor da variável cujo nome é dado por , o primeiro argumento da função. Se a variável cujo nome é estiver definida e não nula, "${!1:? "Variable not defined."}" retornará seu valor. Seu valor é ignorado por : porque : é um não operacional. Se a variável com esse nome não estiver definida ou nula, então, devido à construção de expansão do parâmetro :? , a mensagem de erro especificada será retornada.

Formato de saída aprimorado

A função acima não retornou exatamente a mensagem que você pediu. Podemos consertar isso:

$ def() { ( : "${!1:? "Variable  not defined."}" ) 2>&1 | sed 's/^bash: !1:  //'; }
$ def NONESUCH
Variable not defined.

Ou

$ def() { ( : "${!1:?}" ) 2>/dev/null || echo "Variable not defined"; }
$ def NONESUCH
Variable not defined
    
por John1024 16.09.2014 / 07:07
1

Desde o Ubuntu 12.04 LTS (e talvez um pouco antes disso, mas não desde 10.04 LTS), a versão bash no Ubuntu tem sido pelo menos 4.2 . Assim isso suporta o operador -v dos test , [ e [[ builtins .

Se você aprender apenas uma maneira de testar se as variáveis são definidas no bash, provavelmente deve ser o expansão de parâmetro técnica usada na excelente resposta de John1024. Mesmo que os sistemas Ubuntu usando bash 4.1 e anteriores estejam se tornando cada vez mais incomuns, o 10.04 ainda tem suporte limitado ao servidor, e versões anteriores do bash são muito mais comum em alguns outros sistemas GNU / Linux (e outros sistemas operacionais baseados em Unix).

Mas se você tiver o bash 4.2 ou superior, o "melhor formato de saída" da resposta do John1024 pode ser ainda mais simplificado para :

def() { [ -v "" ] || echo 'Variable not defined'; }

Observe que, se foo for o nome da variável na qual você está interessado, [ -v foo ] - não [ -v $foo ] - testa se estiver definido. Neste caso, eu tenho $1 porque o primeiro parâmetro posicional passado para def conterá o nome da variável a ser testada como seu valor . (O $ no meu exemplo atinge o mesmo nível adicional de indireto obtido por ! na expressão ${...} de o exemplo de John1024 .

ek@Ilex:~$ def() { [ -v "" ] || echo 'Variable not defined'; }
ek@Ilex:~$ def PATH
ek@Ilex:~$ def NONESUCH
Variable not defined

Meus e John1024's def imprimirão Variable not defined :

  • quando nenhuma variável pelo nome é transmitida enquanto o primeiro argumento da função existe
  • mas também quando nenhum primeiro argumento é passado para def .

Isto é:

ek@Ilex:~$ def
Variable not defined

Se você preferir uma mensagem separada nessa situação, poderá lidar com o caso de def sem receber argumentos separadamente:

def() {
    if [ $# -eq 0 ]; then
        echo 'error: too few arguments' >&2
        return 1
    elif [ ! -v "" ]; then
        echo 'Variable not defined'
    fi
}

Escrevi isso com base na idéia de que ter o primeiro argumento de def , seja ou não uma variável definida, é considerada uma operação normal e não um erro. Em contraste, não passar nenhum argumento para def é um erro e eu o tratei como tal:

  • >&2 envia a saída de echo para < a href="https://en.wikipedia.org/wiki/Standard_streams#Standard_error_.28stderr.29"> erro padrão .

  • return 1 faz com que def retorne com status de saída diferente de zero, indicando falha. (Isso é útil principalmente quando uma chamada para def aparecerá em vez de uma instrução ou script composto, embora o status de saída do último comando também possa ser verificado com echo $? .)

    Em outros casos, def retornará o status de saída padrão de 0 (a menos que haja algum outro erro, como echo não conseguir gravar Variable not defined para standard output ).

ek@Ilex:~/source$ def NONESUCH
Variable not defined
ek@Ilex:~/source$ def
error: too few arguments
    
por Eliah Kagan 16.09.2014 / 11:06
0

De acordo com o Guia avançado de script de script :

  

Em um script, os aliases têm utilidade muito limitada. Seria bom se   aliases poderiam assumir algumas das funcionalidades do pré-processador C,   como expansão de macro, mas infelizmente o Bash não se expande   argumentos dentro do corpo alias. [117] Além disso, um script não consegue   expandir um alias em si mesmo dentro de "construções compostas", como if / then   instruções, loops e funções. Uma limitação adicional é que um alias   não expandirá recursivamente. Quase invariavelmente, o que quisermos   um pseudônimo para fazer poderia ser realizado de forma muito mais eficaz com um   função.

É por isso que você deve seguir a resposta de Eliah Kagan ou John1024.

    
por Lety 16.09.2014 / 13:38