··else
····runme="ps cu −U ${USER:-LOGNAME}"
··fi
··eval $runme | \
······awk "/ $1/ { printf \" user %-8.8s pid %-6.6s job %s\n\", \
······\$1,\$2,\$11 }"
··echo "Use −u user or −t tty to narrow down your selection criteria."
elif [$showpid −eq 1]; then
··echo $pid
else
··# Все готово. Изменить приоритет!
··/bin/echo −n "Renicing job \""
··/bin/echo −n $(ps cp $pid | sed 's/ []*/ /g' | tail -1 | cut −d\ −f6-)
··echo "\" ($pid)"
··renice $niceval $pid
fi
exit 0
Часть кода заимствована из сценария № 47 в главе 6, который аналогично выполняет преобразование имени процесса в его числовой идентификатор, но тот сценарий останавливает задания, а не изменяет их приоритет.
В данной ситуации было бы нежелательно по ошибке изменить приоритет сразу нескольких процессов, соответствующих указанному имени (представьте, например, команду renicename −n 10 "*"), поэтому сценарий завершается с сообщением об ошибке, если обнаруживает несколько совпадений. В противном случае он выполняет указанные изменения, предоставляя программе renice самой сообщить о любых возможных ошибках.
Этот сценарий поддерживает несколько параметров: −n val позволяет указать желаемое значение приоритета. По умолчанию оно задается как niceval=1. Флаг −u user позволяет ограничить совпадения только процессами, принадлежащими определенному пользователю, а флаг −t tty обеспечивает аналогичную фильтрацию по имени терминала. Чтобы только увидеть идентификатор найденного процесса без фактического изменения приоритета приложения, используйте флаг −p. В дополнение к одному или нескольким флагам, сценарий renicename требует указать шаблон поиска, с которым будут сравниваться имена процессов, действующих в системе.
В листинге 10.16 показано, что получается, если обнаруживается совпадение с несколькими процессами.
Листинг 10.16.Запуск сценария renicename с именем процесса, которому соответствует несколько идентификаторов
$ renicename "vi"
renicename: more than one process matches pattern vi:
user taylor pid 6584 job vi
user taylor pid 10949 job vi
Use −u user or −t tty to narrow down your selection criteria.
Мы остановили один из этих процессов и снова запустили ту же команду.
$ renicename "vi"
Renicing job "vi" (6584)
Мы можем убедиться, что сценарий выполнил свою задачу и приоритет процесса vi изменился, если вызвать команду ps с флагом −l и идентификатором процесса, как показано в листинге 10.17.
Листинг 10.17.Подтверждение изменения приоритета процесса
$ ps −l 6584
UID··PID PPID····F CPU PRI NI······ SZ··RSS WCHAN··S··ADDR TTY············ TIME CMD
501 6584 1193 4006·· 0··30 1
2453832 1732··- SN+ 0 ttys000 0:00.01 vi wasting.time
Этот чрезмерно широкий формат вывода команды ps читать очень неудобно, но обратите внимание на поле 7 — NI — в котором для данного процесса указано значение 1
. Проверьте любые другие запущенные процессы, и вы увидите, что они имеют стандартный приоритет 0.
Усовершенствование сценария
Интересным дополнением стал бы другой сценарий, следящий за программами, которые расходуют значительную долю процессорного времени, и автоматически изменяющий их приоритет. Это может пригодиться, например, для уменьшения приоритета некоторых интернет-служб или приложений, обычно потребляющих много вычислительных ресурсов. Сценарий в листинге 10.18 использует renicename для преобразования имени процесса в его идентификатор и затем проверяет текущее значение приоритета этого процесса. Он вызывает renice, если значение аргумента оказывается выше текущего уровня (то есть процесс имеет больший приоритет, чем требуется).
Листинг 10.18.Сценарий watch_and_nice
#!/bin/bash
# watch_and_nice — проверяет указанный процесс по имени и уменьшает
#·· его приоритет до желаемого уровня, если необходимо.
if [$# −ne 2]; then
··echo "Usage: $(basename $0) desirednice jobname" >&2
··exit 1
fi
pid="$(renicename −p "$2")"
if ["$pid" == ""]; then
··echo "No process found for $2"
··exit 1
fi
if [! -z "$(echo $pid | sed 's/[0–9]*//g')"]; then
··echo "Failed to make a unique match in the process table for $2" >&2
··exit 1
fi
currentnice="$(ps −lp $pid | tail -1 | awk '{print $6}')"
if [$1 −gt $currentnice]; then
··echo "Adjusting priority of $2 to $1"
··renice $1 $pid
fi
exit 0
Читать дальше