En bash scripting, ¿cuál es la diferencia entre declarar y una variable normal?

43

En bash scripting:

creamos variable con solo nombrarla:

abc=ok

o podemos usar declare

declare abc=ok

¿cual es la diferencia?

¿Y por qué bash hace tantas formas de crear una variable?

primavera amorosa
fuente
66
Cuando se usa en una función, declarehace que los NAME sean locales, como con el localcomando. La -gopción suprime este comportamiento. Ver help declare.
Cyrus
2
declarepermite crear matrices asociativas, enteros y variables de solo lectura. Además, expande sus argumentos, por lo que cosas como declare $name=1son posibles.
choroba

Respuestas:

34

De help -m declare:

NOMBRE

    declare - Establecer valores y atributos variables.

SINOPSIS

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

DESCRIPCIÓN

    Establecer valores y atributos variables.

    Declarar variables y darles atributos. Si no se proporcionan NAME, muestre los atributos y valores de todas las variables.

    Opciones:

      -f
        restringir la acción o visualización a nombres y definiciones de funciones
      -F
        restringir la visualización solo a los nombres de funciones (más el número de línea y el archivo fuente al depurar)
      -g
        crear variables globales cuando se usa en una función de shell; de lo contrario ignorado
      -p
        muestra los atributos y el valor de cada NOMBRE

    Opciones que establecen atributos:

      -a
        hacer matrices indexadas NAME (si es compatible)
      -A
        hacer matrices asociativas NAME (si es compatible)
      -i
        para hacer que las NAME tengan el atributo 'entero'
      -l
        para convertir NAME a minúsculas en la asignación
      -n
        hacer NAME una referencia a la variable nombrada por su valor
      -r
        hacer que las NAME sean de solo lectura
      -t
        para hacer que las NAME tengan el atributo 'trace'
      -u
        convertir NAME a mayúsculas en la asignación
      -x
        hacer exportar NAME

    Usar ' +' en lugar de ' -' desactiva el atributo dado.

    Las variables con el atributo entero tienen evaluación aritmética (ver el letcomando) cuando se le asigna un valor a la variable.

    Cuando se usa en una función, declarehace que los NAME sean locales, como con el local comando. La -gopción ' ' suprime este comportamiento.

    Estado de salida:
    Devuelve el éxito a menos que se proporcione una opción no válida o se produzca un error de asignación variable.

VER TAMBIÉN

    golpe (1)

IMPLEMENTACIÓN

    GNU bash, versión 4.3.11 (1) -release (i686-pc-linux-gnu)
    Copyright (C) 2013 Free Software Foundation, Inc.
    Licencia GPLv3 +: GNU GPL versión 3 o posterior <http://gnu.org/ licencias / gpl.html>


Por lo tanto, declarese utiliza para establecer valores y atributos variables .

Permítanme mostrar el uso de dos atributos con un ejemplo muy simple:

$ # 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

¡Del ejemplo anterior, creo que deberías entender el uso de la declarevariable sobre la variable normal! Este tipo de declareacción es útil en funciones, bucles con secuencias de comandos.

Visite también Variables de escritura: declarar o componer

Pandya
fuente
sí, el "y los atributos" es el punto! Esta es la diferencia.
lovespring
¡Excelente! Me encantan los ejemplos, la mejor manera de enseñar / aprender. ¡Gracias!
turkenh
1
Necesita saber qué "atributos" son para comprender esta respuesta. Son propiedades de la variable como 'entero', 'matriz' o 'solo lectura'.
Noumenon
11

abc=okasigna un valor a la variable abc. declare abcdeclara una variable llamada abc. Los dos se pueden combinar como declare abc=ok.

En bash, como otros shells, las variables de cadena y matriz no necesitan ser declaradas, por declarelo que no es necesario a menos que desee pasar opciones, por ejemplo, declare -A abcpara hacer abcuna matriz asociativa o declare -rpara hacer una variable de solo lectura. Sin embargo, dentro de una función, declarehace una diferencia: hace que la variable sea local a la función, lo que significa que el valor de la variable fuera de la función (si existe) se conserva. (A menos que utilice declare -g, lo que hace que la variable no sea local; esto es útil cuando se combina con otras opciones, por ejemplo, declare -gApara crear una matriz asociativa global en una función). Ejemplo:

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"

Salida:

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

Otra cosa que puedes hacer con el declareincorporado es

El declareincorporado es exclusivo de bash. Está fuertemente inspirado y muy cerca de la typesetconstrucción de ksh , y bash proporciona typesetcomo sinónimo de declarecompatibilidad. (No sé por qué bash no solo lo llamó typeset). Hay una tercera sinonimo, local. También hay export, que es lo mismo que declare -x, de nuevo por compatibilidad (con cada shell de estilo Bourne).

Gilles 'SO- deja de ser malvado'
fuente
¡sí! la 'y opción' es el punto. PD: si diseño el bash, dejaré que el comportamiento de "declarar" haga algo en condiciones diferentes. Esto hace las cosas simples.
lovespring
Buena respuesta. Otra cuestión, que uno entre export, localy declarees el más compatible con otros proyectiles?
0xc0de
1
@ 0xc0de exportexiste en todas las variantes de sh. localexiste solo en bash y zsh, declaresolo en bash. typesetexiste en ksh, bash y zsh.
Gilles 'SO- deja de ser malvado'