2013-11-02 4 views
0

У меня есть следующий сценарий оболочки Z для запуска экземпляра программы, если он еще не активно работает, даже если есть экземпляр зомби, или для возобновления остановленного экземпляра. Я чувствую, что должен быть лучший способ сделать это, используя, возможно, Perl. Сценарий оболочки кажется слишком неудобным - по крайней мере, должно быть возможным манипулирование текстом с другого языка, например 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 
"[email protected]" >/dev/null 2>&1 &! 
unsetopt nobgnice 
} 
+1

Вероятно, это лучше не делать каких-либо манипуляций с текстом на всех, но использовать модуль CPAN 'Proc :: ProcessTable'. –

+1

Покажите пример ввода и ожидаемый результат для части, которую вы хотите заменить (то есть для вашего желаемого скрипта awk). –

ответ

2

Я не понимаю, что вы должны заменить AWK/Perl/..., но этот сценарий кажется не работает:

  1. Две линии с МФС производят 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 
} 
Смежные вопросы