6

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

#!/bin/bash
STR=$(printf "%q" "PS1=\u@\h:\w\$ ")
sed -i '/PS1/c\'"$STR" ~/.bashrc

问题是我收到此错误:

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

任何想法 ?也许是另一种逃避角色的方式?

4

2 回答 2

11

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

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

该错误消息暗示您正在script.sh使用 bash 以外的其他方式运行。

由于该#!/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

那么脚本将彻底搞砸。这有点太聪明了。

于 2014-09-26T23:27:45.777 回答
2

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

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

反过来,

command printf "%s\n" some stuff

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

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

可以启用或禁用特定的 bash 内置函数(也许您的 .bashrc 正在对 printf 执行此操作)。详情请参阅help enable。我想我应该提到你可以使用

type printf

找出当你给它一个裸的printf. 您可以通过传递选项来获取具有给定名称的所有命令的列表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,让我在将修改写入文件之前查看修改做了什么。

于 2014-09-27T19:25:56.563 回答