6

まず、私はこれが初めてです。Windows スクリプトと Apple スクリプトの経験はありますが、bash の経験はあまりありません。私がやろうとしているのは、特定のプロセスの PID と %CPU を取得することです。次に、%CPU を設定された数値と比較し、それが高い場合はプロセスを強制終了します。近づいたような気がしますが、次のエラーが表示されます。

[[: 0.0: 構文エラー: 無効な算術演算子 (エラー トークンは ".0")

私は何を間違っていますか?これまでの私のコードは次のとおりです。

#!/bin/bash
declare -i app_pid
declare -i app_cpu
declare -i cpu_limit
app_name="top"
cpu_limit="50"
app_pid=`ps aux | grep $app_name | grep -v grep | awk {'print $2'}`
app_cpu=`ps aux | grep $app_name | grep -v grep | awk {'print $3'}`
if [[ ! $app_cpu -gt $cpu_limit ]]; then
     echo "crap"
else
     echo "we're good"
fi

明らかに、if/then ステートメントのエコーを置き換えるつもりですが、CPU 負荷が実際に何であるかに関係なく、ステートメントが true であるかのように動作します (-gt を -lt に変更してこれをテストしましたが、それでも「がらくた」がエコーされました)。 "

助けてくれてありがとう。ああ、それが重要な場合、これは OS X 10.7 上にあります。

4

7 に答える 7

11

ps複数の恐ろしいことを避けるために、 の施設を確認することをお勧めします。

私のシステム(psLinuxのprocps、GNU awkから)では、次のようにします。

ps -C "$app-name" -o pid=,pcpu= | 
    awk --assign maxcpu="$cpu_limit" '$2>maxcpu {print "crappy pid",$1}'
于 2013-02-14T23:08:14.960 に答える
9

問題は、bashが小数を処理できないことです。それらに100を掛けて、代わりに単純な整数で作業することができます。

#!/bin/bash
declare -i app_pid
declare -i app_cpu
declare -i cpu_limit
app_name="top"
cpu_limit="5000"
app_pid=`ps aux | grep $app_name | grep -v grep | awk {'print $2'}`
app_cpu=`ps aux | grep $app_name | grep -v grep | awk {'print $3*100'}`
if [[ $app_cpu -gt $cpu_limit ]]; then
     echo "crap"
else
     echo "we're good"
fi

CPUパーセンテージは、アプリケーションの状態の最適ではない測定値であることに注意してください。単一のコアシステムで無限ループを実行している2つのプロセスがある場合、同じ優先度の他のアプリケーションが33%を超えることはありません。

于 2013-02-14T23:00:26.060 に答える
0

top と bc を使用して、これを思いつきました。

exを渡して使用します:./script apache2 50 # max 50%

プログラムの引数に一致する PID が多数ある場合、top がそれらをどのようにリストするかに基づいて、1 つだけが計算されます。それらをすべてキャッチしてパーセンテージなどを平均化することでスクリプトを拡張することもできましたが、これを行う必要があります。

数値を渡すこともでき./script.sh 12345 50ます。これにより、正確な PID の使用が強制されます。

#!/bin/bash

# 1: ['command\ name' or PID number(,s)] 2: MAX_CPU_PERCENT

[[ $# -ne 2 ]] && exit 1
PID_NAMES=$1
# get all PIDS as nn,nn,nn
if [[ ! "$PID_NAMES" =~ ^[0-9,]+$ ]] ; then
    PIDS=$(pgrep -d ',' -x $PID_NAMES)
else
    PIDS=$PID_NAMES
fi
#  echo "$PIDS $MAX_CPU"
MAX_CPU="$2"
MAX_CPU="$(echo "($MAX_CPU+0.5)/1" | bc)"
LOOP=1
while [[ $LOOP -eq 1 ]] ; do
    sleep 0.3s
    # Depending on your 'top' version and OS you might have
    #   to change head and tail line-numbers
    LINE="$(top -b -d 0 -n 1 -p $PIDS | head -n 8 \
        | tail -n 1 | sed -r 's/[ ]+/,/g' | \
        sed -r 's/^\,|\,$//')"
    # If multiple processes in $PIDS, $LINE will only match\
    #   the most active process
    CURR_PID=$(echo "$LINE" | cut -d ',' -f 1)
    # calculate cpu limits
    CURR_CPU_FLOAT=$(echo "$LINE"| cut -d ',' -f 9)
    CURR_CPU=$(echo "($CURR_CPU_FLOAT+0.5)/1" | bc)
    echo "PID $CURR_PID: $CURR_CPU""%"
    if [[ $CURR_CPU -ge $MAX_CPU ]] ; then
        echo "PID $CURR_PID ($PID_NAMES) went over $MAX_CPU""%"
        echo "[[ $CURR_CPU""% -ge $MAX_CPU""% ]]"
        LOOP=0
        break
    fi
done
echo "Stopped"
于 2014-01-27T13:30:01.973 に答える