I work on CSHELL these days. Probably the most unpopular shell today. Anyone would recommend not to use it. Because of the absurdness of its syntax and quoting. For an example: Top 10 reasons to avoid using CShell

My intention was to write a generic wrapper script that I could use to invoke another script that supposedly attempts to update a database and in the unlikely event of failing to do so, the wrapper would wait for a while and retry again. I thought of this approach as we had been facing some database locking issues and some data that was supposed to updated wasn’t getting updated. And this was causing even more problems for us. Since some of our systems rely on this data. By the way, to give you an idea of the locking problem, let me tell you, we have one MySQL database, that is updated by several processes running on 7 different boxes. Now you can understand the number of processes trying to access the database at similar intervals.

  
#!/bin/csh  
  
set argv = \`getopt -s tcsh -o r:f: -- $\*\`  
  
if ($status != 0) then  
    echo "Error"  
    exit 1  
endif  
  
set totalNumberOfRetries = 10  
  
set sleepTime = 30  
  
while (1)  
    switch($1)  
    case -r:  
        set totalNumberOfRetries = "$2"  
        echo "INFO: Number of retries: $totalNumberOfRetries"  
        shift; shift  
        breaksw  
  
    case -f:  
        set sleepTime = "$2"  
        echo "INFO: Retry frequency in seconds: $sleepTime"  
        shift; shift  
        breaksw  
  
    case --:  
        shift  
        break  
        default:  
        echo "Unknown option. Terminating" ; exit 1  
    endsw  
end  
  
echo $#argv  
set check = $argv\[1\]  
echo $check  
shift  
if ( $#totalNumberOfRetries > 0 ) then  
    **eval eval** set retryCount = $totalNumberOfRetries  
    while ( $retryCount >= 0)  
        echo "invoking $check with $argv"  
        eval eval "$check $argv"  
        if ($retryCount != 0) then  
            echo "INFO: $retryCount retries remaining"  
            echo "INFO: Going to wait $sleepTime seconds before next attempt"  
            eval sleep $sleepTime  
        endif  
        @ retryCount --  
    end  
endif  

I’ll do the indentation when I get time.

Did you notice those lines where there are two eval commands? Is it normal to see something like that? For those familiar with CShell it might be normal. I’m just getting familiar. So I felt it quite weird. I have been working on CSHELL for around 6 months. But never came across a requirement where I had to use something this sort. What actually happens in the code above is that, the getopts converts the argument list into single quoted strings separated by white space. now my script name needn’t be the full path of a script. But could also be an alias. I hope you know what an alias is. If not, it is just a short name to call a script. We usually have aliases for tools and we call them in different programs. So here this wrapper would invoke a tool with its arguments. And the tool’s alias would be passed into the program. So suppose the alias is testArgPass to run a script ‘csh /home/users/egk/checkArgPass1.csh’. Then if I type eval ’testArgPass’ $argsList in a shell script, it would eval the testArgPass and expand it to the full ‘csh ….’ and then substitute the list of arguments and execute it.

But getopts makes things a little more complicated. getopts converts the whole thing into something like this

"'testArgPass'"  

which can’t be parsed by one single eval. Because quoting works really weird in CSHELL. You can find a variety of sources talking about the absurd characteristics of Cshell like this one Csh Programming Considered Harmful. So for evaluating the outer quotes you need another eval. And two evals finally succeeds in getting the expanded alias.

I don’t think that was of great help. But then if at all you were searching for eval and command not found cshell or something of that sort, and if my blog turns up in the results, then probably you could save a few hours.