Linux Bash printf%q指令无效

Linux Bash printf%q指令无效,linux,bash,sed,printf,ps1,Linux,Bash,Sed,Printf,Ps1,我想更改.bashrc文件中的PS1。 我发现一个脚本使用printf和%q指令来转义字符: #!/bin/bash STR=$(printf "%q" "PS1=\u@\h:\w\$ ") sed -i '/PS1/c\'"$STR" ~/.bashrc 问题是我遇到了以下错误: script.sh: 2: printf: %q: invalid directive 有什么想法吗?也许还有另一种方法可以转义字符?bash中内置了printf命令。它也是一个外部命令,通常安装在/usr/bi

我想更改.bashrc文件中的PS1。 我发现一个脚本使用printf和%q指令来转义字符:

#!/bin/bash
STR=$(printf "%q" "PS1=\u@\h:\w\$ ")
sed -i '/PS1/c\'"$STR" ~/.bashrc
问题是我遇到了以下错误:

script.sh: 2: printf: %q: invalid directive

有什么想法吗?也许还有另一种方法可以转义字符?

bash中内置了
printf
命令。它也是一个外部命令,通常安装在
/usr/bin/printf
中。在大多数Linux系统上,
/usr/bin/printf
是GNU coreutils实现

GNU coreutils
printf
命令的早期版本不支持
%q
格式说明符;它在2016年10月20日发布的8.25版中引入。bash内置的
printf
命令可以——并且只要bash有内置的
printf
命令就可以了

错误消息表示您正在使用bash以外的其他工具运行
script.sh

自从<代码>#/bin/bash行似乎是正确的,您可能正在执行以下操作之一:

sh script.sh
. script.sh
source script.sh
相反,只需直接执行它(在确保它具有执行权限后,如果需要,使用
chmod+x
):

或者您可以手动编辑
.bashrc
文件。如果脚本执行正确,将把这一行添加到
.bashrc

PS1=\\u@\\h:\\w\$\ 
(该行末尾的空格很重要。)或者您可以这样做:

PS1='\u@\h:\w\$ '
脚本的一个问题是,它将替换提到
PS1
的每一行。如果您只设置了一次,否则不引用它,这很好,但如果您有以下内容:

if [ ... ] ; then
    PS1=this
else
    PS1=that
fi

然后剧本会把事情搞得一团糟。这有点太聪明了。

基思·汤普森在他的回答中给出了很好的建议。但是FWIW,您可以通过在命令名前面加上
builtin
eg来强制bash使用内置命令

builtin printf "%q" "PS1=\u@\h:\w\$ "
相反地

命令printf“%s\n”某些内容

强制bash使用外部命令(如果可以找到)。

command
可用于在存在同名函数时调用磁盘上的命令。但是,
command
不会调用磁盘上的命令,而不是使用相同名称的Bash内置命令,它只用于抑制shell函数的调用。(感谢Rockallite提醒我注意此错误)

可以启用或禁用特定的bash内置项(可能您的.bashrc正在对printf执行此操作)。有关详细信息,请参阅帮助启用。我想我应该提一下你可以用

type printf
要了解当您为bash提供裸
printf
时,它将运行哪种类型的实体(shell函数、内置命令或外部命令)。通过传递
type
-a
选项,可以获得具有给定名称的所有命令的列表,例如

type -a printf 

您可以使用grep查看.bashrc文件中包含PS1的行:

grep 'PS1' ~/.bashrc 

这将为您提供行号和彩色输出。然后,您可以使用行号强制sed修改您想要更改的行

例如,如果grep告诉你,你想更改的行是第7行,你可以这样做

sed -i '7c\'"$STR" ~/.bashrc
编辑它。甚至更好

sed -i~ '7c\'"$STR" ~/.bashrc
它会备份文件的原始版本,以防您出错


当使用
sed-i
时,我通常首先在不使用
-i
的情况下进行测试运行,以便将输出发送到shell,让我在将修改写入文件之前查看修改的内容。

这是其中一种情况,在这种情况下,手动操作比使用奇特的命令行更简单、更安全。:)RE:
GNU coreutils printf命令不支持%q格式说明符
coreutils文档现在提到了
%q
指令:@JanusTroelsen:Updated。我认为在这种情况下使用
内置printf
不会有帮助。默认情况下,bash将使用内置的
printf
。如果在这种情况下它没有使用它,那是因为被调用的shell不是bash。除非它在shell启动期间被
enable-nprintf
出于某种奇怪的原因禁用。但我同意你的理论更有可能,我只是把它作为一种可能性提出来。直到现在,我还是设法避免学习
enable
命令。有意思。我承认这有点晦涩。我是最近才知道这件事的:我在bash man中偶然发现了它,当时我正在查找其他一些内置的细节。我相信有一天它会派上用场的……:)<代码>启用-n启用很诱人。
sed -i '7c\'"$STR" ~/.bashrc
sed -i~ '7c\'"$STR" ~/.bashrc