【问题标题】:Bash Mapfile Var Adds SpaceBash Mapfile Var 增加空间
【发布时间】:2020-10-07 12:10:02
【问题描述】:

我不知道为什么会发生这种情况。

我想将交互式提示中的多行变量粘贴到映射文件中,然后像文件对象一样使用所述映射文件。

由于某种原因,我可以忍受回声中断并使用 printf,但为什么在将 mapfile 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-----

【问题讨论】:

  • mapfile -t
  • DELETE REVOKE YOUR PRIVATE KEY 因为你刚刚在这里发布了
  • 如果需要单个字符串,请将 [@] 替换为 [*]
  • 哇!所有伟大的帮助和答案。了不起的人!谢谢。
  • @LéaGris:SSH 密钥是一次性的。

标签: bash echo whitespace global var


【解决方案1】:

为什么会这样。

添加前导空格!

当然可以 - 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 "%s\n" "${a[*]}"; ) # well known method for printing arrays
+ IFS='|'
+ printf '%s\n' '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 Rationale for Shell and Utilities C.2.5 Parameters and Variables,它与$* $@ 相同,但与数组相同。

【讨论】:

  • 我已经复制了一些非常有用的 LoC。谢谢。
  • “这个答案很有用”我没有足够的声誉。
【解决方案2】:

对脚本的一些修复:

#!/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"

【讨论】:

  • 错过这个我觉得很愚蠢!哦快乐。合并您对其余脚本的更改,一切正常!谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-01
  • 1970-01-01
  • 2011-03-01
  • 1970-01-01
  • 2017-06-09
  • 2012-04-07
  • 2015-12-05
相关资源
最近更新 更多