Solo por interés, ¿por qué importaría? Realmente no podría importarme menos si se almacenaron como texto swahili siempre que no afecte la funcionalidad del idioma (afectar el rendimiento puede ser un problema, pero, si eso es importante, son mejores herramientas en su arsenal que bash)
2
@paxdiablo No importa, solo pregunto por curiosidad, ya que todos los demás lenguajes de programación / scripting que conozco (por ejemplo: Java, C ++, JavaScript, PHP, etc.) tienen una representación de memoria única para cada tipo de datos , por lo que es interesante ver un lenguaje de secuencias de comandos que solo tiene una representación de memoria para todos los tipos de datos.
user268325
Respuestas:
16
Las variables Bash no están tipificadas .
A diferencia de muchos otros lenguajes de programación, Bash no segrega sus variables por "tipo". Esencialmente, las variables de Bash son cadenas de caracteres, pero, según el contexto, Bash permite operaciones aritméticas y comparaciones de variables. El factor determinante es si el valor de una variable contiene solo dígitos.
Como dice otra respuesta , hay una especie de forma débil de escribir con declare.
Esta es una forma muy débil de escribir [1] disponible en ciertos lenguajes de programación.
Ver un ejemplo:
declare -i number
# The script will treat subsequent occurrences of "number" as an integer.
number=3
echo "Number = $number"# Number = 3
number=three
echo "Number = $number"# Number = 0# Tries to evaluate the string "three" as an integer.
Bash tiene esencialmente variables escalares simples, matrices y matrices asociativas. Además, los escalares se pueden etiquetar como enteros con la función declareincorporada . Desde el punto de vista del programador del script / usuario de shell, las variables de cadena actúan como cadenas, las variables enteras actúan como enteros y las matrices de acuerdo con su tipo. La implementación interna no es muy relevante.
Pero, si deseamos saber cómo se almacenan realmente los datos en la memoria, debemos examinar el código fuente para ver qué hace realmente el programa.
Las matrices se almacenan en lo que parece ser una lista vinculada ( array.h) y las matrices asociativas como tablas hash. Los valores dentro de ellos se almacenan nuevamente como cadenas. La elección de una lista vinculada para las matrices puede parecer extraña, pero como las matrices pueden ser escasas y los índices pueden ser números arbitrarios independientemente de la cantidad de elementos que contenga la matriz, esa elección de diseño es un poco más fácil de entender.
Sin embargo, el código también contiene una definición para lo no utilizadounion _value , con campos para números enteros, números de coma flotante, así como valores de cadena. Está marcado en un comentario como "para el futuro", por lo que es posible que alguna versión futura de Bash almacene diferentes tipos de escalares en sus formas nativas.
Por mi vida, no puedo encontrar esto en ninguna parte con tantas palabras, pero así es como lo entiendo.
Bash es un intérprete, no un compilador y representa todas las variables como cadenas. De ahí todo el esfuerzo y énfasis que conlleva las expansiones de varios tipos.
Bash pasa pasa todas las variables con nombre que declarecomo cadenas con atributos que el control de la forma en que la variable se va ampliado por declareel almacenamiento.
banana=yellow #no call to declare
declare -p banana
declare -- banana="yellow"#but declare was invoked with --
declare -i test=a #arithmetic expansion to null/zero
declare -p test
declare -i test="0"
declare -i test2=5+4#successful arithmetic expansion
declare -p test2
declare -i test2="9"
declare -i float=99.6#arithmetical expansion fails due to syntax
bash: declare:99.6: syntax error: invalid arithmetic operator (error token is ".6")
nofloat=99.9
declare -p nofloat
declare -- nofloat"99.6"#Success because arithmetical expansion not invoked
declare -a a #variable is marked as a placeholder to receive an array
declare -p a
declare -a a
a[3]=99#array elements are appended
a[4]=99
declare -p a
declare -a a=([3]="99"[4]="99")
declare -A newmap #same as -a but names instead of numbers
newmap[name]="A Bloke"
newmap[designation]=CFO
newmap[company]="My Company"
declare -p newmap
declare -A newmap=([company]="My Company"[name]="A Bloke"[designation]="CFO")
Y por supuesto
declare -ia finale[1]=9+16
declare -p finale
declare -ai finale=([1]="25")
La clave para esto es que, incluso si declaretiene una representación interna que cambia con las banderas de atributos, las cadenas son todo lo que bash ve o quiere ver.
Esta página tiene una guía completa sobre cómo escribir variables en Bash. Esta sección tiene más información sobre el declarecomando incorporado. Este fragmento de código de ese enlace puede ser de interés:
La única forma de interactuar con las variables de Bash es a través de Bash, por lo que es imposible que note alguna diferencia en cuanto a cómo se almacenan las variables en la memoria, ya que nunca puede acceder a ellas a través de la memoria directamente , siempre debe preguntarle a Bash por su valor, y Bash luego puede traducirlos de la forma en que quiera verse como si hubieran sido almacenados de una manera específica.
De hecho, es posible que ni siquiera se pueden almacenar en la memoria en absoluto . No sé cuán inteligentes son las implementaciones comunes de Bash, pero al menos es posible en casos simples determinar si se usará una variable y / o si se modificará, y optimizarla por completo o alinearla.
Creo que el punto de la pregunta era la representación más que la ubicación
bu5hman el
2
Mi punto es que no puedes conocer la representación, porque no puedes observarla. Por lo tanto, es irrelevante y puede cambiar sin que te des cuenta. Es simplemente imposible saber qué representación podría elegir Bash. Podría profundizar en el código fuente de una implementación y verificar qué representación elige, pero podría cambiar la representación mañana en la próxima versión del parche y no habría forma de que lo supiera.
Jörg W Mittag el
¿Variables de Schroedingers? Estoy de acuerdo con usted fundamentalmente en que la representación subyacente es irrelevante (vea mi respuesta), pero al usar bash efectivamente estamos 'codificando a una interfaz' y la representación en la interfaz es fibrosa.
bu5hman el
2
Sí, pero la pregunta no es sobre la representación en el límite de la interfaz, sino específicamente sobre cómo se "almacenan en la memoria". Y a esa pregunta, respondería: no, no podemos y no debemos saber.
Jörg W Mittag el
Lo que parafrasea la última línea de mi propia publicación ... como dije, estamos de acuerdo ... y dado el representante de los OP y la naturaleza de la pregunta, creo que recibirán calificaciones razonables por su tarea, quienquiera que sea se cita ;-).
bash
)Respuestas:
Las variables Bash no están tipificadas .
Como dice otra respuesta , hay una especie de forma débil de escribir con
declare
.Ver un ejemplo:
Referencias
fuente
Bash tiene esencialmente variables escalares simples, matrices y matrices asociativas. Además, los escalares se pueden etiquetar como enteros con la función
declare
incorporada . Desde el punto de vista del programador del script / usuario de shell, las variables de cadena actúan como cadenas, las variables enteras actúan como enteros y las matrices de acuerdo con su tipo. La implementación interna no es muy relevante.Pero, si deseamos saber cómo se almacenan realmente los datos en la memoria, debemos examinar el código fuente para ver qué hace realmente el programa.
En Bash 4.4, los escalares se almacenan como cadenas, independientemente de la etiqueta entera. Esto es visible en la definición de
struct variable
/SHELL_VAR
typedef y en la funciónmake_variable_value
, que traduce explícitamente enteros a cadenas para el almacenamiento.Las matrices se almacenan en lo que parece ser una lista vinculada (
array.h
) y las matrices asociativas como tablas hash. Los valores dentro de ellos se almacenan nuevamente como cadenas. La elección de una lista vinculada para las matrices puede parecer extraña, pero como las matrices pueden ser escasas y los índices pueden ser números arbitrarios independientemente de la cantidad de elementos que contenga la matriz, esa elección de diseño es un poco más fácil de entender.Sin embargo, el código también contiene una definición para lo no utilizado
union _value
, con campos para números enteros, números de coma flotante, así como valores de cadena. Está marcado en un comentario como "para el futuro", por lo que es posible que alguna versión futura de Bash almacene diferentes tipos de escalares en sus formas nativas.fuente
Por mi vida, no puedo encontrar esto en ninguna parte con tantas palabras, pero así es como lo entiendo.
Bash es un intérprete, no un compilador y representa todas las variables como cadenas. De ahí todo el esfuerzo y énfasis que conlleva las expansiones de varios tipos.
Bash pasa pasa todas las variables con nombre que
declare
como cadenas con atributos que el control de la forma en que la variable se va ampliado pordeclare
el almacenamiento.Y por supuesto
La clave para esto es que, incluso si
declare
tiene una representación interna que cambia con las banderas de atributos, las cadenas son todo lo que bash ve o quiere ver.fuente
Esta página tiene una guía completa sobre cómo escribir variables en Bash. Esta sección tiene más información sobre el
declare
comando incorporado. Este fragmento de código de ese enlace puede ser de interés:Aquí está la
man
página paradeclare
.fuente
Es irrelevante.
La única forma de interactuar con las variables de Bash es a través de Bash, por lo que es imposible que note alguna diferencia en cuanto a cómo se almacenan las variables en la memoria, ya que nunca puede acceder a ellas a través de la memoria directamente , siempre debe preguntarle a Bash por su valor, y Bash luego puede traducirlos de la forma en que quiera verse como si hubieran sido almacenados de una manera específica.
De hecho, es posible que ni siquiera se pueden almacenar en la memoria en absoluto . No sé cuán inteligentes son las implementaciones comunes de Bash, pero al menos es posible en casos simples determinar si se usará una variable y / o si se modificará, y optimizarla por completo o alinearla.
fuente