Toutes les variables sont-elles stockées en mémoire sous forme de chaîne dans bash?

14

Supposons que j'ai créé les variables suivantes:

s=John
i=12345
f=3.14

Toutes ces variables sont-elles stockées en mémoire sous forme de chaîne, ou bashont-elles d'autres types de données?

user268325
la source
1
Juste par intérêt, pourquoi est-ce important? Je m'en fous vraiment s'ils sont stockés en texte swahili tant qu'ils n'affectent pas la fonctionnalité de la langue (affecter les performances peut être un problème mais, si c'est important, ce sont de meilleurs outils dans votre arsenal que bash).
2
@paxdiablo Ce n'est pas grave, je demande juste par curiosité, car tous les autres langages de programmation / scripting que je connais (par exemple: Java, C ++, JavaScript, PHP, etc.) ont une représentation mémoire unique pour chaque type de données , il est donc intéressant de voir un langage de script qui n'a qu'une seule représentation mémoire pour tous les types de données.
user268325

Réponses:

16

Les variables bash sont non typées .

Contrairement à de nombreux autres langages de programmation, Bash ne sépare pas ses variables par "type". Essentiellement, les variables Bash sont des chaînes de caractères, mais, selon le contexte, Bash permet des opérations arithmétiques et des comparaisons sur les variables. Le facteur déterminant est de savoir si la valeur d'une variable ne contient que des chiffres.

Comme le dit une autre réponse , il existe une sorte de forme faible de frappe avec declare.

Il s'agit d'une forme très faible du typage [1] disponible dans certains langages de programmation.

Voir un exemple:

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.

Les références:

roaima
la source
13

Bash a essentiellement des variables scalaires simples, des tableaux et des tableaux associatifs. De plus, les scalaires peuvent être étiquetés comme des entiers avec la fonction declareintégrée . Du point de vue du programmeur de script / utilisateur du shell, les variables de chaîne agissent comme des chaînes, les variables entières agissent comme des entiers et les tableaux en fonction de leur type. L'implémentation interne n'est pas très pertinente.


Mais, si nous voulons savoir comment les données sont réellement stockées en mémoire, nous devons examiner le code source pour voir ce que fait réellement le programme.

Dans Bash 4.4, les scalaires sont stockés sous forme de chaînes, quelle que soit la balise entière. Ceci est visible dans la définition de struct variable/ the SHELL_VARtypedef et dans la fonctionmake_variable_value , qui traduit explicitement les entiers en chaînes pour le stockage.

Les tableaux sont stockés dans ce qui semble être une liste liée ( array.h) et des tableaux associatifs sous forme de tables de hachage. Les valeurs qu'elles contiennent sont à nouveau stockées sous forme de chaînes. Le choix d'une liste chaînée pour les tableaux peut sembler étrange, mais comme les tableaux peuvent être clairsemés et que les index peuvent être des nombres arbitraires indépendamment du peu d'éléments que le tableau contient, ce choix de conception est un peu plus facile à comprendre.

Cependant, le code contient également une définition de l' inutiliséunion _value , avec des champs pour les nombres entiers, les nombres à virgule flottante, ainsi que les valeurs de chaîne. Il est marqué dans un commentaire comme "pour le futur", il est donc possible qu'une future version de Bash stocke différents types de scalaires dans leurs formes natives.

ilkkachu
la source
1

Pour la vie de moi, je ne peux trouver cela déclaré nulle part en autant de mots, mais c'est ainsi que je le comprends.

Bash est un interpréteur, pas un compilateur et représente toutes les variables sous forme de chaînes. D'où tous les efforts et l'accent qui va avec les extensions de divers types.

Bash passe passe toutes les variables nommées en declaretant que chaînes avec des attributs qui contrôlent la façon dont cette variable doit être développée par declarele stockage.

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

Et bien sûr

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

Le coda est que même si leur declarereprésentation interne change avec les drapeaux d'attributs, les chaînes sont tout ce que bash voit ou veut voir.

bu5hman
la source
0

Cette page contient un guide complet sur la saisie de variables dans Bash. Cette section contient plus d'informations sur la declarecommande intégrée. Cet extrait de code de ce lien peut être intéressant:

[bob in ~] declare -i VARIABLE=12

[bob in ~] VARIABLE=string

[bob in ~] echo $VARIABLE
0

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

Voici la manpage pourdeclare .

Tanner Babcock
la source
0

Ce n'est pas pertinent.

La seule façon d'interagir avec les variables Bash est via Bash, il vous est donc impossible de remarquer une différence quant à la façon dont les variables sont stockées en mémoire, car vous ne pouvez jamais y accéder directement via la mémoire , vous devez toujours demander à Bash leur valeur, et Bash peut ensuite les traduire de la façon dont il veut ressembler à s'ils avaient été stockés d'une manière spécifique.

En fait, ils peuvent même ne pas être stockés en mémoire du tout . Je ne sais pas à quel point les implémentations courantes de Bash sont intelligentes, mais il est au moins possible dans des cas simples de déterminer si une variable sera utilisée et / ou si elle sera modifiée, et de l'optimiser complètement ou de l'intégrer.

Jörg W Mittag
la source
Je pense que le point de la question était la représentation plutôt que l' emplacement
bu5hman
2
Mon point est que vous ne pouvez pas connaître la représentation, parce que vous ne pouvez pas l'observer. Donc, c'est sans importance et cela pourrait changer sans que vous vous en rendiez compte. Il est tout simplement impossible de dire quelle représentation Bash pourrait choisir. Vous pouvez vous plonger dans le code source d'une implémentation et vérifier quelle représentation il choisit, mais cela pourrait changer la représentation demain dans la prochaine version du correctif et il n'y aurait aucun moyen de le savoir.
Jörg W Mittag
Variables Schroedingers? Je suis d'accord avec vous sur le fait que la représentation sous-jacente n'est pas pertinente (voir ma réponse), mais en utilisant bash, nous «codons vers une interface» et la représentation à l'interface est filandreuse.
bu5hman
2
Oui, mais la question ne porte pas sur la représentation à la frontière de l'interface, mais spécifiquement sur la façon dont ils sont "stockés en mémoire". Et à cette question, je répondrais: nous ne savons pas, ne pouvons pas et ne devrions pas savoir.
Jörg W Mittag
Ce qui paraphrase la dernière ligne de mon propre article ... comme je l'ai dit, nous sommes d'accord ... et étant donné le représentant des PO et la nature de la question, je pense qu'ils recevront des notes raisonnables pour leurs devoirs, peu importe qui est cité ;-).
bu5hman