我正在尝试echo
在 Puppet 规则中使用来添加一行.bashrc
,但我似乎无法正确引用。
'/usr/bin/echo -E PS1=\"[\t--------------------------------------------------------\n-\u@\h:\W]\$\" >> /home/unu/.bashrc'
这件事给了我以下结果:
PS1="[t--------------------------------------------------------n-u@h:W]$"
另一种尝试:
'/usr/bin/echo -E PS1="[\t--------------------------------------------------------\n-\u@\h:\W]\$" >> /home/unu/.bashrc'
这件事给了我以下信息:
PS1=[\t--------------------------------------------------------\n-\u@\h:\W]$
另一个:
'/usr/bin/echo -e PS1="[\\t--------------------------------------------------------\\n-\\u@\\h:\\W]\\$" >> /home/unu/.bashrc'
这个给了我这个:
PS1=[ --------------------------------------------------------
-\u@\h:\W]$
\
如果没有或"
以某种方式解释,我似乎无法找到一种方法来做到这一点。我该怎么做?
我想过使用更多引号,但这会导致 Puppet 出现语法错误:
"/usr/bin/echo -e 'PS1="[\\t--------------------------------------------------------\\n-\\u@\\h:\\W]\\$"' >> /home/unu/.bashrc"
得到这个结果:
Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Syntax error at '' (file: /etc/puppetlabs/code/environments/production/modules/profile/manifests/ps1.pp, line: 3, column: 38) on node centoslave1
这是整个代码:
class profile::ps1 {
exec { 'myps1':
command => "/usr/bin/echo -e 'PS1="[\\t--------------------------------------------------------\\n-\\u@\\h:\\W]\\$"' >> /home/unu/.bashrc"
}
}
到底是怎么回事
了解哪里出了问题是正确解决问题的线索。元素的右侧,在 之后
然后,您会在其后面加上一些对于清单而言在语法上不正确的胡言乱语: 和另一个字符串:=>
,必须是一个字符串。字符串在 Puppet 中有多种形式。双引号字符串以双引号开头,以第二组结尾。所以你的字符串是正确执行此操作
自下而上构建正确的设置。从您希望命令输出到该文件的内容开始。输出是一个 shell 命令,它将
这样的命令是,使用单引号(这里最好是双引号,因为它不需要对这些PS1
shell 变量设置为:\
和$
字符进行转义)来阻止 shell 对转义序列进行转义: 您可以通过 shell 调用输出这样的命令echo
(我们将返回到这一点),但您需要通过更多转义确保单引号到达echo
命令:然而,这有一个问题,即
echo
跨平台和 shell 的行为不一致,并且(具有讽刺意味的是)它可能转换的转义序列实际上不是你想要的。实际上,尽管您的问题上有标签,但运行该命令的 shell 不一定是 Bourne Again shell,具体取决于操作系统(您尚未指定)。例如,它可能是 Debian Almquist shell。为了获得更好的结果,请使用printf
:请注意,到目前为止,假设它是提供给 shell 以执行的命令行。传递给
echo
and的参数的转义和引用,printf
以使它们最终得到正确的内容,这符合 shell 规则。因此,请注意有关提供商的问题评论。现在您需要将其编码为Puppet 字符串。单引号字符串在这里再次成为更好的选择,因为您只需要转义
'
and字符(这与单引号字符串的shell\
规则不太一样,请注意):进一步阅读
有(至少)两个层次的东西吞噬了你的角色:
echo
本身如果你运行:
你得到输出
因为外壳在反斜杠处吃了双引号,而不是回声。shell 将它们作为 shell 语法来表示
hello, "world"
作为单个参数传递给 echo。然后打印哪个回声,加上换行符。echo -e
特别是还解释反斜杠序列(取决于实现);这个问题的简单解决方案是使用printf '%s\n' WHATEVER
而不是echo WHATEVER
.在大多数情况下,您可以使用单引号保护某些内容免受 shell 的影响(只要它本身不包含单引号)。所以,你可能想要:
这使:
如果您必须在多层外壳转义中幸存下来,您可能会发现
printf '%q\n' WHATEVER
它很有用,它以某种格式打印它以在外壳中幸存下来(但这可能是 Bash 独有的功能,尚未检查)。顺便说一句:如果您需要保护单引号字符串中的单引号,则必须执行以下操作
'\''
:如果你仔细看它实际上是
'i'
+\'
+'ll'
。PS:
PS1
经历另一个扩展(参见 Bash 文档);你知道那些\u
很明显的。但是变量也被扩展了——所以如果你$
在最后有一些东西,你需要转义它(如果在双引号字符串中,则使用三个反斜杠):PS1="foo\\\$PATH % "
使用
printf
:你可以简单地使用
cat
:ps1-file
可以手动创建(使用您喜欢的编辑器),这样您就可以避免 / / 中的bash
转义echo
问题printf
。要使该文件到达节点,您需要添加一个文件部分。这意味着将原始文件放在
modulepath
. 由于其内容是少量文本,您可以使用 指定它们content =>
,但这会产生引用/转义问题。