我不习惯用bash编写代码,但我在自学。我正在尝试创建一个从进程列表中查询信息的脚本。我已经做到了,但我想更进一步,做到这一点:
- 如果存在操作系统,脚本将使用一组命令运行
- 如果存在操作系统B,脚本将使用不同的命令集运行
这是我到目前为止所拥有的。它可以在我的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
这是我的脚本版本。它适用于Ubuntu和Debian。在某些方面,它可能比你的更安全(由于你笨拙的cut
,当一个进程占用超过10%的内存时,我显然在你的程序中遇到了一个错误)。此外,您的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 '%sn' "${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
对递减的pmem
进行排序h
告诉ps
不显示任何标题
所有这些都提供给read
bash内置,它读取空间分隔的字段,这里是字段pmem
、pid
、fname
,并将这些值放入相应的变量percent
、pid
和nameofprocess
中。
mapfile
命令读取标准输入(此处为lsof
命令的输出),并将每一行放入数组字段中。该阵列的大小是通过线CCD_ 21来计算的。存储在阵列openfiles
中的lsof
的输出被输出到相应的文件。
然后,我们使用cat <<EOF
,而不是许多echo
,然后将read
与-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
例如,您可以通过(更新)来实现这一点
#!/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