2

我不习惯用 bash 编写代码,但我正在自学。我正在尝试创建一个脚本,该脚本将从进程列表中查询信息。我已经做到了,但我想更进一步并做到这一点:

  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

这是我的脚本版本。它适用于 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=-pmem告诉ps排序 wrt 递减pmem
  • h告诉ps不显示任何标题

所有这些都交给了readbash 内置函数,它读取空格分隔的字段,这里是 fields pmem, pid,fname并将这些值放入相应的变量percent, pidandnameofprocess中。

mapfile命令读取标准输入(此处为lsof命令的输出)并将每一行放入一个数组字段中。该数组的大小由 line 计算howmany=${#openfiles[@]}lsof存储在数组中的 的输出openfiles被输出到相应的文件。

echo然后,我们使用 a代替 many cat <<EOF,然后将readis 与-p(prompt) 选项一起使用。

我不知道这是否真的回答了你的问题,但至少,你有一个编写良好的 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 回答
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 回答