Ran into an issue when running the following command in a fish
shell:
❯ printf '%q\n' 'André Previn & London Symphony Orchestra'
%q: invalid conversion specification
I hadn't realized at first that fish
actually has their own custom printf
function that behaves in largely the same way as the GNU coreutils
printf
function, but does not support the q
directive like GNU coreutils
printf
does.
fish-shell
docs:
https://fishshell.com/docs/current/cmds/printf.html#format-specifiers
GNU coreutils
printf
docs:
https://www.gnu.org/software/coreutils/manual/html_node/printf-invocation.html#printf-invocation
Is there a way to tell fish-shell
that I want it to use the GNU coreutils
printf
function instead of their customized printf
function?
[Edit 1]: I hadn't realized that MacOS has it's own BSD-derived builtins that it uses, not the GNU coreutils builtins. Still am able to use the q
option in zsh
, but not in fish
when running the following commands:
# in zsh
❯ printf '%q\n' 'test'
test
# fish, run in a zsh shell
❯ builtin printf '%q\n' 'test'
%q: invalid conversion specification
❯ command printf '%q\n' 'test'
printf: illegal format character q
When you run unqualified printf
in fish, bash or zsh, it will run the given shell's builtin version of printf.
There is an executable called printf
on your system, probably in /usr/bin/printf or similar.
To run that one, you can use command printf
in fish or e.g. env printf
(which would also work in bash).
However, since you are on macOS it is not a GNU coreutils version, but macOS' own BSD-derived one.
And since %q
is a GNU-extension, it won't have it, and so running it won't actually help you.
You can run e.g. bash's builtin printf by running bash:
bash -c 'printf "%q\n" "$@"' printf 'echo $(hahaha)'
(that second "printf" tells bash to call that process "printf" - it uses it as the argv0, $0
)
Fish's printf does not have %q
, and if it did it would perform escaping for fish, not bash/zsh/sh - the quoting rules are different. It does have string escape
instead.