2013-11-02 24 views
0

我有以下的Z shell脚本来启动一个程序的实例,如果一个程序还没有被主动运行,即使有僵尸实例,或者恢复一个停止的实例。我觉得必须有更好的方式来使用,也许使用perl。 shell脚本看起来太尴尬 - 至少应该可以从另一种语言(如perl或awk)进行文本操作。我该如何替换这个shell脚本?

launchprogram(){ 
if [ $# = 0 ] 
then 
    cat <<\EOF 
launchprogram requires at least one argument. 
Usage: launchprogram <program> <optional arguments> 
EOF 
    return 1 
fi 
mystatus=Z # assume we have a zombie process 
process="$(pgrep "$1" | tr \\n ,)" 
echo "$process" 
process="${process%,}" 
if [ "$process" != '' ] 
then 
     process="$(ps -o 'pid s cmd' -p "$process" | sed '1 d')" 
fi 
oldifs="$IFS" 
IFS="$(printf \nX)" 
IFS="${IFS%X}" 
for i in $process 
do 
    mystatus="${process[2]}" 
    case $mystatus in 
    (T) 
     if ! kill -CONT "${i[1]}" 
     then 
     IFS="$oldifs" 
     return $? 
     fi 
     ;; 
    (Z) 
     ;; 
    (*) 
     IFS="$oldifs" 
     return $? 
     ;; 
    esac 
done 
IFS="$oldifs" 
    setopt nobgnice 
"[email protected]" >/dev/null 2>&1 &! 
unsetopt nobgnice 
} 
+1

也许这是更好地做任何文本操作可言,但使用CPAN模块'PROC :: ProcessTable'。 –

+1

显示要替换的部分的一些示例输入和预期输出(即,用于所需的awk脚本)。 –

回答

2

我看不出有什么,你应该使用awk/perl的/ ...代替,但这个剧本似乎不起作用:

  1. 两行与IFS产生IFS等于n同时预计IFS包含只有换行符。
  2. "$process[2]"不正确,因为它是第二个字符而不是第二列。没有提到它的意思是$i[2]
  3. ${i[1]}相同。
  4. 默认情况下,zsh变量不会自动分割为参数,因此for i in $process将始终迭代一个值:整个$process

因此,我将使用以下考虑重写剧本:

  1. pgrep没有必要的,因为ps支持-C(假定程序名称不包含空格或逗号)。由于有办法删除标题,因此不需要sed
  2. zsh有${(f)}需要按行分割字符串的人。 ${(s. .)}用空格分开。
  3. 最后(cmd)列未在任何地方使用。
  4. mystatus不需要默认值,因为它在循环之外的任何地方都不会使用。
 
launchprogram(){ 
    emulate -L zsh 
    if [ $# = 0 ] 
    then 
     cat 
EOF 
     return 1 
    fi 
    local mystatus 
    local process 
    local i 
    local -a iarr 
    process="$(ps -o 'pid=,s=' -C "$1")" 
    echo "$process" 
    for i in ${(f)process} 
    do 
     iarr=(${(s. .)i}) 
     mystatus="${iarr[2]}" 
     case $mystatus in 
      (T) 
       if ! kill -CONT "${iarr[1]}" 
       then 
        return $? 
       fi 
       ;; 
      (Z) 
       ;; 
      (*) 
       return $? 
       ;; 
     esac 
    done 
    setopt nobgnice 
    "[email protected]" >/dev/null 2>&1 &! 
    # With emulate -L unsetting option is not needed 
}