Todas as variáveis são armazenadas na memória como string no bash?

10

Digamos que criei as seguintes variáveis:

s=John
i=12345
f=3.14

Todas essas variáveis são armazenadas na memória como string ou bash tem outros tipos de dados?

    
por user268325 01.01.2018 / 12:02

5 respostas

15

As variáveis de bash são sem tipos .

Unlike many other programming languages, Bash does not segregate its variables by "type." Essentially, Bash variables are character strings, but, depending on context, Bash permits arithmetic operations and comparisons on variables. The determining factor is whether the value of a variable contains only digits.

Como outra resposta diz , há uma espécie de forma fraca de digitar com declare .

This is a very weak form of the typing [1] available in certain programming languages.

Veja um exemplo:

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.

Referências:

por 01.01.2018 / 12:16
11

Basicamente, o Bash tem variáveis escalares simples, matrizes e matrizes associativas. Além disso, os escalares podem ser marcados como inteiros com o declare builtin . Do ponto de vista do usuário do programador de script / shell, as variáveis de cadeia agem como strings, as variáveis inteiras agem como inteiros e as matrizes de acordo com seu tipo. A implementação interna não é muito relevante.

Mas, se quisermos saber como os dados são realmente armazenados na memória, devemos examinar o código-fonte para ver o que o programa realmente faz.

No Bash 4.4, os escalares são armazenados como strings, independentemente da tag inteira. Isso fica visível na definição de struct variable / the SHELL_VAR typedef e na função make_variable_value , que traduz explicitamente inteiros para strings para armazenamento.

As matrizes são armazenadas no que parece ser uma lista vinculada ( array.h ) e matrizes associativas como tabelas hash. Os valores dentro deles são novamente armazenados como strings. A escolha de uma lista vinculada para matrizes pode parecer estranha, mas como as matrizes podem ser esparsas e os índices podem ser números arbitrários, independentemente de quantos elementos a matriz contenha, essa escolha de design é um pouco mais fácil de entender.

No entanto, o código também contém uma definição para o union _value não utilizado, com campos para números inteiros, números de ponto flutuante, assim como valores de string. Ele está marcado em um comentário como "para o futuro", então é possível que alguma versão futura do Bash armazene diferentes tipos de escalares em seus formulários nativos.

    
por 01.01.2018 / 21:08
1

Para a vida de mim eu não posso encontrar isso declarado em qualquer lugar em tantas palavras, mas é assim que eu entendo isso.

Bash é um interpretador, não um compilador e representa todas as variáveis como strings. Daí todo o esforço e ênfase que acompanha as expansões de vários tipos.

Bash passa passes all denominam variáveis para declare como strings com atributos que controlam como essa variável deve ser expandida por declare no armazenamento.

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" )

E claro

declare -ia finale[1]=9+16
declare -p finale
declare -ai finale=([1]="25")

A coda para isso é que, mesmo que declare tenha uma representação interna que mude com os flags de atributo, strings são tudo o que o bash vê ou quer ver.

    
por 01.01.2018 / 17:15
0

Esta página tem um guia abrangente sobre as variáveis de digitação no Bash. Esta seção tem mais informações sobre o comando interno declare . Este snippet de código desse link pode ser de interesse:

[bob in ~] declare -i VARIABLE=12

[bob in ~] VARIABLE=string

[bob in ~] echo $VARIABLE
0

[bob in ~] declare -p VARIABLE
declare -i VARIABLE="0"

Aqui está a página man de declare .

    
por 01.01.2018 / 12:40
0

É irrelevante.

A única maneira de interagir com as variáveis do Bash é através do Bash, então é impossível para você notar qualquer diferença em como as variáveis são armazenadas na memória, porque você pode nunca acessar através da memória diretamente, você sempre precisa perguntar ao Bash seu valor, e o Bash pode então traduzi-los da maneira que quiser parecer como se eles tivessem armazenado de qualquer maneira específica.

Na verdade, eles podem nem ser armazenados na memória de todo . Não sei quão inteligentes são as implementações comuns do Bash, mas é possível, pelo menos em casos simples, determinar se uma variável será usada e / ou se será modificada e otimizá-la completamente ou em linha. / p>     

por 01.01.2018 / 17:27

Tags