Ksh

AIX - 在無法分叉時使用 ksh 內置函式來釋放記憶體

  • June 30, 2020

上下文:具有非常低記憶體的 AIX lpar(不可能進行分叉,因此只有 shell 的內置函式(cd、echo、kill)可以工作)。我可以有一個 (hmc) 控制台,但我需要一種更好的方法來開始在 AIX 中釋放記憶體,當記憶體太低甚至無法執行“ps -ef”時。(我有辦法,但它是一種隨機殺死現有 pid 的方法。我需要更多關於我可以殺死的 PID 的資訊,所以我可以選擇一個不重要的 PID)

我想知道 :

  • 我怎麼能看到只使用 ksh’ 內置的文件的內容
  • 和最終目標:我可以查看哪些文件的內容,僅使用內置函式來選擇要殺死的 pid,這樣我只殺死“普通”程序,(當我殺死足夠多的 PID 時,我將能夠“ps - ef" “netstat -rn” 等,並且 “ps” 仍應顯示“重要”程序)

我已經知道的:

  • 我可以登錄控制台(ssh user@hmc,vtmenu,選擇有 OutOfMemory 問題的 lpar,以 root 身份登錄,過了一會兒(2-5 分鐘),還有幾個抱怨 ksh 無法在 /etc/ 中派生命令個人資料,我得到一個(ksh)提示。
  • 現在我可以模擬“ls”來查看 /proc/PID# 目錄存在什麼:cd /proc ; echo * 將為我提供仍在執行的 PID 列表。(通常我會看到 0、1(init),它們不會被殺死,還有一大堆其他 PID,幾乎沒有說明它們執行的是什麼程序(ksh?syncd?ls?java?)。
  • 我還可以: kill some pids here釋放足夠的記憶體(kill 是 ksh 中的內置函式(或 bash!),所以不需要分叉來使用它),當我殺死足夠的 PID 時,我就可以做一個ps -ef netstat -rn等等,讓我在我從 lpar 本身重新啟動伺服器之前獲取伺服器的狀態shutdown -rF(這將同步、關閉文件系統等。請注意,從 HMC 重新啟動的替代方法通常是不可能的(因為它可能會嘗試分叉一些命令) , 除非您添加“–immed”,這就像直接關閉電源一樣,是不可取的,因為它會導致文件系統問題,有時會在重新啟動 lpar 時導致非常長的 fsck)。
  • 殺死一些 PID 並執行關機:允許我了解一些正在執行和需要重新啟動的“ps -ef”想法,獲取路由(以防靜態路由不匹配),並“更優雅地”關機,保留文件系統並在啟動時避免冗長的 fsck。)

但我還需要你的幫助:

  • 查看一些文件的內容!(例如:為了能夠在 /var/run/*.pid 中查看某些 pid 文件的 pid,我會這樣做:cd /var/run然後echo *pid獲取 pid 文件的列表,但是只有內置的 ksh (記住:沒有分叉!)我怎樣才能獲得其中一個文件的內容?)。同樣的技巧也可以幫助在 /proc/PID#/ …下獲取一些資訊,也許讓我也可以選擇正確的 PID 來殺死)
  • 使用上述方法“明智地”選擇 PID(或您可以擁有的任何技巧)

精度:如果您的技巧適用於此版本的 ksh 內置函式,則加分:

prompt# strings /usr/bin/ksh | grep '\..*\.' | grep builtin
0@(#)27  1.57.14.5  src/bos/usr/bin/ksh/builtin.c, cmdksh, bos61Z, z2013_29A2 7/5/13 00:10:52

請試試這個:

ksh 中包含的內置函式列表:

$ ksh -c 'builtin' 

這是唯一對回答您的問題有用的內置函式:

echo kill print printf read

因此,似乎“讀取文件”的唯一方法是使用 read。

讓我們定義幾個函式(在 CLI 中複製和粘貼):

function Usage {
   echo "fileread: filename [from line] [to line]"
   exit 1
}

function fileread {
   [ "$#" -lt 1 ] && echo "please supply the name of a file" && Usage
   linestart=${2:-1}
   lineend=${3:-0}
   i=0
   while IFS=$'\n' read line; do
       i=$((i+1))
       [[ "$i" -lt "$linestart" ]] && continue
       [[ "$lineend" != 0 && "$i" -gt "$lineend" ]] && continue
       echo "$i $line"
   done <"$1"
}

然後,呼叫函式(例如):

$ cd /var/run
$ fileread sshd.pid 10 20

引用自:https://unix.stackexchange.com/questions/317735