2

私はbashでコードを書くことに慣れていませんが、自分で教えています。プロセスリストから情報を照会するスクリプトを作成しようとしています。私はそれをしました、しかし私はそれをさらに進めてそれをそうさせたいです:

  1. OSが存在する場合、スクリプトは1セットのコマンドで実行されます。
  2. B OSが存在する場合、スクリプトは異なるコマンドセットで実行されます。

これが私がこれまでに持っているものです。Centosディストリビューションでは動作しますが、Ubuntuでは動作しません。どんな助けでも大歓迎です。

#!/bin/bash

pid=$(ps -eo pmem,pid | sort -nr -k 1 | cut -d " " -f 2 | head -1)
howmany=$(lsof -l -n -p $pid | wc -l)
nameofprocess=$(ps -eo pmem,fname | sort -nr -k 1 | cut -d " " -f 2 | head -1)
percent=$(ps -eo pmem,pid,fname | sort -k 1 -nr | head -1 | cut -d " " -f 1)

lsof -l -n -p $pid > ~/`date "+%Y-%m-%d-%H%M"`.process.log 2>&1

echo " "
echo "$nameofprocess has $howmany files open, and is using $percent"%" of memory."
echo "-----------------------------------"
echo "A log has been created in your home directory"
echo "-----------------------------------"
echo " "
echo ""$USER", do you want to terminate? (y/n)"
read yn
case $yn in

        [yY] | [yY][Ee][Ss] )
                kill -15 $pid
                ;;

        [nN] | [n|N][O|o] )
                echo "Not killing. Powering down."
                echo "......."
                sleep 2
                ;;
        *) echo "Does not compute"
                ;;
esac
4

2 に答える 2

0

これは、たとえば(更新)によって実現できます。

#!/bin/bash

# place distribution independent code here
# dist=$(lsb_release -is)

if [[ -f /etc/redheat-release ]];
then # this is a RedHead based distribution like centos, fedora, ...
    dist="redhead"
elif [[ -f /etc/issue.net ]];
then
    # dist=$(cat /etc/issue.net | cut -d' ' -f1) # debian, ubuntu, ...
    dist="ubuntu"
else
    dist="unknown"
fi

if [[ $dist == "ubuntu" ]];
then
    # use your ubuntu command set
elif [[ $dist == "redhead" ]];
then
    # use your centos command set
else
    # do some magic here
fi

# place distribution independent code here
于 2012-12-08T02:23:19.987 に答える
0

これが私のバージョンのスクリプトです。UbuntuとDebianで動作します。いくつかの点でおそらくあなたよりも安全です(あなたの厄介なために、プロセスがメモリの10%以上を占めるとき、私は明らかにあなたにバグがありましたcut)。さらに、あなたpsは「アトミック」ではないので、の異なる呼び出しの間で状況が変わる可能性がありpsます。

#!/bin/bash

read percent pid nameofprocess < <(ps -eo pmem,pid,fname --sort=-pmem h)
mapfile -t openfiles < <(lsof -l -n -p $pid)
howmany=${#openfiles[@]}

printf '%s\n' "${openfiles[@]}" > ~/$(date "+%Y-%m-%d-%H%M.process.log")

cat <<EOF

$nameofprocess has $howmany files open, and is using $percent% of memory.
-----------------------------------
A log has been created in your home directory
-----------------------------------

EOF

read -p "$USER, do you want to terminate? (y/n) "

case $REPLY in
    [yY] | [yY][Ee][Ss] )
            kill -15 $pid
            ;;

    [nN] | [n|N][O|o] )
            echo "Not killing. Powering down."
            echo "......."
            sleep 2
            ;;
    *) echo "Does not compute"
            ;;
esac

まず、のバージョンにフラグとオプションがあることを確認ps--sortますh

  • --sort=-pmemps減少するwrtをソートするように指示しますpmem
  • hpsヘッダーを表示しないように指示します

readこれはすべて、スペースで区切られたフィールド、ここではフィールド、、を読み取り、pmemこれらpidfname値を対応する変数percent、、pidに配置するbashビルトインに与えられますnameofprocess

このmapfileコマンドは、標準入力(ここではlsofコマンドの出力)を読み取り、各行を配列フィールドに配置します。この配列のサイズは、行によって計算されますhowmany=${#openfiles[@]}lsof配列に格納されているのの出力openfilesは、対応するファイルに出力されます。

echo次に、多くのsの代わりに、を使用しcat <<EOF、次に(prompt)オプションreadでisを使用します。-p

これが本当にあなたの質問に答えるかどうかはわかりませんが、少なくとも、無駄なコマンド呼び出しが少なく、よく書かれたbashスクリプトがあります(caseステートメントまで、16プロセスを呼び出しましたが、私は4プロセスしか呼び出しませんでした)。さらに、最初のps呼び出しの後、私のスクリプトではなく、スクリプトで状況が変わる可能性があります(発生する可能性は非常に低いですが)。

lsofの出力を配列に入れずに、追加のwcコマンドを使用する次の方法もお勧めします。

#!/bin/bash

read percent pid nameofprocess < <(ps -eo pmem,pid,fname --sort=-pmem h)
logfilename="~/$(date "+%Y-%m-%d-%H%M.process.log")
lsof -l -n -p $pid > "$logfilename"
howmany=$(wc -l < "$logfilename")

cat <<EOF

$nameofprocess has $howmany files open, and is using $percent% of memory.
-----------------------------------
A log has been created in your home directory ($logfilename)
-----------------------------------

EOF

read -p "$USER, do you want to terminate? (y/n) "

case $REPLY in
    [yY] | [yY][Ee][Ss] )
            kill -15 $pid
            ;;

    [nN] | [n|N][O|o] )
            echo "Not killing. Powering down."
            echo "......."
            sleep 2
            ;;
    *) echo "Does not compute"
            ;;
esac
于 2012-12-08T13:08:06.287 に答える