一個java中呼叫bash指令碼錯誤的診斷

柳飛發表於2011-08-31

背景:

系統是一個分散式架構,分為管理端和agent端。agent接收管理端命令,呼叫bash執行操作,獲取結果後返回管理端。中間以jms為通訊機制。

現象:

管理端呼叫agent有時會顯示jms超時。經查,指令碼可以單獨執行(不管執行結果如何,程式都能正常退出)。而agent中執行process.waitFor()的語句有時卻被block,直至超時。

分析:

由於指令碼看起來無錯,所以主要集中在看java呼叫bash的寫法,參考了多種,大同小異,問題仍然存在。經人指點,呼叫linux的程式操作,主要會和三個資料流打交道。一個是輸入流,對應java中Process物件的OutputStream,一個是輸出流,對應java中Process物件的InputStream,還有一個是錯誤流ErrorStream。我們在ErrorStream中發現了錯誤資訊。原來,指令碼會建立一個服務,並不斷呼叫某個命令檢測是否成功。在單獨執行指令碼時,該命令可以被指令碼直接呼叫,但在java呼叫時,由於執行的使用者不同,該命令無法執行而報錯。此外該檢測一直執行,所以整個被block。

解決:

  • java執行bash的命令中加上-l,以宣告用登入使用者來執行指令碼。
  • 檢測不是無休止,而是隔段時間檢測若干次後退出。

相關文章