It is currently Fri, 15 Oct 2021 21:43:53 GMT

Author Message
 tcsh: define function-like alias

A method describing how is discussed in ORA's "Unix Power Tools." (Hint:
embed the if...then in an "eval" statement.)

[From ""]

# An example of putting if-then-else in an alias.
# # (This alias compiles a C program and makes the executable unreadable.)
# alias C 'eval "if (\!* =~ *.c) then \\
#       echo "C quitting: no .c on end of \!* please." \\
# else \\
#       if (-e \!*) mv \!* \!*.old \\
#       echo \!*.c SENT TO cc \\
#       cc -s \!*.c -o \!* \\
#       if (-e \!*) chmod 311 \!* \\
# endif"'

I remember this file: incorrect, incomplete, ill-advised.

A more general method is to set up aliases to "source" scripts
having the "function body." The usual csh history tomfoolery may be
manipulated to pass command line parameters. Many years ago I went
around and around via email perfecting for another query a robust
method of simulating command line parameters in "source"d files in
t/csh, but it is lost and I cannot recall the details; presumably
you will follow the same mental processes that I did to eventually
to come to the same successful conclusion.

Okay, now the obligatory link:


... and, if you are still interested in t/csh scripting, a document which
may be of technical value to you is:


 Fri, 09 May 2003 03:00:00 GMT   
 tcsh: define function-like alias
On 2000-11-20 said:
   >it is possible to write an alias for the echo command but i am
   >not able to write an alias for the if/then/else command. i can
   >use !* to use an argument inside an alias definition so it is
   >no problem to transfer the argument. but if i understand the
   >documentation of the tcsh correctly it is not allowed to write the
   >if/then/else command in one line. but i can't set an alias to
   >a command covering more than one line.
Can you use && and || in an alias?

Net-Tamer V 1.08X - Test Drive

 Fri, 09 May 2003 03:00:00 GMT   
 tcsh: define function-like alias


Barry Margolin,
Genuity, Burlington, MA
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

 Sat, 10 May 2003 09:26:18 GMT   
 tcsh: define function-like alias

Now that mention it is is either a typographic error or a scripting error
on the part of the ORA authors. T/csh cannot have embedded dquotes (all
such "bournisms" are not so logically implemented...)

Glad it worked out for you; as for myself I would be as pleased to be
able to speak German as well as you speak English. Three years of German
in high school and I am still reticent to practise it.


 Sun, 11 May 2003 09:31:36 GMT   
 tcsh: define function-like alias

This does the trick:

set verbose echo
alias foo 'eval "echo ''"'"'"'"'"'"'"''hello world''"'"'"'"'"'"'"''"'
unset verbose echo

Klaus "\"r" Frank

 Mon, 12 May 2003 03:00:00 GMT   
 tcsh: define function-like alias

Here's the second example that was missing from in my reply:

alias foo 'eval "if ($a == $a) then \\
echo ''"'"'"'"'"'"'"''*bar''"'"'"'"'"'"'"'' \\

or shorter

alias foo 'eval "if ($a == $a) then \\
echo "'"'"'"'"'"'"*bar"'"'"'"'"'"'" \\

The general pattern is to undo the quoting, insert "'"'"'"'" for a double
quote, and continue the quoting again. If there were another level of
eval, you would need a 27-character construct for the innermost double quote.

It should be possible to support the transformation from simple commands to
nested commands with appropriate sed commands and to apply them repeatedly.
Any volunteers?

 Mon, 12 May 2003 03:00:00 GMT   
 tcsh: define function-like alias

   alias foo 'eval "if ($a == $a) then \\
   echo ''"'"'"'"'"'"'"''*bar''"'"'"'"'"'"'"'' \\

I checked it again in csh and tcsh; it works. Try to copy/paste with the mouse.

Again, the best way to see the quotes at the different stages of interpretation
is to use the `echo' and `verbose' variables of the csh when defining the alias
and when using the alias.

We want to end up with
        echo "*bar"
. So the first round of eval should get the one argument
        "echo "'"'"*bar"'"'""
because this will yield the concatenation of \e\c\h\o\ , \", \*\b\a\r, and \".
Hence, the eval command that the alias foo should contain should be
        eval "echo "'"'"*bar"'"'""
. Note that I have substituted \'\"\' for any \". (I'm leaving out the if line,
the endif line and the escaped newlines here.) Now, the alias command will use
single quotes to quote the eval command. Because the eval command does contain
four single quotes, they must be quoted using outside the single quoted content
using paired double quotes. That is, a string
would be quoted as
        alias that 'xxx'"'"'yyy'"'"'zzz'
. Note that I have substituted \"\'\" for any \'. Hence, our eval command will
fit into the alias command as
        alias foo 'eval "echo "'"'"'"'"'"'"*bar"'"'"'"'"'"'""'
because this will yield the concatenation of \e\v\a\l\ \"\e\c\h\o\ \", \',
\", \', \"\*\b\a\r\", \', \", \', and \"\".

(The first version of my alias which you quoted was inconsistent as I didn't
include the second double quote in the single quote quotation.)

The obvious summary is: don't do that manually, it's error-prone. But it
should be possible to automate the process sketched above by sed scripts
or, say, $YOUR_FAVORITE_EDITOR's macros. It might be possible to write a
shell script that reads a script and outputs a transformed script that
uses the input inside eval or alias commands, depending on command-line
parameters to the transformator script. Maybe it's even possible to use
an alias instead of a script, so one could write

make_alias foo <<EOF
echo -n starting command.....
if ( { command } ) then
  echo ok
  echo fail

to make the appropriate alias out of the here-doc-quoted lines with
correct quoting of quotes and newlines. This would involve advanced
use of csh eval and possibly csh workarounds. Again, any volunteers?

set eval '"$@"'; "$@"
echo Done.

 Tue, 13 May 2003 03:00:00 GMT   
 tcsh: define function-like alias

I played around with csh and ended up with a little shar file
which contains a similar alias. I don't know its limitations yet.
(Yes, writing and sourcing a file in /tmp is a security hole.)

The new csh `keywords' :-) are make_alias and "end_alias" (with dquotes!).
Volunteers are invited to define try/"catch"/"endtry" blocks with possible
throw statements... :-)

# This is a shell archive (produced by GNU shar 4.0).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
# Made on 2000-11-26 18:30 MET by <klausf@pfitzner>.
# Source directory was `/home/private/students/klausf'.
# Existing files will *not* be overwritten unless `-c' is specified.
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#    256 -rwxr-xr-x make_alias.sed
#    270 -rw-r--r-- make_alias.csh
#    253 -rwxr-xr-x example.csh
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
  echo 'WARNING: not restoring timestamps'
rm -f 1231235999 $$.touch
# ============= make_alias.sed ==============
if test -f 'make_alias.sed' && test X"$1" != X"-c"; then
  echo 'x - skipping make_alias.sed (File already exists)'
  echo 'x - extracting make_alias.sed (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'make_alias.sed' &&
#!/bin/sed -f
# Make the innermost eval command
1s/^/eval '/;
# Escape excamation marks and newlines
# Finish the alias command
1s/^/alias @alias_name@ '/;
;echo arguments>/dev/null'
# eof
  $shar_touch -am 11261755100 'make_alias.sed' &&
  chmod 0755 'make_alias.sed' ||
  echo 'restore of make_alias.sed failed'
  shar_count="`wc -c < 'make_alias.sed'`"
  test 256 -eq "$shar_count" ||
    echo "make_alias.sed: original size 256, current size $shar_count"
# ============= make_alias.csh ==============
if test -f 'make_alias.csh' && test X"$1" != X"-c"; then
  echo 'x - skipping make_alias.csh (File already exists)'
  echo 'x - extracting make_alias.csh (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'make_alias.csh' &&
#!/bin/echo -source-this-file->
alias make_alias 'echo Defining alias, finish with '"'"'"end_alias"'"'"';\\
X    <<"end_alias" ./make_alias.sed | \\
X    sed -e s/@alias_name@/\!\!:1/ >/tmp/make_alias$$; \\
X    source /tmp/make_alias$$; \\
X    rm /tmp/make_alias$$; \\
  $shar_touch -am 11261756100 'make_alias.csh' &&
  chmod 0644 'make_alias.csh' ||
  echo 'restore of make_alias.csh failed'
  shar_count="`wc -c < 'make_alias.csh'`"
  test 270 -eq "$shar_count" ||
    echo "make_alias.csh: original size 270, current size $shar_count"
# ============= example.csh ==============
if test -f 'example.csh' && test X"$1" != X"-c"; then
  echo 'x - skipping example.csh (File already exists)'
  echo 'x - extracting example.csh (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'example.csh' &&
#! /usr/local/bin/tcsh -f
source ./make_alias.csh
make_alias example >&/dev/null
X    echo 'First argument is "!!:1".'
X    if ($USER == klausf) then
X       echo Hi, Klaus...
X    else
X       echo Hi...
X    endif
X    echo 'Done.'
example some_argument
  $shar_touch -am 11261758100 'example.csh' &&
  chmod 0755 'example.csh' ||
  echo 'restore of example.csh failed'
  shar_count="`wc -c < 'example.csh'`"
  test 253 -eq "$shar_count" ||
    echo "example.csh: original size 253, current size $shar_count"
exit 0

 Thu, 15 May 2003 03:00:00 GMT   
 tcsh: define function-like alias

Using an appropriate meta-alias defined below, you can actually write:

make_alias check_command
        echo -n 'starting command "!!:1" .....'
        if ( { !!:1 } ) then
          echo ok
          echo fail

check_command true
check_command false

Here's the meta-alias in its self-contained version. If you want to hack
on it, ask me for the unquoted unquoted sed scriptfile and the pure alias.

alias make_alias '\\
    <<"end_alias" sed -e '"'"'\\
#\\!/bin/sed -f\\
## Make the eval command\\
# quote quotes\\
# enclose with quotes\\
1s/^/eval '"'"'"'"'"'"'"'"'/;\\
## Make the alias command\\
# escape exclamation marks and newlines\\
# quote quotes\\
# enclose with quotes\\
1s/^/alias @alias_name@ '"'"'"'"'"'"'"'"'/;\\
;echo >/dev/null'"'"'"'"'"'"'"'"'\\
#^^^^^^^^^^^^^^^ (workaround against printing of arguments)\\
'"'"' | \\
    sed -e s/@alias_name@/\!\!:1/ >/tmp/make_alias$$; \\
    source /tmp/make_alias$$; \\
    rm /tmp/make_alias$$; \\

Klaus M. Frank  kla...@Pool.Informatik.RWTH-Aachen.DE

 Sat, 17 May 2003 03:00:00 GMT   
 tcsh: define function-like alias
why not a "normal" shell like ksh or zsh ?

 Sun, 22 Jun 2003 04:13:14 GMT   
   [ 10 post ] 

Similar Threads

1. Define Tcsh Alias with $ Character as Regexp

2. bash: function-defining function?

3. gcc #define #define #define

4. Aliases in X - where defined?

5. How to define aliases on startup

6. format of user-defined alias file

7. help defining csh alias

8. : Alias defining

9. How to define funtions in tcsh?

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software