Even better -- use this script, paste anything into stdin. It will come back out quotable and pasteable into a shell.
#!/bin/bash
printf '%q' "$(cat)"
echo #!/bin/bash
printf '%q' "$(cat)"
echo function bashquote () {
printf '%q' "$(cat)"
echo
} bashquote() { printf '%q\n' "$(cat)" ; } bashquote() { printf '%q\n' "$(</dev/stdin)"; }
Bash treats the string "/dev/stdin" as magic, so that works even if /dev/stdin doesn't exist. However, bash (unlike ksh) spawns a subshell for $(</dev/stdin), so using cat is actually lighter. (Also, it's not clear to me why $(<&0) doesn't work in bash.) #!/bin/bash
printf '%q' "$(pbpaste)" | pbcopy $ echo "text with spaces" | bash -c 'printf "%q" "$(cat)"'; echo
text\ with\ spaces
For me, this escapes spaces with backslashes; the example in the article escapes them by quoting the whole string. Is this a difference in bash versions, or do these uses differ somehow?(I replaced the single quotes with double so i could pass this to bash -c, but i get the same result if i use your code verbatim as a script)
And the difference is not negligible. With quotes, i can type or paste more into the middle, and the string is still valid. With escapes, i have to be careful to escape the added text. It's significantly more ergonomic to use quoted text.
$'This string \'has single\' "and double" quotes and a $'
vs bash's %q, This\ string\ \'has\ single\'\ \"and\ double\"\ quotes\ and\ a\ \$Here's an example function for quoting from stdin:
function bashquotesingle() {
printf "'";
sed "s/'/'\\\\''/g";
printf "'";
}
Though it does have a bug, at least on macOS, where sed adds a trailing newline. (See https://stackoverflow.com/questions/13325138/why-does-sed-ad...)