Shell Script: 找到 subprocess

前陣子寫了一段腳本,用來進行 Java web server 的自我測試:先在 subprocess 中啟動 Jetty server ,然後在後續的後續其他 subprocess 裡,等待 Jetty 啟動完畢,然後取出它一個網頁。取出網頁的動作會讓 Java 專案中所安排的 jdbc:initialize-database 執行。最後完成的腳本如下:

# 正確版
pre-clean-test:
	echo systemProperties.INITIALIZE_DATABASE=true > src/main/resources/META-INF/config/sys.properties
	(mvn jetty:run &); \
		sleep 30s; \
		curl http://localhost:8080/kyeez/
	git checkout -- src/main/resources/META-INF/config/sys.properties

clean-test: pre-clean-test
	kill $(shell ps aux | grep jetty | awk 'NR==1 { print $$2 }')
	mvn test

$ make clean-test 的工作,是讓網站啟動、讓測試資料重新安裝,然後進行單元測試。

本來前後二段都寫在一起,如以下:

# 錯誤版
clean-test:
	echo systemProperties.INITIALIZE_DATABASE=true > src/main/resources/META-INF/config/sys.properties
	(mvn jetty:run &); \
		sleep 30s; \
		curl http://localhost:8080/kyeez/
	git checkout -- src/main/resources/META-INF/config/sys.properties
	kill $(shell ps aux | grep jetty | awk 'NR==1 { print $$2 }')
	mvn test

但發現在倒數第二行 kill process-ID 的時候,都刪到號碼遠比正確的 process-ID 小的某個號碼。

由於目前我所學到 script 知識只有一些零碎的知識,所以我做了一個猜想:我猜, $ make clean-test 之後,是創造出一支 subprocess 的樹,而且 make 腳本的 $(shell …) 功能有個預先執行的特性。所以從以上例子,當它將 $ kill $(shell ps aux …) 一行的參數展開的時候,所抓到的 process-ID 是第一行 $ echo systemProperties… 的號碼。我猜是有個 subprocess 樹擔任了這一段腳本的環境,使它在這個環境中,雖然想要找 jetty 所執行在的 process 卻仍然找錯位置。

因此,我做了簡單的調換,讓 $ kill $(shell ps aux …) 放在 make clean-test 規則的第一行,那麼,它是在另一個腳本環境中,在前面那個腳本環境之外,找到 jetty 所執行在的 process 號碼。

廣告

About 黃耀賢 (Yau-Hsien Huang)

熱愛 Erlang ,並且有相關工作經驗。喜歡程式語言。喜歡邏輯。目前用 Python 工作。
本篇發表於 Programming, Web Programming 並標籤為 。將永久鏈結加入書籤。