11
votes

Y a-t-il une commande bash qui peut indiquer la taille d'une variable de coquille

existe-t-il un moyen de trouver la taille (mémoire utilisée) de la variable de coque à partir de la ligne de commande, sans utiliser c?


0 commentaires

4 Réponses :


14
votes

wc peut vous dire combien de caractères et d'octets sont dans une variable et bash lui-même peut vous dire combien d'éléments sont dans un tableau. Si ce que vous recherchez, c'est la manière dont les structures internes de grandes Bash sont destinées à détenir une variable spécifique, je ne crois pas que c'est disponible n'importe où. XXX


3 commentaires

Vous pouvez simplement écrire $ {# foo} pour avoir la longueur de chaîne - Vérifiez ma réponse


@Foo: en caractères, oui. Pas en octets.


Si vous recherchez vraiment la mémoire utilisée, vous devez ajouter la longueur du nom et ajouter des frais généraux. Et à peu près double pour les variables exportées.



2
votes
${#VAR}
tells you the length of the string VAR

4 commentaires

Et pour les tableaux, vous pouvez les développer avec $ {ary [*]} Attribuez-le à une variable TEMP et utilisez ce qui précède pour obtenir le total des valeurs. Plus utilisez $ {! Ary [*]} pour obtenir une liste des clés. Cela devient compliqué, n'est-ce pas?


Vous devez définir ifs = "" pour vous assurer que vous n'introduisez pas de caractères supplémentaires. c'est un pita, je sais


Vrai, mais c'est un cri lointain de la mémoire utilisée (en particulier, moins de la moitié si la variable est exportée et potentiellement moins dans une locale multi-octets puisque vous comptez des caractères et non des octets).


$ {# Var} sur un tableau donne la longueur du premier élément (voir la réponse de Dennis Williamson)



20
votes

Cela vous indique combien de caractères sont dans la valeur d'une variable scalaire nommée "var": xxx pré>

ceci vous indique le nombre d'éléments dans une matrice nommée "tableau": p> xxx pré>

Cela vous indique le nombre de caractères dans un élément d'un tableau: p> xxx pré>

Si vous essayez d'obtenir la taille de Un tableau et vous laissez l'index [@] code>, vous obtenez la longueur de l'élément 0: p> xxx pré>

si vous voulez la longueur totale de tous éléments d'un tableau, vous pouvez itérer sur la matrice et les ajouter, vous pouvez utiliser ifs code> et certaines étapes similaires à celles ci-dessous ou que vous pourriez: P>

for idx in ${!array[@]}
do
    something_with ${array[idx]}
done


2 commentaires

Ce n'est pas si simple ... SET LC_ALL = C Pour compter les octets plutôt que pour compter les cordes, et il y a la mémoire utilisée par le nom de la variable (et les touches, pour les tableaux), ainsi que des variables exportées, plus aérien.


woo hoo! $ (($ {# variable_name} + 1)) était exactement le modèle que je cherchais! :) #Différent_context #random



1
votes

pour une variable scalaire, $ {# var} code> vous donne la longueur en caractères. Dans une locale unibyte, c'est la longueur des octets. La taille en octets est la longueur du nom en octets, ainsi que la longueur de la valeur en octets, plus une surcharge constante. xxx pré>

si la variable est exportée, la taille est à peu près double. p> xxx pré>

pour une variable de matrice, vous devez résumer les longueurs (à nouveau, en octets) des éléments et ajouter une surcharge constante par élément plus une surcharge constante pour le Array. P>

_sizeof_pointer=4
_sizeof_int=4
_malloc_granularity=16
_malloc_overhead=16
## Usage: compute_size VAR
## Print the amount of memory (in bytes) used by VAR.
## The extra bytes used by the memory allocator are not taken into account.
add_size () {
  local IFS="+" this extra
  set $(($1 + _malloc_overhead))
  _size=$((_size + $1))
  set $(($1 % _malloc_granularity))
  [[ $1 -eq 0 ]] || _size=$((_size + _malloc_granularity - $1))
}
compute_size () {
  local LC_ALL=C _size=0 _key
  if eval "[ -z \${$1+1} ]"; then echo 0; return; fi
  add_size $((_sizeof_pointer*5 + _sizeof_int*2)) # constant overhead
  add_size ${#1} # the name
  case $(declare -p $1) in
    declare\ -x*)
      eval "add_size \${#$1}" # the value
      eval "add_size \$((\${#1} + \${#$1} + 2))" # the export string
      ;;
    declare\ -a*)
      eval 'for _key in "${!'$1'[@]}"; do
              add_size $_key
              add_size ${#'$1'[$_key]}
              add_size $((_sizeof_pointer*4))
            done'
      add_size $((_sizeof_pointer*2 + _sizeof_int*2))
      add_size $((_sizeof_pointer*4))
      ;;
    *)
      eval "add_size \${#$1}" # the value
      ;;
  esac
  echo $_size
}


0 commentaires