Apenas por interesse, por que isso importa? Eu realmente não poderia me importar menos se eles fossem armazenados como texto em suaíli, desde que não afetassem a funcionalidade do idioma (afetar o desempenho pode ser um problema, mas, se isso é importante, são ferramentas melhores no seu arsenal do que bash)
2
@paxdiablo Não importa, estou apenas perguntando por curiosidade, pois todas as outras linguagens de programação / script que eu conheço (por exemplo: Java, C ++, JavaScript, PHP, etc.) têm uma representação de memória exclusiva para cada tipo de dados , é interessante ver uma linguagem de script que tenha apenas uma representação de memória para todos os tipos de dados.
precisa saber é o seguinte
Respostas:
16
As variáveis bash são sem tipo .
Ao contrário de muitas outras linguagens de programação, o Bash não segrega suas variáveis por "tipo". Essencialmente, as variáveis do Bash são cadeias de caracteres, mas, dependendo do contexto, o Bash permite operações aritméticas e comparações de variáveis. O fator determinante é se o valor de uma variável contém apenas dígitos.
Esta é uma forma muito fraca da digitação [1] disponível em certas linguagens de programação.
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.
O Bash possui essencialmente variáveis escalares simples, matrizes e matrizes associativas. Além disso, os escalares podem ser marcados como números inteiros com o declareinterno . Do ponto de vista do programador de scripts / usuário do shell, as variáveis de string atuam como strings, as variáveis inteiras atuam 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 seqüências de caracteres, independentemente da marca inteira. Isso é visível na definição de struct variable/ the SHELL_VARtypedef e na funçãomake_variable_value , que converte explicitamente números inteiros em seqüências de caracteres para armazenamento.
Matrizes são armazenadas no que parece ser uma lista vinculada ( array.h) e matrizes associativas como tabelas de hash. Os valores dentro deles são novamente armazenados como seqüências de caracteres. A escolha de uma lista vinculada de matrizes pode parecer estranha, mas como as matrizes podem ser esparsas e os índices podem ser números arbitrários, independentemente do número de elementos que a matriz contém, essa opção de design é um pouco mais fácil de entender.
No entanto, o código também contém uma definição para o não utilizadounion _value , com campos para números inteiros, números de ponto flutuante e valores de sequência. Ele está marcado em um comentário como "para o futuro", portanto, é possível que alguma versão futura do Bash armazene diferentes tipos de escalares em suas formas nativas.
Pela minha vida, não consigo encontrar isso em nenhum lugar em tantas palavras, mas é assim que eu o entendo.
Bash é um intérprete, não um compilador e representa todas as variáveis como strings. Daí todo o esforço e ênfase que acompanham as expansões de vários tipos.
Bash passa passa todas as variáveis nomeadas para declarecomo cordas com atributos que controlam como essa variável deve ser expandida por declareno 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 disso é que, mesmo que declaretenha uma representação interna que mude com os sinalizadores de atributo, as strings são tudo o que o bash vê ou deseja ver.
Esta página possui um guia completo sobre como digitar variáveis no Bash. Esta seção tem mais informações sobre o declarecomando interno. Este snippet de código desse link pode ser interessante:
A única maneira de interagir com as variáveis do Bash é através do Bash, por isso é impossível notar qualquer diferença quanto à forma como as variáveis são armazenadas na memória, porque como você nunca pode acessá-las diretamente através da memória , sempre solicite ao Bash valor e Bash pode então traduzi-los de qualquer maneira que ele quer olhar como se eles tinham sido armazenados em qualquer forma específica.
Na verdade, eles não podem sequer ser armazenadas na memória em tudo . Não sei quão inteligentes são as implementações comuns do Bash, mas é pelo menos possível em casos simples determinar se uma variável será usada e / ou se será modificada e otimizá-la completamente ou incorporá-la.
Eu acho que o ponto da questão era a representação em vez da localização
bu5hman
2
O que quero dizer é que você não pode conhecer a representação, porque não pode observá-la. Portanto, é irrelevante e pode mudar sem que você perceba. É simplesmente impossível dizer qual representação Bash pode escolher. Você pode se aprofundar no código fonte de uma implementação e verificar qual representação ela escolhe, mas isso pode mudar a representação amanhã no próximo lançamento de patch e não há como você saber.
Jörg W Mittag 01/01
Variáveis de Schroedingers? Eu concordo fundamentalmente com você sobre a irrelevância da representação subjacente (veja minha resposta), mas ao usar o bash estamos efetivamente 'codificando para uma interface' e a representação na interface é exigente.
bu5hman
2
Sim, mas a questão não é sobre a representação nos limites da interface, mas especificamente sobre como eles são "armazenados na memória". E a essa pergunta, eu responderia: não sabemos, não podemos e não devemos saber.
Jörg W Mittag 01/01
O que parafraseia a última linha do meu próprio post ..... como eu disse, nós concordamos ...... e dado o representante dos OPs e a natureza da pergunta, acho que eles receberão notas razoáveis pelo dever de casa, quem quer que seja é citado ;-).
bash
)Respostas:
As variáveis bash são sem tipo .
Como outra resposta diz , existe uma forma fraca de digitação
declare
.Veja um exemplo:
Referências:
fonte
O Bash possui essencialmente variáveis escalares simples, matrizes e matrizes associativas. Além disso, os escalares podem ser marcados como números inteiros com o
declare
interno . Do ponto de vista do programador de scripts / usuário do shell, as variáveis de string atuam como strings, as variáveis inteiras atuam 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 seqüências de caracteres, independentemente da marca inteira. Isso é visível na definição de
struct variable
/ theSHELL_VAR
typedef e na funçãomake_variable_value
, que converte explicitamente números inteiros em seqüências de caracteres para armazenamento.Matrizes são armazenadas no que parece ser uma lista vinculada (
array.h
) e matrizes associativas como tabelas de hash. Os valores dentro deles são novamente armazenados como seqüências de caracteres. A escolha de uma lista vinculada de matrizes pode parecer estranha, mas como as matrizes podem ser esparsas e os índices podem ser números arbitrários, independentemente do número de elementos que a matriz contém, essa opção de design é um pouco mais fácil de entender.No entanto, o código também contém uma definição para o não utilizado
union _value
, com campos para números inteiros, números de ponto flutuante e valores de sequência. Ele está marcado em um comentário como "para o futuro", portanto, é possível que alguma versão futura do Bash armazene diferentes tipos de escalares em suas formas nativas.fonte
Pela minha vida, não consigo encontrar isso em nenhum lugar em tantas palavras, mas é assim que eu o entendo.
Bash é um intérprete, não um compilador e representa todas as variáveis como strings. Daí todo o esforço e ênfase que acompanham as expansões de vários tipos.
Bash passa passa todas as variáveis nomeadas para
declare
como cordas com atributos que controlam como essa variável deve ser expandida pordeclare
no armazenamento.E claro
A coda disso é que, mesmo que
declare
tenha uma representação interna que mude com os sinalizadores de atributo, as strings são tudo o que o bash vê ou deseja ver.fonte
Esta página possui um guia completo sobre como digitar variáveis no Bash. Esta seção tem mais informações sobre o
declare
comando interno. Este snippet de código desse link pode ser interessante:Aqui está a
man
página paradeclare
.fonte
Isso é irrelevante.
A única maneira de interagir com as variáveis do Bash é através do Bash, por isso é impossível notar qualquer diferença quanto à forma como as variáveis são armazenadas na memória, porque como você nunca pode acessá-las diretamente através da memória , sempre solicite ao Bash valor e Bash pode então traduzi-los de qualquer maneira que ele quer olhar como se eles tinham sido armazenados em qualquer forma específica.
Na verdade, eles não podem sequer ser armazenadas na memória em tudo . Não sei quão inteligentes são as implementações comuns do Bash, mas é pelo menos possível em casos simples determinar se uma variável será usada e / ou se será modificada e otimizá-la completamente ou incorporá-la.
fonte