在 shell 中不使用引号将一个变量分配给另一个变量有问题吗?

在 shell 中不使用引号将一个变量分配给另一个变量有问题吗?

这个问题是关于指派将一个变量的全部内容复制到另一个变量。

变量不存在用过的(发送至echo等)

参数扩展正在作业期间完成。

我的问题也仅与 POSIX shell 有关(此处未使用数组)。

error="You have an error in your input"

newVar="$error"
# vs.
newVar=$error
#         ↑
#         └─This assignment is the question. It doesn't seem that quotes are
#           needed here in order to assign the entire contents of $error to
#           a new variable.

#                 ┌─(But quotes are required when they're used.)
#                 ↓
printf "%s\n" "$error"
# => You have an error in your input
printf "%s\n" "$newVar"
# => You have an error in your input

我在写作中是否遗漏了任何陷阱newVar=$error

更新:

无论 中的内容如何$error,​​我想知道相同的数据是否会在$newVar不引发任何错误或损坏数据的情况下保留下来。

$ error="Test * ${1} \n [!a] [[:punct:]] ./test \t \n \\"
$ newVar=$error
#       ↑
#       └─Does this step ever fail or cause the two variables to differ?
$ echo "$error"
Test *  \n [!a] [[:punct:]] ./test \t \n \
$ echo "$newVar"
Test *  \n [!a] [[:punct:]] ./test \t \n \

答案1

在类似 Bourne 的 shell 中(如果我们忘记了某些 shell 的旧实现中的bug 1 )

var=$otherVar

很好。您正在分配给标量变量,因此这里不能有 glob+splitting,因此您不需要编写它var="$otherVar"(尽管引号在这里不会造成伤害)。

例外情况是:

var=$*

和:

var=$@

你应该只使用var="$*".var=$@ var=$* var="$@"当 的第一个字符$IFS不是空格时, 的行为因 shell 而异。

当然,在:

array=("$var")

您确实需要引号,否则数组元素将被分配为 split+globbing 的结果$var

另请注意,您需要以下引号:

export var="$otherVar"

有很多 shell(在它们中,这里是一个简单的命令,所以 split+glob 发生)。

并在:

env var="$otherVar" cmd

或者

awk -v var="$otherVar"...

如有疑问,请使用引号。


1某些旧版本在模拟zsh时存在通配符前面的反斜杠问题sh

$ (a='\*' exec -a sh zsh-3.1.9 -c 'b=$a; printf "%s\n" "$b"')
*
$ (a='\*' exec -a sh zsh-3.1.9 -c 'b="$a"; printf "%s\n" "$b"')
\*

这是很久以前就解决的。

相关内容