Linux 是否有一个 bash 命令可以告诉 shell 变量的大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4988155/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a bash command that can tell the size of a shell variable
提问by Ankur Agarwal
Is there a way to find the size(memory used) of shell variable from command line, without using C ?
有没有办法在不使用 C 的情况下从命令行查找 shell 变量的大小(使用的内存)?
采纳答案by Ignacio Vazquez-Abrams
wc
can tell you how many characters and bytes are in a variable, and bash itself can tell you how many elements are in an array. If what you're looking for is how large bash's internal structures are for holding a specific variable then I don't believe that's available anywhere.
wc
可以告诉您变量中有多少字符和字节,而 bash 本身可以告诉您数组中有多少元素。如果您正在寻找的是用于保存特定变量的 bash 内部结构有多大,那么我认为这在任何地方都不可用。
$ foo=42
$ bar=(1 2 3 4)
$ echo -n "$foo" | wc -c -m
2 2
$ echo "${#bar[@]}"
4
回答by Foo Bah
${#VAR}
tells you the length of the string VAR
告诉你字符串的长度 VAR
回答by Paused until further notice.
This tells you how many characters are in the value of a scalar variable named "var":
这告诉您名为“var”的标量变量的值中有多少个字符:
echo ${#var}
This tells you the number of elements in an array named "array":
这会告诉您名为“array”的数组中的元素数:
echo ${#array[@]}
This tells you the number of characters in an element of an array:
这告诉您数组元素中的字符数:
echo ${#array[3]}
If you try to get the size of an array and you leave out the [@]
index, you get the length of element 0:
如果您尝试获取数组的大小而忽略[@]
索引,则会得到元素 0 的长度:
$ array=(1 22 333 4444)
$ echo ${#array}
1
$ echo ${#array[@]}
4
$ echo ${#array[2]}
3
If you want the total length of all elements of an array, you could iterate over the array and add them up, you could use IFS
and some steps similar to those below, or you could:
如果你想要一个数组所有元素的总长度,你可以遍历数组并将它们相加,你可以使用IFS
和下面类似的一些步骤,或者你可以:
$ tmp="${array[*]}"
$ echo $(( ${#tmp} - ${#array[@]} + 1 ))
10
Beware of using the number of elements in an array as the index of the last element since Bash supports sparse arrays:
请注意使用数组中元素的数量作为最后一个元素的索引,因为 Bash 支持稀疏数组:
$ array=(1 22 333 4444 55555)
$ echo ${#array[@]}
5
$ array[9]=999999999
$ echo ${#array[@]}
6
$ echo ${array[${#array[@]} - 1]} # same as echo ${array[6 - 1]}
$ # only a newline is echoed since element 5 is empty (only if "nounset" option* is not set (default in most cases))
$ # when "nounset" option is set (possibly using command "set -u") then bash will print such error:
$ # bash: array[${#array[@]} - 1]: unbound variable
$ unset "array[1]" # always quote array elements when you unset them
$ echo ${#array[@]}
5
$ echo ${array[${#array[@]} - 1]} # same as echo ${array[5 - 1]}
55555
That was obviously not the last element. To get the last element:
这显然不是最后一个要素。获取最后一个元素:
$ echo ${array[@]: -1} # note the space before the minus sign
999999999
Note that in the upcoming Bash 4.2, you can do echo ${array[-1]}
to get the last element. In versions prior to 4.2, you get a bad subscript error for negative subscripts.
请注意,在即将发布的 Bash 4.2 中,您可以echo ${array[-1]}
获取最后一个元素。在 4.2 之前的版本中,负下标会出现错误的下标错误。
To get the index of the last element:
获取最后一个元素的索引:
$ idx=(${!array[@]})
$ echo ${idx[@]: -1}
9
Then you can do:
然后你可以这样做:
$ last=${idx[@]: -1}
$ echo ${array[last]}
999999999
To iterate over a sparse array:
迭代稀疏数组:
for idx in ${!array[@]}
do
something_with ${array[idx]}
done
* I recommend avoiding nounset
* 我建议避免 nounset
回答by Gilles 'SO- stop being evil'
For a scalar variable, ${#VAR}
gives you the length in characters. In a unibyte locale, this is the length in bytes. The size in bytes is the length of the name in bytes, plus the length of the value in bytes, plus a constant overhead.
对于标量变量,${#VAR}
以字符为单位提供长度。在单字节语言环境中,这是以字节为单位的长度。以字节为单位的大小是名称的长度(以字节为单位)加上值的长度(以字节为单位),再加上常数开销。
LC_ALL=C
name=VAR
size=$(($#name + $#VAR)) # plus a small overhead
If the variable is exported, the size is roughly double.
如果变量被导出,大小大约是两倍。
LC_ALL=C
name=VAR
size=$((($#name + $#VAR) * 2)) # plus a small overhead
For an array variable, you need to sum up the lengths (again, in bytes) of the elements, and add a constant overhead per element plus a constant overhead for the array.
对于数组变量,您需要对元素的长度(再次以字节为单位)求和,并为每个元素添加一个常量开销加上数组的常量开销。
LC_ALL=C
name=VAR
size=$(($#name)) # plus a small overhead
for key in "${!VAR[@]}"; do
size=$((size + ${#key} + ${#VAR[$key]})) # plus a small overhead
done
Here's a minimally tested function that computes the approximate size occupied by a variable. Arrays and exports are taken into account, but not special read-only variables such as $RANDOM
. The sizes have been observed on bash 4.2, different versions may have different overheads. You may need to adjust the constants depending on your system types and malloc
implementation.
这是一个经过最少测试的函数,用于计算变量占用的近似大小。考虑数组和导出,但不考虑特殊的只读变量,例如$RANDOM
. 大小已在 bash 4.2 上观察到,不同的版本可能有不同的开销。您可能需要根据您的系统类型和malloc
实现来调整常量。
_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 $(( + _malloc_overhead))
_size=$((_size + ))
set $(( % _malloc_granularity))
[[ -eq 0 ]] || _size=$((_size + _malloc_granularity - ))
}
compute_size () {
local LC_ALL=C _size=0 _key
if eval "[ -z ${+1} ]"; then echo 0; return; fi
add_size $((_sizeof_pointer*5 + _sizeof_int*2)) # constant overhead
add_size ${#1} # the name
case $(declare -p ) in
declare\ -x*)
eval "add_size ${#}" # the value
eval "add_size $((${#1} + ${#} + 2))" # the export string
;;
declare\ -a*)
eval 'for _key in "${!''[@]}"; do
add_size $_key
add_size ${#''[$_key]}
add_size $((_sizeof_pointer*4))
done'
add_size $((_sizeof_pointer*2 + _sizeof_int*2))
add_size $((_sizeof_pointer*4))
;;
*)
eval "add_size ${#}" # the value
;;
esac
echo $_size
}