tcsh-org / tcsh

This is a read-only mirror of the tcsh code repository.
https://www.tcsh.org/
Other
232 stars 42 forks source link

Add functions support to tcsh #4

Open Navis-Raven opened 6 years ago

Navis-Raven commented 6 years ago

Enhancement proposing: Add functions supporting to tcsh (like in bash, but with parameters)

like here: https://ryanstutorials.net/bash-scripting-tutorial/bash-functions.php

But It would be good if these functions in tcsh integrates parameters.

Krush206 commented 1 year ago

Although the C Shell lacks functions, aliases serve as workaround:

alias function 'if -e $1 then\
echo OK\
else\
echo Not OK\
endif'

Pipes and I/O redirection don't work well with multi-line aliases, except if eval is issued. To avoid eval, have the script in a variable and source it from a FIFO:

setenv qscr 'if -e $1 then\
echo OK\
else\
echo Not OK\
endif'
mkfifo ~/qscr
alias qscr '( echo "$qscr:q" > ~/qscr & ) ; source ~/qscr'

Or have it in an alias alone, with echo:

alias qscr '( echo '\''if -e $1 then\\
echo OK\\
else\\
echo Not OK\\
endif'\'' > ~/qscr & ) ; source ~/qscr'
mkfifo ~/qscr
rwp0 commented 1 year ago

I always think that for functions there's programming languages like Perl, and shells should solely be for interactive purposes (what would be a difference if not). But that's my own opinion which lead me to adopt C shell rather than Bourne shell (sh, dash, ksh, bash etc) as my Unix CLI. IMHO We should not futher complicate the programming (scripting) aspect of shells but rather improve it's interactive capabilities which makes them easier for use for command typing purposes and so.

Krush206 commented 1 year ago

I'm leaving another workaround here. I remember reading somewhere goto and source can be used to simulate functions in C Shell. I thought of applying both, and the result is recursion:

#!/bin/tcsh -f

alias function 'source $0 _FUNC'
if ( "$1" == "_FUNC" ) goto "$2"

set ret = "`function myfunc`"
echo "$ret"
exit

myfunc:
function myfunc2
echo "A function."
exit

myfunc2:
echo "Another function."
exit

Note this only works on Tcsh. The original Csh doesn't allow for passing more than one argument.

Krush206 commented 1 year ago

If you're interested, I'm working on the function built-in for Csh (not Tcsh), @Navis-Raven. It's a wrapper around goto and source. The idea worked on the function built-in is the same of the above workaround; the Shell recurses the script and searches for a goto label. I haven't tested thoroughly, but works as expected.

Navis-Raven commented 1 year ago

thanks. I hope you will enhance it, test it and put it into tcsh in the future. Does this functions accepts parameters ?

Note that the only way I've found to overcome this lack of functions in tsch is to run another tcsh script with parameters.

In the end, in my scripting software, I ended up with a script that launched another script that launched another script that launched another script... and so on... In the end, I had about twenty files in my software. If there had been functions, I could have saved myself a lot of complexity.

Krush206 commented 1 year ago

Yes, it does support passing parameters, @Navis-Raven. Parameters are stored to the argv variable, thus may accessed by subscripting or by the read-only number variables (i.e: $1-9).

Navis-Raven commented 1 year ago

it seems, and I mean it seems to me, that if this function integrates tcsh, bash will definitely be a thing of the past. I may be exaggerating a little, but this is a major breakthrough.

Krush206 commented 2 months ago

https://github.com/tcsh-org/tcsh/pull/77/commits/954cfd6550dccce993d2f99c65729d4466faacba I think functions based on pipes makes a simpler feature, as well as allows for use in interactive sessions, resembling Bourne-compatible Shells better. Unlike the goto-based version, functions may only be called if they were previously declared (i.e: no forward jumps), making a similar behavior to Bourne-compatible Shells.

This new version relies on a tree derived from variables and aliases. Unlike to aliases and variables, the tree is restrictive. Once a function is declared, may not be redeclared or undeclared.

I was afraid this wouldn't work out for some operations, such as loops and gotos, because pipes cannot rewind. Fortunately, I was wrong, and the fact these operations are possible from interactive sessions, from a terminal, makes the assumption just as wrong, though I'm clueless as to how the Shell handles rewinding on unsupported sources.