Bourne Shell 到 CShell

Bourne Shell 到 CShell

这工作正常:

#!/bin/sh

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

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

但如果我尝试将其切换到 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

我收到一个Illegal variable错误。有任何想法吗?

答案1

关于编写脚本,您应该了解的第一件事csh通常是一个非常糟糕的主意。也就是说,如果您坚持的话,您的脚本的问题是:

  • csh不支持$()命令替换的构造,请改用` `
  • csh不支持该for i ... do ... done语法,请改用foreach i ... end
  • csh不会像"${elapse%:*}".您必须使用其他工具来解决它。
  • 我不知道如何开始[工作csh(但可能是可能的),作为解决方法,请使用if

因此,脚本的工作版本csh将是:

#!/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

但说真的,不要编写脚本csh,它只会给你带来痛苦。特别是因为您真正需要的是:

 ps -o pid=,etime= -p $(pgrep $NAME) | cut -d: -f1 | 
        awk -vval="$ALTER" '$2>val{print $1}'

答案2

${var%$pattern}是 POSIX-shell 构造(由 ksh 引入),在csh.

你可以expr在这里使用:

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

但我首先会

  1. 避免csh
  2. 避免csh
  3. 避免 shell 脚本中的循环。这里,整个事情可以通过使用与大多数 shell 兼容的语法ps进行管道传输来完成。awk

相关内容