Tim, the Enchanter

What manner of man are you that can summon up code without C# or Java?

Friday, February 20, 2009

 

How to escape arguments in bash

Today I was trying to write a convenience wrapper script that ran commands remotely on a server (for one of the people we work with). But, for some reason, ssh handles arguments in a completely suprising (and annoyingly inconvenient) manner that completely ignores quotes.

For example:

timcharper@timcharper:~ $ ssh my_server grep "4 5 6" ./
grep: 5: No such file or directory
grep: 6: No such file or directory

Grrr…. this made me feel ANGRY. Because of this, I couldn’t use the “$@” trick to splat all the arguments on the end and just move on with life. But it’s cool, because I’ve got a thick table to bang my head against, combined with an overly-aggressive problem-solving drive that won’t accept no for an answer.

So, I came across an awk trick to escape every character in a string, and another trick to iterate over arguments. Combining the two techniques did the trick, and I can now properly pass command line arguments through an ssh wrapper script. Since it depends on bash and awk, and bash and awk are on EVERY POSIX system out there, it’s a winner.

The working script:

#!/bin/sh
CMD=""

for (( i = 1; i <= $# ; i++ )); do
  eval ARG=\$$i
  CMD="$CMD $(echo "$ARG" | awk '{gsub(".", "\\\\&");print}')"
done

ssh my_server cd /path/to/app \&\& RAILS_ENV=production $CMD

Surprisingly, this is quite bullet broof, and properly escapes strings and preserves arguments like:

./remote.sh grep "hello there" . -R
./remote.sh grep "So I says to the typewriter, \"Hey, I'm in quotes\"" . -R
./remote.sh grep "\"" . -R

I wish somebody had posted a solution like this for me to find, so, here you go. If you came here looking for this solution, I probably saved you an hour of your life, and a lot of stress to boot. You’re welcome.

Have you ever wasted more than an hour on a trivial problem like this? Is there an easier way to do this?


Archives

March 2008   April 2008   May 2008   June 2008   July 2008   August 2008   October 2008   November 2008   February 2009   June 2009   December 2009   January 2010   February 2010   May 2010   June 2010   November 2010  

This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]