我不习惯用bash编写代码,但我自学了。我正在尝试创建一个将从进程列表中查询信息的脚本。我已经做到了,但我想进一步做到这一点:
这是我到目前为止所拥有的。它适用于我的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
答案 0 :(得分: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
答案 1 :(得分: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
对pmem
h
告诉ps
不显示任何标题所有这一切都发送到read
bash builtin,它读取空格分隔的字段,在这里显示字段pmem
,pid
,fname
并将这些值放入相应的变量percent
,pid
和nameofprocess
。
mapfile
命令读取标准输入(此处为lsof
命令的输出)并将每行放入数组字段中。该数组的大小由行howmany=${#openfiles[@]}
计算。存储在数组lsof
中的openfiles
输出将输出到相应的文件。
然后,我们使用echo
代替多个cat <<EOF
,然后将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