I want to change my PS1 in my .bashrc file. I've found a script using printf with %q directive to escape characters :
#!/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. It's also an external command, typically installed in/usr/bin/printf
. On most Linux systems,/usr/bin/printf
is the GNU coreutils implementation.Older releases of the GNU coreutils
printf
command do not support the%q
format specifier; it was introduced in version 8.25, released 2016-10-20. bash's built-inprintf
command does -- and has as long as bash has had a built-inprintf
command.The error message implies that you're running
script.sh
using something other than bash.Since the
#!/bin/bash
line appears to be correct, you're probably doing one of the following:Instead, just execute it directly (after making sure it has execute permission, using
chmod +x
if needed):Or you could just edit your
.bashrc
file manually. The script, if executed correctly, will add this line to your.bashrc
:(The space at the end of that line is significant.) Or you can do it more simply like this:
One problem with the script is that it will replace every line that mentions
PS1
. If you just set it once and otherwise don't refer to it, that's fine, but if you have something like: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
egConversely,command printf "%s\n" some stuff
forces bash to use the external command (if it can find one).
command
can be used to invoke commands on disk when a function with the same name exists. 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. (Thanks to Rockallite for bringing this error to my attention).It's possible to enable or disable specific bash builtins (maybe your .bashrc is doing that to printf). See
help enable
for details. And I guess I should mention that you can useto find out what kind of entity (shell function, builtin, or external command) bash will run when you give it a naked
printf
. You can get a list of all commands with a given name by passingtype
the-a
option, egYou can use grep to see the lines in your .bashrc file that contain PS1:
or
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.
Eg, if grep tells you that the line you want to change is line 7, you can do
to edit it. Or even better,
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.