在不使用引号的情况下在 shell 中将一个变量分配给另一个变量有什么问题吗?

Cal*_*aul 5 shell posix quoting assignment

这个问题是关于一个变量的全部内容分配给另一个变量。

使用变量(发送至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
Run Code Online (Sandbox Code Playgroud)

我在写作时有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 \
Run Code Online (Sandbox Code Playgroud)

Sté*_*las 12

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

var=$otherVar
Run Code Online (Sandbox Code Playgroud)

很好。您正在分配给一个标量变量,所以这里不能有 glob+splitting,所以您不需要写它var="$otherVar"(尽管这里的引号没有害处)。

一个例外是:

var=$*
Run Code Online (Sandbox Code Playgroud)

和:

var=$@
Run Code Online (Sandbox Code Playgroud)

您应该只使用var="$*". var=$@ var=$* var="$@"当的第一个字符$IFS不是空格时,shell的行为会有所不同。

当然,在:

array=("$var")
Run Code Online (Sandbox Code Playgroud)

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

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

export var="$otherVar"
Run Code Online (Sandbox Code Playgroud)

有许多外壳(在它们中,这里是一个简单的命令,因此出现 split+glob)。

在:

env var="$otherVar" cmd
Run Code Online (Sandbox Code Playgroud)

或者

awk -v var="$otherVar"...
Run Code Online (Sandbox Code Playgroud)

如果有疑问,请使用引号。


1一些旧版本zshsh模拟时通配符前面有反斜杠的问题:

$ (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"')
\*
Run Code Online (Sandbox Code Playgroud)

很久以前就修好了。