1

This works fine:

#!/bin/sh

ALTER="$1"
NAME="$2"

for pr in $(pgrep $NAME); do
    elapse=$(ps -o etime= -p $pr)
    [ "${elapse%:*}" -gt "$ALTER" ] && echo $pr
done

But if I try to switch it to CShell:

#!/bin/csh

set ALTER = "$1"
set NAME = "$2"

for pr in $(pgrep $NAME); do
    set elapse = $(ps -o etime= -p $pr)
    [ "${elapse%:*}" -gt "$ALTER" ] && echo $pr
done

I get an Illegal variable error. Any ideas?

5
  • 4
    Why do you like to convert something to csh at all? csh is not really useful for scripting.
    – schily
    Commented Oct 7, 2015 at 12:34
  • somebody told me to do it :/
    – JuM
    Commented Oct 7, 2015 at 12:36
  • 3
    @JuM then they really, really hate you. Trying to script in csh is just painful and should be avoided at all costs really.
    – terdon
    Commented Oct 7, 2015 at 12:46
  • Okay thanks a lot for all the replies! :)
    – JuM
    Commented Oct 7, 2015 at 12:48
  • IMO csh should be avoided even as a CLI shell because you've got all the usual csh problems for your one-liners, AND you have to use a different language (e.g. sh or bash or ksh etc) for your scripts. As a CLI shell, there's nothing csh can do that bash, zsh, or a modern ksh can't do.
    – cas
    Commented Oct 7, 2015 at 21:48

2 Answers 2

6

The first thing you should know about scripting in csh is that it is usually a very bad idea. That said, if you insist, the problems with your script are:

  • csh doesn't support the $() construct for command substitution, use ` ` instead.
  • csh doesn't support the for i ... do ... done syntax, use foreach i ... end instead.
  • csh doesn't do funky string manipulation like "${elapse%:*}". You'll have to get around it using some other tool.
  • I don't know how to get [ to work with csh (but it's probably possible), as a workaround, use if instead.

So, a working version of your script in csh would be:

#!/bin/csh
set ALTER = "$1" 
set NAME = "$2" 
foreach pr  (`pgrep "$NAME"`)
    set elapse = `ps -o etime= -p "$pr" | cut -d: -f1` 
    if ( "$elapse" > "$ALTER" ) echo "$pr"
end

Seriously though, don't script in csh, it will only cause you pain. Especially since all you really need is:

 ps -o pid=,etime= -p $(pgrep $NAME) | cut -d: -f1 | 
        awk -vval="$ALTER" '$2>val{print $1}'
7
  • Version: $Id: csh-faq,v 1.7 95/09/28 12:52:17 tchrist Exp Locker: tchrist $ Happy Birthday! Twenty years later and people are still being told to use csh.
    – bishop
    Commented Oct 7, 2015 at 14:14
  • 1
    [ is an external command; I'd be very surprised if it doesn't work.
    – Random832
    Commented Oct 7, 2015 at 15:08
  • @Random832 it's both a builtin and an external one, but yes, good point. /usr/bin/[ 10 > 5 ] && echo y seems to work in csh. [ 10 > 5 ] && echo y doesn't. I don't know the details, I'm happy to remain ignorant of csh :)
    – terdon
    Commented Oct 7, 2015 at 15:10
  • Well, > isn't actually a supported operator in the [ command; you need -gt and you need to be comparing integers. By the way, check for a file named 5 in the directory you tested it in.
    – Random832
    Commented Oct 7, 2015 at 15:13
  • @Random832 d'oh! Yup, that created 5. However, this still fails in csh: [ 5 -gt 4 ] && echo y. Anyway, answer edited to reflect that csh could probably use [ if not for my ignorance. Thanks.
    – terdon
    Commented Oct 7, 2015 at 15:16
3

${var%$pattern} is a POSIX-shell construct (introduced by ksh) not available in csh.

You could use expr here:

expr "$elapse" : '\([0-9]*\)' '>' "$ALTER" > /dev/null && echo $pr

But I would first

  1. avoid csh
  2. avoid csh
  3. avoid loops in shell scripting. Here the whole thing can be done by piping ps to awk in a syntax compatible with most shells.
1
  • You forgot to mention that he should avoid csh :-) Commented Oct 10, 2015 at 8:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .