简体   繁体   English

Bash printf%q无效指令

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM