Bash printf %q 无效指令

问题描述 投票:0回答:3

我想更改 .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

有什么想法吗?也许还有另一种逃避角色的方法?

linux bash sed printf ps1
3个回答
15
投票

printf
命令内置于 bash 中。它也是一个外部命令,通常安装在
/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
):

./script.sh

或者您可以手动编辑您的

.bashrc
文件。如果正确执行该脚本,则会将此行添加到您的
.bashrc
:

PS1=\\u@\\h:\\w\$\ 

(该行末尾的空格很重要。)或者您可以像这样更简单地做到这一点:

PS1='\u@\h:\w\$ '

脚本的一个问题是它将替换提到 PS1

每一行
。如果您只设置一次并且不引用它,那很好,但是如果您有类似的内容:

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

那么脚本就会彻底搞乱它。就是有点太聪明了。


2
投票

Keith Thompson 在他的回答中给出了很好的建议。但是 FWIW,您可以通过在命令名称前面加上

builtin
来强制 bash 使用内置命令,例如

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

相反,

command printf "%s\n" some stuff

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

当存在同名的

function

 时,
command 可用于调用磁盘上的命令。但是,
command
会调用磁盘上的命令来代替具有相同名称的 Bash 内置命令,它仅用于抑制 shell 函数的调用。 (感谢 Rockallite 提醒我注意这个错误)。

可以启用或禁用特定的 bash 内置函数(也许您的 .bashrc 正在对 printf 执行此操作)。详情请参阅

help enable
。我想我应该提到你可以使用

type printf

找出当你给它一个裸

printf
时bash将运行什么样的实体(shell函数、内置或外部命令)。您可以通过传递
type
-a
选项来获取具有给定名称的所有命令的列表,例如

type -a printf 

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

grep 'PS1' ~/.bashrc 

grep -n0 --color=auto 'PS1=' ~/.bashrc

它为您提供行号和精美的彩色输出。然后你可以使用行号来强制 sed 只修改你想要更改的行。

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

sed -i '7c\'"$STR" ~/.bashrc

编辑它。或者更好,

sed -i~ '7c\'"$STR" ~/.bashrc

它会备份文件的原始版本,以防您犯错误。

使用

sed -i
时,我通常会先在没有
-i
的情况下进行测试运行,以便输出到达 shell,让我在将修改写入文件之前查看修改的作用。


0
投票

对于使用

fish-shell
的其他人,我没有意识到
fish-shell
实际上有自己的“内置”
printf
函数,但不支持
%q
指令。当我尝试在
fish
shell 中使用该指令时,我会收到如下错误消息:

%q: invalid conversion specification

当我退出

fish-shell
并直接使用
zsh
时,我能够毫无问题地使用
printf '%q\n' ...

© www.soinside.com 2019 - 2024. All rights reserved.