很好的Bash引用风格

很好的Bash引用风格,bash,Bash,您能否引用这个变量分配,它从一些预先计算的组件生成日志消息 formatted_message=$(printf '%s [PID %s] %s (%s) %s:%s | %s\n' \ "${TIMESTAMP}" \ "${PROCESS}" \ "${SEVERITY}" \

您能否引用这个变量分配,它从一些预先计算的组件生成日志消息

formatted_message=$(printf '%s [PID %s] %s (%s) %s:%s | %s\n' \
                           "${TIMESTAMP}" \
                           "${PROCESS}" \
                           "${SEVERITY}" \
                           "${SOURCE}" \
                           "${FUNCTION}" \
                           "${LINE}" \
                           "${MESSAGE}")
这种Bash编程风格真的很好吗

我喜欢尝试学习一些Bash,但我发现有些东西“效率低下”:

  • 当有那么多关于引号在不同上下文中的含义的规则时,我必须(用一个“心智编译器”)不断地解析我读过的代码,然后再读,再读,应用一些特定于上下文的隐式规则(例如,表达式的左侧、右侧、应用于数组的扩展与标量值等)至少对我来说,这在精神上很麻烦。在我过于简单的世界观中,有一个固定的约定和简单的异常将允许我更快地阅读代码,有时编写代码时会增加一两个字符,但在一般情况下,非常“自动”,特别是更容易识别异常
让我们举一个让我对“最佳编码实践”感到困惑的例子:

我可以省略左边的引语,而不会有任何实际的行为改变。。将它们添加到评估的右侧具有重要的效果。突然间,我对过程替代和所有其他“评估/替代”上下文产生了疑问,我希望有一种简单的方法来实现它,除了少数例外

如果有一篇关于这方面的指导性文章/博客文章,我真的会详细研究它,了解(希望)一个真正的Bash程序员在将引用放在省略它们的特定位置时想要传达什么

注:我的学习发生在夜间的收费站。除了你们,我这里没有其他程序员来比较我的观点,有些开源代码“就在那里”,没有附带的注释来证明选择像“编码风格”这样微妙的选择是合理的

另一点:我发现总是打字更容易:

printf "${my_string_var}"
但这当然也很好:

printf "$my_string_var"
(我只是碰巧用
{}
更好地“看到”了变量扩展)

但这可能不等同于word split变量内容(?)


总结 如果你只想回答一个简单、直截了当的问题,并且远离“辩论”:

  • 你会引用上面的第一个作业吗?为什么?

注意:我的一个问题是,即使我尝试在这里和那里加上双引号,最后的
\n
也会消失。。但现在我明白了,
$()
将其剥离。

我不会引用右侧,因为通常的原因(防止无意中的分词)不适用于变量赋值的RHS

如果您使用的是
bash
4或更高版本,则可以完全免除该赋值。此外,如果不需要大括号来应用参数展开运算符或将参数名与相邻字符隔离,我发现大括号是不必要的,而且会分散注意力。当然,引用仍然很重要

printf -v formatted_message '%s [PID %s] %s (%s) %s:%s | %s\n' \
                       "$TIMESTAMP" \
                       "$PROCESS" \
                       "$SEVERITY" \
                       "$SOURCE" \
                       "$FUNCTION" \
                       "$LINE" \
                       "$MESSAGE"

在shell脚本中引用不是一件简单的事情。这里有一些有用的链接:,和。我发现,在这里花时间阅读有关stackoverflow的shell和bash问题,仅仅通过重复就巩固了引用的细微差别。不断地尝试和询问:你最终会到达那里。当有疑问时(也许还有其他时候),引用你的字符串和变量。你很快就会遇到实际需要它们的情况。例如,当第一个变量为空时,您的
[[[$x==“$x”]]
可能会产生意外的结果。不管怎样,就这些事情而言,Bash太复杂了。我建议你去参加Bash或其他活动。这就是我学习英语的方式,尽管这对我来说有点挑战,因为英语不是我的第一语言英语是我的第一语言,我仍然觉得
bash
手册页有时很有挑战性我总是忘记在这些情况下,
print-v
正是我所需要的。谢谢你提醒我。我之所以使用大括号,是因为在某些情况下,人们需要大括号,而且,正如您所知,我更喜欢一直做一些事情,而不是先考虑它,为算法、良好的代码架构等留出更多思考时间。无论如何,谢谢。。和往常一样。亲爱的@chepner,我需要补充一点,那就是你建议我重新安排我的作业有一个非常重要的好处。。有些事你忘了提,但我相信你已经知道了。。你的作业实际上保留了最后的换行符!下面让我举一个例子来说明我的意思….
v=$(printf“newlines\n”);回声“$v”;printf-v w“换行符\n”;回显“$w”
和。。除了优点之外,我还可以看到使用
printfo-v
的一个限制:您不能指定您希望以这种方式将结果分配给只读变量,对吗?您可以始终设置变量的值,然后将其标记为只读(
printfo-v foo bar;declare-r foo
),但我认为,如果只读变量很重要,您可能需要重新考虑您的语言选择。
printf $my_string_var # with $my_string_var := 'foo bar'
printf -v formatted_message '%s [PID %s] %s (%s) %s:%s | %s\n' \
                       "$TIMESTAMP" \
                       "$PROCESS" \
                       "$SEVERITY" \
                       "$SOURCE" \
                       "$FUNCTION" \
                       "$LINE" \
                       "$MESSAGE"