Bash Mapfile Var添加空间



我很困惑为什么会发生这种情况。

我想将交互式提示中的多行var粘贴到地图文件中,然后像处理文件对象一样处理所述地图文件。

由于某种原因,我可以使用printf来处理回声中断,但为什么在将映射文件var分配给另一个(全局(var时添加前导空格?

#!/bin/bash
global_privkey=""
myfunc(){
local input_pattern
# Paste SSH privkey.
builtin echo "paste your privkey:"
builtin mapfile input_pattern
# Adds leading space!
builtin echo "echo (adds space):"
builtin echo "${input_pattern[@]}"
# Works.
builtin echo "printf (good):"
builtin printf "%s" "${input_pattern[@]}"
builtin echo
# Adds leading space!
global_privkey="${input_pattern[@]}"
}
myfunc
# Leading space!
builtin echo "global printf (adds space from var assignment):"
builtin printf "%s" "$global_privkey"
builtin echo
exit 0

输出:

arch :: ~/scripts % ./input_privkey_minimal.sh
paste your privkey:
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACCzzWDcxsfWJ0NI15wBtPLqQPfryYDSZz8jN+eSk7+pdAAAALD7CKEF+wih
BQAAAAtzc2gtZWQyNTUxOQAAACCzzWDcxsfWJ0NI15wBtPLqQPfryYDSZz8jN+eSk7+pdA
AAAED6QmKlvu9ASHyHHBm7oLq7l2AMglXKq+uJ9IlbZBDbc7PNYNzGx9YnQ0jXnAG08upA
9+vJgNJnPyM355KTv6l0AAAAKHJvYmVydEAxMDItMTgyLTE1NS0zNS5pcC5hZnJpaG9zdC
5qb2J1cmcBAgMEBQ==
-----END OPENSSH PRIVATE KEY-----
echo (adds space):
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACCzzWDcxsfWJ0NI15wBtPLqQPfryYDSZz8jN+eSk7+pdAAAALD7CKEF+wih
BQAAAAtzc2gtZWQyNTUxOQAAACCzzWDcxsfWJ0NI15wBtPLqQPfryYDSZz8jN+eSk7+pdA
AAAED6QmKlvu9ASHyHHBm7oLq7l2AMglXKq+uJ9IlbZBDbc7PNYNzGx9YnQ0jXnAG08upA
9+vJgNJnPyM355KTv6l0AAAAKHJvYmVydEAxMDItMTgyLTE1NS0zNS5pcC5hZnJpaG9zdC
5qb2J1cmcBAgMEBQ==
-----END OPENSSH PRIVATE KEY-----
printf (good):
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACCzzWDcxsfWJ0NI15wBtPLqQPfryYDSZz8jN+eSk7+pdAAAALD7CKEF+wih
BQAAAAtzc2gtZWQyNTUxOQAAACCzzWDcxsfWJ0NI15wBtPLqQPfryYDSZz8jN+eSk7+pdA
AAAED6QmKlvu9ASHyHHBm7oLq7l2AMglXKq+uJ9IlbZBDbc7PNYNzGx9YnQ0jXnAG08upA
9+vJgNJnPyM355KTv6l0AAAAKHJvYmVydEAxMDItMTgyLTE1NS0zNS5pcC5hZnJpaG9zdC
5qb2J1cmcBAgMEBQ==
-----END OPENSSH PRIVATE KEY-----
global printf (adds space from var assignment):
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACCzzWDcxsfWJ0NI15wBtPLqQPfryYDSZz8jN+eSk7+pdAAAALD7CKEF+wih
BQAAAAtzc2gtZWQyNTUxOQAAACCzzWDcxsfWJ0NI15wBtPLqQPfryYDSZz8jN+eSk7+pdA
AAAED6QmKlvu9ASHyHHBm7oLq7l2AMglXKq+uJ9IlbZBDbc7PNYNzGx9YnQ0jXnAG08upA
9+vJgNJnPyM355KTv6l0AAAAKHJvYmVydEAxMDItMTgyLTE1NS0zNS5pcC5hZnJpaG9zdC
5qb2J1cmcBAgMEBQ==
-----END OPENSSH PRIVATE KEY-----

为什么会发生这种情况。

添加前导空格!

当然可以-echo用空格分隔参数。

$ echo '1'       "2"           3
1 2 3             # wow single spaces

$ a=(1     2    '3     var     with  spaces')
$ echo "${a[@]}"
1 2 3     var     with  spaces       # arguments contents are preserved

当您将多个参数传递给echo时,这些参数由空格分隔。

mapfile不会从数组元素中删除尾随分隔符。因此,每个数组元素都以一条换行符结束。另外,echo输出第二个换行符,因此打印出两个换行符从而产生一个空行。

$ a=(1$'n' 2$'n' 3$'n')    # mapfile leaves newline in variables
$ set -x
$ echo "${a[@]}"
+ echo '1
' '2
' '3
'      # executes echo with 3 arguments, each with a newline
1
2     # echo outputs values separated by spaces
3
# echo outputs extra newline

# the echo "${a[@]}" is equal to:
$ echo 1$'n' 2$'n' 3$'n'
1
2
3
$

当在分配中使用${array[@]}扩展数组时,数组元素使用IFS中的第一个字符(默认为空格(进行连接。在该上下文中,它等于${array[*]}(因为"单词"在赋值时被连接在一起(。

$ set -x
$ a=(1 2 3)
+ a=(1 2 3)
$ echo "${a[@]}"
+ echo 1 2 3  # passes 3 arguments
1 2 3
$ echo "${a[*]}"
+ echo '1 2 3'  # passes 1 argument separated by first character in IFS
1 2 3
$ ( IFS='|'; printf "%sn" "${a[*]}"; ) # well known method for printing arrays
+ IFS='|'
+ printf '%sn' '1|2|3'
1|2|3
$ b="${a[@]}"
+ b='1 2 3'   # wow, spaces
$ b="${a[*]}"
+ b='1 2 3'   # * will be equal to @ in assignment

使用[*][@]的数组扩展的处理方式类似于使用位置自变量的$*$@。对于更广泛的示例,我推荐Posix Reason For Shell and Utilities C.2.5参数和变量,它与$*$@相同,但与阵列相同。

对脚本的一些修复:

#!/usr/bin/env bash
global_privkey=""
myfunc(){
local input_pattern
# Paste SSH privkey.
echo "paste your privkey:"
mapfile -t input_pattern
# Adds leading space!
echo "echo (adds space):"
echo "${input_pattern[@]}"
# Works.
echo "printf (good):"
printf %s\n "${input_pattern[@]}"
echo
# Delete BEGIN END entries
unset 'input_pattern[0]' 'input_pattern[-1]'
# Join lines into a single string
printf -v global_privkey %s "${input_pattern[@]}"
}
myfunc
# Leading space!
echo "global printf (adds space from var assignment):"
printf %s\n "$global_privkey"

相关内容

  • 没有找到相关文章

最新更新