No script bash, qual é a diferença entre declarar e uma variável normal?

43

No script bash:

criamos variável apenas nomeando-a:

abc=ok

ou podemos usar declare

declare abc=ok

qual é a diferença?

e por que o bash faz tantas maneiras de criar uma variável?

lovespring
fonte
6
Quando usado em uma função, declaretorna os NAMEs locais, como no localcomando. A -gopção suprime esse comportamento. Veja help declare.
Cyrus
2
declaretorna possível criar matrizes associativas, números inteiros e variáveis ​​somente leitura. Além disso, ele expande seus argumentos, para que coisas como declare $name=1sejam possíveis.
choroba

Respostas:

34

De help -m declare:

NOME

    declare - Defina valores e atributos variáveis.

SINOPSE

    declare[ -aAfFgilnrtux] [ -p] [ name[ ] ...]=value

DESCRIÇÃO

    Defina valores e atributos de variáveis.

    Declare variáveis ​​e atribua a elas. Se nenhum NAMEs for fornecido, exiba os atributos e valores de todas as variáveis.

    Opções:

      -f
        restringir ação ou exibição para nomes e definições de função
      -F
        restringir a exibição apenas aos nomes das funções (mais o número da linha e o arquivo de origem durante a depuração)
      -g
        crie variáveis ​​globais quando usadas em uma função shell; caso contrário ignorado
      -p
        exibir os atributos e o valor de cada NAME

    Opções que definem atributos:

      -a
        criar matrizes indexadas NAMEs (se suportadas)
      -A
        criar matrizes associativas NAMEs (se suportadas)
      -i
        fazer com que os NAMEs tenham o atributo 'número inteiro'
      -l
        converter NAMEs em minúsculas na atribuição
      -n
        faça de NAME uma referência à variável nomeada por seu valor
      -r
        fazer NAMEs somente leitura
      -t
        fazer com que os NAMEs tenham o atributo 'trace'
      -u
        converter NAMEs em maiúsculas na atribuição
      -x
        fazer NAMEs exportar

    Usar ' +' em vez de ' -' desativa o atributo fornecido.

    Variáveis ​​com o atributo inteiro têm avaliação aritmética (consulte o letcomando) executada quando um valor é atribuído à variável.

    Quando usado em uma função, declaretorna os NAMEs locais, como no local comando. A -gopção ' ' suprime esse comportamento.

    Status de saída:
    retorna êxito, a menos que seja fornecida uma opção inválida ou ocorra um erro de atribuição variável.

VEJA TAMBÉM

    bash (1)

IMPLEMENTAÇÃO

    Lançamento do GNU bash, versão 4.3.11 (1) (i686-pc-linux-gnu)
    Copyright (C) 2013 Free Software Foundation, Inc.
    Licença GPLv3 +: GNU GPL versão 3 ou posterior <http://gnu.org/ licenças / gpl.html>


Portanto, declareé usado para definir valores e atributos de variáveis .

Deixe-me mostrar o uso de dois atributos com um exemplo muito simples:

$ # First Example:
$ declare -r abc=ok
$ echo $abc
ok
$ abc=not-ok
bash: abc: readonly variable


$ # Second Example:
$ declare -i x=10
$ echo $x
10
$ x=ok
$ echo $x
0
$ x=15
$ echo $x
15
$ x=15+5
$ echo $x
20

A partir do exemplo acima, acho que você deve entender o uso da declarevariável sobre a variável normal! Esse tipo de declareação é útil em funções, loops com scripts.

Visite também Digitando variáveis: declare ou digite

Pandya
fonte
sim, o "e atributos" é o ponto! essa é a diferença
precisa saber é
Ótimo! Eu amo exemplos, a melhor maneira de ensinar / aprender. Obrigado!
turkenh
1
Você precisa saber o que "atributos" são para entender esta resposta. São propriedades da variável como 'número inteiro', 'matriz' ou 'somente leitura'.
Noumenon
11

abc=okatribui um valor para a variável abc. declare abcdeclara uma variável chamada abc. Os dois podem ser combinados como declare abc=ok.

No bash, como outros shells, as variáveis ​​de string e array não precisam ser declaradas, portanto declarenão são necessárias, a menos que você deseje passar opções, por exemplo, declare -A abcpara criar abcum array associativo ou declare -rpara tornar uma variável somente leitura. No entanto, dentro de uma função, declarefaz a diferença: faz com que a variável seja local para a função, o que significa que o valor da variável fora da função (se houver) é preservado. (A menos que você use declare -g, o que torna a variável não local; isso é útil quando combinado com outras opções, por exemplo, declare -gApara criar uma matriz associativa global em uma função.) Exemplo:

f () {
  declare a
  a='a in f'
  b='b in f'
  echo "From f: a is $a"
  echo "From f: b is $b"
}
a='Initial a'
b='Initial b'
f
echo "After f: a is $a"
echo "After f: b is $b"

Saída:

From f: a is a in f
From f: b is b in f
After f: a is Initial a
After f: b is b in f

Outra coisa que você pode fazer com o declarebuilt-in é

O declarebuiltin é exclusivo para o bash. É fortemente inspirado e muito próximo ao built-in do ksh typeset, e o bash fornece typesetcomo sinônimo de declarecompatibilidade. (Não sei por que o bash não chamou apenas typeset). Há um terceiro sinônimo local. Há também exporto mesmo que declare -x, novamente, para compatibilidade (com todos os shell no estilo Bourne).

Gilles 'SO- parar de ser mau'
fonte
sim! o 'e opção' é o ponto. ps se eu projetar o bash, deixarei o comportamento de "declarar" fazer alguma coisa com condições diferentes. isso simplifica as coisas.
precisa saber é
Boa resposta. Uma pergunta adicional, qual dentre export, locale declareé a mais compatível com outras conchas?
0xc0de 14/04
1
@ 0xc0de exportexiste em todas as variantes de sh. localexiste apenas no bash e zsh, declareapenas no bash. typesetexiste em ksh, bash e zsh.
Gilles 'SO- stop be evil'