gjoost@westc.UUCP (Gertjan van Oosten) (09/19/89)
The problem concerns csh-aliases (aliasi ??? - David Addison in 'Moonlighting'). (There really should be a newsgroup for this -- comp.csh.questions?? Let's start a vote!!) The basic problem is as follows: I want an alias to kill all processes called 'roy'. Outline: % alias killroy 'kill `ps ax | grep -w roy | grep -v grep | awk '{print $1}'`' The problem comes down to having single quotes within single quotes. The single quotes around the 'awk' argument can't be double quotes, because they would lead to the evaluation of '$1'. Escaping the '$' is no use within double quotes. Not being able to figure out how (and if) this 'quoting problem' can be dealt with, the following solution was found (whitespace added for clarity): % alias killroy 'set var=\$1 ; kill `ps ax | grep -w roy | grep -v grep | awk "{print $var}"` ; unset var' This works, but has its drawbacks, one of them being that 'var' may be set before executing the command; it will be unset afterwards. This can be solved by introducing a subshell: % alias killroy '(set var=\$1 ; kill `ps ax | grep -w roy | grep -v grep | awk "{print $var}"`)' So far, so good. Now comes the real problem: I want to kill all processes called 'roy' on machine 'host'. Outline ('rsh' is 'remote shell', not 'restricted shell' (who uses restricted shells, anyway?)): % alias killroy 'rsh host kill `ps ax | grep -w roy | grep -v grep | awk '{print $1}'`' The easy way out is to add another alias: % alias killhostroy 'rsh host killroy' This is based on '~/.cshrc' being interpreted by 'rsh' before executing the command; thus the 'killroy'-alias should be executed in '~/.cshrc'. Another solution would be: % alias killroy 'rsh host set var=\$1 ";" kill `ps ax | grep -w roy | grep -v grep | awk "{print $var}"`' if `ps ax | ...` were executed on machine 'host'. However, this is not the case: it is executed locally. Aaargh. (Not Camargue...:-)) Does anyone out there have a more elegant (jus 'telegant - M.M.) solution? Could somebody please enlighten me? +----------------------------------------------------------------------+ | Gertjan van Oosten mcvax!westc!gjoost | | West Consulting bv | | Phoenixstraat 49 P.O. Box 3318 Tel: +31-15-123190 | | 2611 AL Delft 2601 DH Delft Fax: +31-15-147889 | | The Netherlands | +----------------------------------------------------------------------+ No Points Name Hp [max] 1 6141 HC-V was killed on level 6 by a hill orc. - [66]
maart@cs.vu.nl (Maarten Litmaath) (09/20/89)
gjoost@westc.UUCP (Gertjan van Oosten) writes:
\...
\% alias killroy 'kill `ps ax | grep -w roy | grep -v grep | awk '{print $1}'`'
The `string' is broken into words as follows:
'kill `ps ax | grep -w roy | grep -v grep | awk '{print
$1}'`'
i.e. parts of the string aren't quoted.
Solution:
'kill ... awk '\''{print $1}'\''`'
^ ^ ^ ^ ^ ^
+-------------+ +----------+ +-+
\...
\% alias killroy 'rsh host kill `ps ax | grep -w roy | grep -v grep |
\ awk '{print $1}'`'
This would become:
alias killroy \
'rsh host kill '\''`ps ... awk '\'\\\'\''{print $1}'\'\\\'\''`'\'
Er, say that again?
Of course this isn't the optimal solution, regarding the number of quotes and
backslashes; it is, however, a GENERAL solution.
The following trick might be helpful:
set q = \'
set b = \\
set q1 = $b$q
set b1 = $b$b
set q2 = $b1$q1
# etc.
alias killroy \
'rsh host kill '$q'`ps ... awk '$q$q1$q'{print $1}'$q$q1$q'`'$q
^ ^ ^ ^ ^ ^
+---------------+ +-------------+ +----+
i.e. $q is a real quote, $q1 will be a real quote one interpretation level
deeper and so on.
--
creat(2) shouldn't have been create(2): |Maarten Litmaath @ VU Amsterdam:
it shouldn't have existed at all. |maart@cs.vu.nl, mcvax!botter!maart
rostamia@umbc5.umbc.edu (Rouben Rostamian) (09/20/89)
In article <498@westc.UUCP> gjoost@westc.UUCP (Gertjan van Oosten) writes: >The basic problem is as follows: I want an alias to kill all processes >called 'roy'. > >% alias killroy 'kill `ps ax | grep -w roy | grep -v grep | awk '{print $1}'`' > >The problem comes down to having single quotes within single quotes. The >single quotes around the 'awk' argument can't be double quotes, because they >would lead to the evaluation of '$1'. Escaping the '$' is no use within >double quotes. ...The rest of the article omitted. General idea first: Suppose A, B, C, are fragments of shell expressions, and suppose that you wish to enclose the expression - A 'B' C - in a pair of single quotes. [Note: I use hyphens to delineate the expressions; they are NOT parts of the the expressions.] The obvious solution - 'A 'B' C' - will not do, because in effect it creates the quoted strings - 'A ' - and - ' C' -, and squeezes an unquoted - B - in between. This is important, so make sure you see this before reading on! Now that you see this, the rest is easy: What you want is - 'A '\''B'\'' C' - which is parsed as 'A ' + \' + 'B' + \' + ' C'. Get it? Now back to your problem. Applying the general idea above, you can see that the statement: alias killroy \ 'kill '\`'ps ax | grep -w roy | grep -v grep | awk ' \''{print $1}'\'\` does the trick. In fact, the pair of quotes surrounding "kill" are not necessary and may be dropped. An alternative solution, somewhat uglier, is to drop all unnecessary single quotes and to "escape" all special characters in sight: alias killroy \ kill \` ps ax \| grep -w roy \| grep -v grep \| awk \'\{print \$1\}\'\` I hope that this helps. Rouben Rostamian Phone: 301 455-2458 Department of Mathematics e-mail: University of Maryland Baltimore Counnty Rostamian@umbc.bitnet Baltimore, MD 21228 rostamia@umbc3.umbc.edu
CCDN@levels.sait.edu.au (DAVID NEWALL) (09/21/89)
In article <498@westc.UUCP>, gjoost@westc.UUCP (Gertjan van Oosten) writes: > The basic problem is as follows: I want an alias to kill all processes > called 'roy'. > > % alias killroy 'kill `ps ax | grep -w roy | grep -v grep | awk '{print $1}'`' > > The problem comes down to having single quotes within single quotes. What's wrong with cut? Use cut before you go diving for awk. % alias killroy 'kill `ps ax | grep -w roy | grep -v grep | cut -c1-5`' David Newall Phone: +61 8 343 3160 Unix Systems Programmer Fax: +61 8 349 6939 Academic Computing Service E-mail: ccdn@levels.sait.oz.au SA Institute of Technology Post: The Levels, South Australia, 5095
guy@auspex.auspex.com (Guy Harris) (09/24/89)
>What's wrong with cut?
It's not present on all flavors of UNIX, although I think
publicly-available reimplementations do exist.