我该如何替换这个shell脚本?

时间:2013-11-02 05:02:54

标签: perl bash shell awk zsh

我有以下Z shell脚本来启动一个程序实例,如果一个程序尚未主动运行,即使有一个僵尸实例,或者恢复已停止的实例。我觉得必须有一个更好的方法来使用,也许使用perl。 shell脚本看起来太尴尬了 - 至少应该可以使用其他语言进行文本操作,比如perl或awk。

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
"$@" >/dev/null 2>&1 &!
unsetopt nobgnice
}

1 个答案:

答案 0 :(得分:2)

我看不出你应该用awk / perl / ...替换什么,但这个脚本似乎不起作用:

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

      由于pgrep支持ps,因此不需要
    1. -C(这假定程序名称不包含空格或逗号)。由于有办法删除标题,因此不需要sed
    2. zsh对于那些需要按行拆分字符串的人有${(f)}${(s. .)}用于按空格分割。
    3. 最后(cmd)列未在任何地方使用。
    4. mystatus不需要默认值,因为它不会在循环之外的任何地方使用。
    5. 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
          "$@" >/dev/null 2>&1 &!
          # With emulate -L unsetting option is not needed
      }