2012-12-08 109 views
2

我不習慣在bash中編寫代碼,但我自學自己。我試圖創建一個腳本來查詢進程列表中的信息。我已經做了,但我希望把它進一步,使它如此:bash腳本中的條件變量?

  1. 腳本用一組命令運行如果A OS是存在的。
  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 
+0

的就是你在ubuntu下運行這個錯誤? – sge

+1

而不是讓你的腳本以不同的方式處理不同的分佈,以便攜的方式寫它會更有用。如果您可以回答@ Lorunification的問題,我們可能會告訴您需要更改哪些內容。 –

回答

0

這裏是我的腳本的版本達到這一目的的例子。它適用於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 '%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不顯示任何頭

所有這些都給012ashbash內建函數,它讀取空格分隔的字段,這裏的字段pmem,pid,fname並將這些值放入相應的變量percent,pidnameofprocess

mapfile命令讀取標準輸入(這裏是lsof命令的輸出)並將每行放入數組字段中。該數組的大小由行howmany=${#openfiles[@]}計算。存儲在數組openfiles中的lsof的輸出被輸出到相應的文件。

然後,我們使用cat <<EOF而不是許多echo s,然後使用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 
+0

感謝您的回覆。我今天要處理你的建議,並讓你知道它是如何工作的。 – Kryten

+0

現在很好用。非常感謝。我試圖重新發明輪子,但你給我看了一個更簡單的方法。謝謝! – Kryten

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 
+0

我這樣做了: 錯誤: -bash:lsb_release:command not found。 假設這些不是符合lsb的系統。 – Kryten

+0

我想弄清楚如何以另一種通用的方式使用os名稱。貓/ proc /版本和切割不起作用。版本文件位於不同的地方。哼。 – Kryten

+0

快速而骯髒的方法是手動創建一個包含分佈的文件。但我相信有一種方法可以很好地解決這個問題。 – sge