views:

76

answers:

2

I know, I know, I should use a modern shell... Anyway, so here is the alias:

  alias p4client echo `p4 info | perl -ne 's/Client name: (.*)$/print $1/e'` 

I also know there is probably a better way to get the p4 client name. This is just an example. So, can anyone tell me a nice and clean way to get this to evaluate this when I invoke the alias rather than evaluating when the alias is created?

+3  A: 

The alias value needs to be quoted since it contains special characters. Try this:

alias p4client "echo "\`"p4 info | perl -ne 's/Client name: (.*)'\"\$"'/print '\"\$"'1/e'"\`

And holy crap, csh is the world's worst shell. Its quoting rules are terrible. I melted my brain trying to come up with this and now I have no energy left to explain it. Excuse me while I have an aneurysm.

Edit 1: Behold, your precious dollar signs $ have morphed into this monstrosity! '\"\$"'

Edit 2: OK, I am beginning to recover. My strength returns with each moment I spend in my beloved bash's sweet embrace. Begone, csh, you foul beast!

The reason this is so ugly is because the whole thing must be doubly escaped. Once to get the dollar signs passed on to perl, and another time to get them safely past the alias statement. If it helps, the goal is to get the alias to look like this:

% alias
4client echo `p4 info | perl -ne 's/Client name: (.*)'\$'/print '\$'1/e'`

The reason for the '\$' sequences there is that csh has no way to escape dollar signs inside of double quotes. You can't just put a backslash in front. You actually have to temporarily close the quotes, use \$ outside of quotes, and then re-open the quotes.

John Kugelman
+1: That's ghastly enough that I'd create a (one-line, bash) shell script to do the job, just to prevent having to going through the 'meta-syntactical zoo' that is the C shell's quoting mechanism. I hope the aneurysm heals quickly!
Jonathan Leffler
some of your trouble is trying to make the outer quotes double instead of single
ysth
Way to take one for the team. :-) And I bet you've already seen this, but just in case: http://www.faqs.org/faqs/unix-faq/shell/csh-whynot/
Jim Lewis
+2  A: 

The only trick is backslash escaping the single quotes and surrounding everything else with single quotes:

alias p4client 'echo `p4 info | perl -ne '\''s/Client name: (.*)$/print $1/e'\''`'

Though the perl can be simplified:

alias p4client 'echo `p4 info | perl -ne '\''print /Client name: (.*)/'\''`'

and the echo and `` are saying capture the output these commands print and print it; just print the output instead (only having perl include the newline instead of stripping it from the p4 output only to have echo re-add it):

alias p4client 'p4 info | perl -ne '\''print /Client name: (.*)/s'\'

though now there's nothing double-quote-unfriendly left in there, so:

alias p4client "p4 info | perl -ne 'print /Client name: (.*)/s'"

There's nothing different here from how you would do it in bash except not having an = after p4client.

ysth
Wow, beautiful, simple and explained very well! I hope your employer is paying you well because you sir are a rock star. Thanks!
stephenmm