Bash printf%q无效指令

时间:2014-09-26 22:08:54

标签: linux bash sed printf ps1

我想在.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

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

2 个答案:

答案 0 :(得分:6)

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
然后脚本会彻底搞砸了。它有点太聪明了。

答案 1 :(得分:0)

凯斯汤普森在答案中提出了很好的建议。但是FWIW,您可以通过在命令名前添加builtin来强制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

找出什么样的实体(shell函数,内置函数或外部命令)bash在你给它一个裸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,让我看看在将它们写入文件之前的修改。< / p>