Skip to content

Instantly share code, notes, and snippets.

@jamesandariese
Last active May 17, 2016 01:00
Show Gist options
  • Save jamesandariese/58821cd9af3654af82b62e1515c01b4e to your computer and use it in GitHub Desktop.
Save jamesandariese/58821cd9af3654af82b62e1515c01b4e to your computer and use it in GitHub Desktop.
Bash quoting

Bash Escaping

Description

I constantly am using watch with some hideous chain of jq and awk.

Perhaps I could always have a dashboard or always have my logs exactly the right info and never need to poll a system for something interesting about it that was unexpected -- yeah, right.

Maybe if I was infinitely insightful.

Better, maybe if I was part of an entire team of infinitely insightful people.

So yeah, I constantly am using watch with some hideous chain of jq and awk.

This invariably means trying to find what to quote and adding some judicious \" and my person favorite, '"'"'. What a pain!

Here's a function that won't print out anything human readable but it will print out something bash readable.

Usage

You can put this in your .bash_profile or just paste it in when you need it.

Whatever you choose to do, here's how you use it.

Call escape, paste in your command line, hit C-d.

james$ # come up with your sweet pipeline.
james$ curl -s http://localhost:9200/_nodes/stats | jq -r '[.nodes|to_entries[]|.value]|sort_by(.os.load_average[0])|reverse[]|"\(.name)\n    load avg: \(.os.load_average[0])\n    cpu used: \(100 - .os.cpu.idle)"'
james$ # now esape it
james$ escape
< PASTE IN ABOVE LINE AND PRESS CONTROL D >
< *DON'T HIT RETURN UNLESS YOU WANT IT IN YOUR ESCAPED COMMAND LINE WHICH YOU PROBABLY DON'T* >
'c''u''r''l'' ''-''s'' ''h''t''t''p'':''/''/''l''o''c''a''l''h''o''s''t'':''9''2''0''0''/''_''n''o''d''e''s''/''s''t''a''t''s'' ''|'' ''j''q'' ''-''r'' '"'"'[''.''n''o''d''e''s''|''t''o''_''e''n''t''r''i''e''s''['']''|''.''v''a''l''u''e'']''|''s''o''r''t''_''b''y''(''.''o''s''.''l''o''a''d''_''a''v''e''r''a''g''e''[''0'']'')''|''r''e''v''e''r''s''e''['']''|''"''\''(''.''n''a''m''e'')''\''n'' '' '' '' ''l''o''a''d'' ''a''v''g'':'' ''\''(''.''o''s''.''l''o''a''d''_''a''v''e''r''a''g''e''[''0'']'')''\''n'' '' '' '' ''c''p''u'' ''u''s''e''d'':'' ''\''(''1''0''0'' ''-'' ''.''o''s''.''c''p''u''.''i''d''l''e'')''"'"'"
james$ watch 'c''u''r''l'' ''-''s'' ''h''t''t''p'':''/''/''l''o''c''a''l''h''o''s''t'':''9''2''0''0''/''_''n''o''d''e''s''/''s''t''a''t''s'' ''|'' ''j''q'' ''-''r'' '"'"'[''.''n''o''d''e''s''|''t''o''_''e''n''t''r''i''e''s''['']''|''.''v''a''l''u''e'']''|''s''o''r''t''_''b''y''(''.''o''s''.''l''o''a''d''_''a''v''e''r''a''g''e''[''0'']'')''|''r''e''v''e''r''s''e''['']''|''"''\''(''.''n''a''m''e'')''\''n'' '' '' '' ''l''o''a''d'' ''a''v''g'':'' ''\''(''.''o''s''.''l''o''a''d''_''a''v''e''r''a''g''e''[''0'']'')''\''n'' '' '' '' ''c''p''u'' ''u''s''e''d'':'' ''\''(''1''0''0'' ''-'' ''.''o''s''.''c''p''u''.''i''d''l''e'')''"'"'"
< VIEW THE AWESOME!!! >

NOTE

if you don't want your command line to end in a newline, hit C-d before hitting enter.

escape() {
while read -d '' -s -n1 -r ;do
case "$REPLY" in
"'") echo -n '"'"'"'"'
;;
`printf "\x04"`) echo;break
;;
*) echo -n "'$REPLY'"
;;
esac
done
}
@jamesandariese
Copy link
Author

I am aware that 'curl blah blah blah | jq '"'"'stuff in here "double quotes too"'"'"'' is much more concise but it's more difficult to make in straight bash so I decided against it. there's also a (deprecated but commonly used) function in Python that does this for you. Again,
that's not bash. I wanted this to work anywhere so I don't have to wonder where I am when I put it in my .bash_profile.

There are better methods for some version of better. This is for a specific version of better that's spelled "works anywhere with bash" which is a pretty large subset of systems out there.

This also works on a DD-WRT (busybox 1.22.1, in my case) if you remove the -d '' but then it won't work with newlines... for the use case, that's fine -- remove all the newlines from your pipelines which probably already has no newlines.

Just FYI :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment