[英]Bash printf %q invalid directive
I want to change my PS1 in my .bashrc file. 我想在.bashrc文件中更改我的PS1。 I've found a script using printf with %q directive to escape characters : 我找到了一个使用带有%q指令的printf来转义字符的脚本:
#!/bin/bash
STR=$(printf "%q" "PS1=\u@\h:\w\$ ")
sed -i '/PS1/c\'"$STR" ~/.bashrc
The problem is that I get this error : 问题是我收到此错误:
script.sh: 2: printf: %q: invalid directive
Any idea ? 任何想法 ? Maybe an other way to escape the characters ? 也许另一种逃避角色的方法?
The printf
command is built into bash. printf
命令内置于bash中。 It's also an external command, typically installed in /usr/bin/printf
. 它也是一个外部命令,通常安装在/usr/bin/printf
。 On most Linux systems, /usr/bin/printf
is the GNU coreutils implementation. 在大多数Linux系统上, /usr/bin/printf
是GNU coreutils实现。
Older releases of the GNU coreutils printf
command do not support the %q
format specifier; 较早版本的GNU coreutils printf
命令不支持%q
格式说明符; it was introduced in version 8.25, released 2016-10-20. 它是在2016年10月20日发布的版本8.25中引入的。 bash's built-in printf
command does -- and has as long as bash has had a built-in printf
command. bash的内置printf
命令可以 - 并且只要bash有内置的printf
命令。
The error message implies that you're running script.sh
using something other than bash. 错误消息暗示您正在使用bash之外的其他内容运行script.sh
。
Since the #!/bin/bash
line appears to be correct, you're probably doing one of the following: 由于#!/bin/bash
行似乎是正确的,您可能正在执行以下操作之一:
sh script.sh
. script.sh
source script.sh
Instead, just execute it directly (after making sure it has execute permission, using chmod +x
if needed): 相反,只需直接执行它(在确保它具有执行权限后,如果需要,使用chmod +x
):
./script.sh
Or you could just edit your .bashrc
file manually. 或者您可以手动编辑.bashrc
文件。 The script, if executed correctly, will add this line to your .bashrc
: 如果脚本正确执行,则会将此行添加到.bashrc
:
PS1=\\u@\\h:\\w\$\
(The space at the end of that line is significant.) Or you can do it more simply like this: (该行末尾的空间很重要。)或者你可以更简单地这样做:
PS1='\u@\h:\w\$ '
One problem with the script is that it will replace every line that mentions PS1
. 该脚本的一个问题是它将替换提到PS1
每一行。 If you just set it once and otherwise don't refer to it, that's fine, but if you have something like: 如果你只是设置一次,否则不参考它,那很好,但如果你有类似的东西:
if [ ... ] ; then
PS1=this
else
PS1=that
fi
then the script will thoroughly mess that up. 那么剧本就会彻底搞砸了。 It's just a bit too clever. 这有点太聪明了。
Keith Thompson has given good advice in his answer. 基思汤普森在答案中提出了很好的建议。 But FWIW, you can force bash to use a builtin command by preceding the command name with builtin
eg 但是FWIW,你可以强制bash使用内置命令,在命令名前加上builtin
例如
builtin printf "%q" "PS1=\u@\h:\w\$ "
Conversely, 反过来,
command printf "%s\\n" some stuff
forces bash to use the external command (if it can find one). 强制bash使用外部命令(如果可以找到一个)。
command
can be used to invoke commands on disk when a function with the same name exists. command
时,可以使用具有相同名称的功能存在于磁盘上的调用命令。 However, command
does not invoke a command on disk in lieu of a Bash built-in with the same name, it only works to suppress invocation of a shell function. 然而, command
磁盘上不代替猛砸调用命令的内置具有相同的名称,它只能抑制一个shell函数的调用。 (Thanks to Rockallite for bringing this error to my attention). (感谢Rockallite引起我的注意这个错误)。
It's possible to enable or disable specific bash builtins (maybe your .bashrc is doing that to printf). 可以启用或禁用特定的bash内置函数(也许你的.bashrc正在对printf执行此操作)。 See help enable
for details. 请参阅help enable
了解详情。 And I guess I should mention that you can use 我想我应该提一下,你可以使用
type printf
to find out what kind of entity (shell function, builtin, or external command) bash will run when you give it a naked printf
. 找出什么样的实体(shell函数,内置函数或外部命令)bash在你给它一个裸露的printf
时会运行。 You can get a list of all commands with a given name by passing type
the -a
option, eg 您可以通过传递type
-a
选项来获取具有给定名称的所有命令的列表,例如
type -a printf
You can use grep to see the lines in your .bashrc file that contain PS1: 您可以使用grep查看.bashrc文件中包含PS1的行:
grep 'PS1' ~/.bashrc
or 要么
grep -n0 --color=auto 'PS1=' ~/.bashrc
which gives you line numbers and fancy coloured output. 它为您提供行号和彩色输出。 And then you can use the line number to force sed to just modify the line you want changed. 然后,您可以使用行号强制sed只修改您想要更改的行。
Eg, if grep tells you that the line you want to change is line 7, you can do 例如,如果grep告诉您要更改的行是第7行,则可以执行此操作
sed -i '7c\'"$STR" ~/.bashrc
to edit it. 编辑它。 Or even better, 甚至更好,
sed -i~ '7c\'"$STR" ~/.bashrc
which backs up the original version of the file in case you make a mistake. 如果您犯了错误,它会备份文件的原始版本。
When using sed -i
I generally do a test run first without the -i
so that the output goes to the shell, to let me see what the modifications do before I write them to the file. 当使用sed -i
我通常在没有-i
情况下首先进行测试运行,以便输出转到shell,让我看看在将它们写入文件之前修改了什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.