Csh alias with perl one-liner evaluates when alias is created and not when alias is used
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开发者_如何学C than evaluating when the alias is created?
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.
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.
精彩评论