一個“指令碼執行夯死”問題的分析
問題現象:
使用一個指令碼命令分發執行的指令碼,在執行時出現夯死,無法繼續進行
[root@yj01 cluster]# sh clustercmd.sh "ls -l /tmp"
問題分析
- 於是使用指令碼除錯的方式,執行結果如下:
[root@yj01 cluster]# sh -x clustercmd.sh "ls -l /tmp"
+ R_CMD='ls -l /tmp'
+ G_CURRENT_PATH=
+ G_LIB_SCRIPT=cluster_lib.sh
+ G_REMOTE_SCRIPT=remote.sh
+ G_CONF_FILE=cluster.ini
+ G_CONF_FILE_TMP=cluster.ini.tmp.645182
+ G_RESULT=0
+ G_HOSTS_ARRAY=()
+ G_PASSWDS_ARRAY=()
+ '[' /usr/bin/sh '!=' /bin/bash ']'
+ bash clustercmd.sh 'ls -l /tmp'
結果顯示在執行bash clustercmd.sh 'ls -l /tmp'時,長時間夯死,不再繼續進行。
-
繼續使用strace命令檢視指令碼執行情況:
[root@yj01 cluster]# strace sh clustercmd.sh "ls -l /tmp" execve("/usr/bin/sh", ["sh", "clustercmd.sh", "ls -l /tmp"], [/* 32 vars */]) = 0 brk(0) = 0xa17000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0c603f0000 ...... rt_sigaction(SIGINT, {0x43e5e0, [], SA_RESTORER, 0x7f0c5fa16670}, {SIG_DFL, [], SA_RESTORER, 0x7f0c5fa16670}, 8) = 0 // 在執行到此處時,較長時間夯住,後續丟擲Can't allocate memory異常 ****wait4(-1, clustercmd.sh: fork: Cannot allocate memory*****
此處表示,新fork出一個程式進行命令操作,在等待的過程中,丟擲“Can't allocate memory”異常
-
檢視OS記憶體情況以及最大程式數
// OS的記憶體是充足的 [root@yj01 cluster]# free -g total used free shared buff/cache available Mem: 31 9 17 0 4 21 Swap: 3 0 3 // OS的最大程式數是充足的 [root@yj01 cluster]# sysctl kernel.pid_max kernel.pid_max = 798720 [root@yj01 cluster]# ps -eLf | wc -l 711 [root@yj01 cluster]#
從OS資訊來看,記憶體充足,程式數遠遠小於最大的限制. 因此懷疑在夯住的時間內,產生大量程式,os記憶體被大量佔用,最後出現了上述中的“Cannot allocate memory”
- 再次執行 sh -x clustercmd.sh "ls -l /tmp" 同時檢視OS的記憶體使用以及啟動程式數
// os可用記憶體記憶體大量減少
[root@yj01 ~]# free -g
total used free shared buff/cache available
Mem: 31 9 17 0 4 21
Swap: 3 0 3
[root@yj01 ~]# free -g
total used free shared buff/cache available
Mem: 31 10 16 0 4 20
Swap: 3 0 3
[root@yj01 ~]# free -g
total used free shared buff/cache available
Mem: 31 12 14 0 4 18
Swap: 3 0 3
//程式被大量建立
[root@yj01 ~]# ps -eLf | wc -l
9984
[root@yj01 ~]# ps -eLf | wc -l
10452
[root@yj01 ~]# ps -eLf | wc -l
10981
[root@yj01 ~]# ps -eLf | wc -l
11463
於是懷疑指令碼bug引發啟動大量的程式將OS資源耗完,最後程式執行失敗退出。
- 指令碼分析
檢視指令碼可以看出指令碼中強制使用bash來解析執行,但是在執行bash時可能使用到的不是/bin/bash從而導致程式進入死迴圈。
#!/bin/bash
....
if [ "$BASH" != "/bin/bash" ]; then
bash $0 "$@"
exit $?
fi
檢視環境發現如下:
執行which bash 發現使用的是/usr/bin/bash
[root@yj01 cluster]# which bash
/usr/bin/bash
//檢視環境變數發現 /usr/bin在/bin前面
[root@yj01 cluster]# echo $PATH
/usr/local/openssh-7.4p1/sbin:/usr/local/openssh-7.4p1/bin:/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/openssh-7.4p1/bin:/root/bin:/root/bin
[root@yj01 cluster]#
可以看出在執行bash $0 "$@"
時,使用的是/usr/bin/bash 因此程式進入死迴圈
解決方案
修改if判斷條件if [ ${BASH:0-4} != "bash" ]; 只要執行的是bash命令,即可通過
相關文章
- 執行 shell 指令碼 \r 問題解決指令碼
- [20220414]toad呼叫執行指令碼問題.txt指令碼
- Slave SQL執行緒與PXB FTWRL死鎖問題分析SQL執行緒
- PHP 避免同時執行一個指令碼PHP指令碼
- [20221126]tpt pr.sql指令碼執行問題.txtSQL指令碼
- Linux 作業系統指令碼格式問題導致指令碼無法執行Linux作業系統指令碼
- 從一個死鎖問題分析最佳化器特性
- shell指令碼放到crontab裡就執行不成功的問題指令碼
- 關於程式碼如何執行的五個問題
- MySQL 死鎖問題分析MySql
- 深入分析 Redis Lua 指令碼執行原理Redis指令碼
- 請教個問題執行 httprunner 遇到的問題HTTP
- Python | 多執行緒死鎖問題的巧妙解決方法Python執行緒
- 今天寫了一個統計執行sql次數的指令碼SQL指令碼
- 多執行緒引起的效能問題分析執行緒
- MySQL:一個死鎖分析 (未分析出來的死鎖)MySql
- 執行shell指令碼指令碼
- ORACLE問題處理十個指令碼Oracle指令碼
- 比特幣原始碼分析:多執行緒檢查指令碼比特幣原始碼執行緒指令碼
- 分享一個shell指令碼的坑:grep匹配+wc取值 在指令碼執行後的結果與手動執行結果不一致指令碼
- 如何在Windows上使用Git建立一個可執行指令碼?WindowsGit指令碼
- PHP 使用檔案鎖 避免同時執行一個指令碼PHP指令碼
- 執行python指令碼後臺執行Python指令碼
- SpringMVC中出現的執行緒安全問題分析SpringMVC執行緒
- appium ios java 指令碼如何用指令執行,例如 adb 那種方式執行指令碼APPiOSJava指令碼
- 線上定時指令碼執行慢,分析過程指令碼
- mybatis執行sql指令碼MyBatisSQL指令碼
- Selenium執行JavaScript指令碼JavaScript指令碼
- 一個執行緒,從“生”到“死”經歷的過程執行緒
- 一個RESOURCE MANAGER引起的問題分析
- 一個CRM OData的效能問題分析
- HashMap多執行緒併發問題分析HashMap執行緒
- 一個不常遇到的HbuilderX自動化測試執行問題UI
- 解決SqlServer執行指令碼,檔案過大,記憶體溢位問題SQLServer指令碼記憶體溢位
- MySQL鎖等待與死鎖問題分析MySql
- 死磕 java執行緒系列之自己動手寫一個執行緒池Java執行緒
- 我寫了一個指令碼,可在“任意”伺服器上執行命令!指令碼伺服器
- 死磕以太坊原始碼分析之EVM指令集原始碼