一般問題:如果腳本或調用它的shell(bash)命令調用它爲一個腳本,變量?Shell腳本掛起,但僅在調用變量或strace時纔會掛起
換句話說,怎麼會有這樣的腳本工作,當這樣的調用... /path/to/script arg arg
...失敗並掛起時,這樣的調用... VAR=$(/path/to/script arg arg);
?我有一個腳本,它工作正常(:
我的具體情況(主要編輯注意到,軟件故障引起了很大的初步測試給出不正確的結果後)啓動,停止或重新啓動Java應用程序Apache Solr,adapted from here)。代碼如下,其命令是sbin/service solr [action]
,例如sbin/service solr start
。
當從腳本或直接從控制檯(bash
在我的情況下)調用,如sbin/service solr start
,它工作正常,並迅速完成。但是,如果它被調用到變量中,例如VAR=$(sbin/service solr start);
,它可以工作,但會掛載一個futext/clock_gettime循環(以下跟蹤)。它也掛起,如果它被稱爲不是一個變量,但strace
。
奇怪的是,其他腳本以相同的語法調用,例如,當調用一個變量時,工作得很好。所以顯然有可能會有一些關於腳本的東西,當輸出存儲爲變量時會使其掛起,但如果不是這種情況,則可以很好地運行。
下面是測試什麼叫掛的結果,什麼都不用:
掛起 ---------------------- --------------------------
VAR=$(/sbin/service solr start);
VAR=$(source /sbin/service solr start);
VAR=$(nohup /sbin/service solr start &);
(因此,調用哪個進程並不重要)另外,編輯腳本文件以使用source
啓動服務會導致服務無法工作。
不掛 -------------------------------------
VAR=$(/sbin/service solr start >> /dev/null);
輸出到/dev/null
允許我們要求輸出,而不使其掛起。然而,由於沒有收到實際的輸出,所以沒有多大用處。
/sbin/service solr start
相反的是我首先想到的。這會輸出一個簡單的更新消息,理想情況下,我們會在變量和日誌中捕獲 - 但試圖這樣做會導致它掛起。
VAR=$(/sbin/service httpd restart);
是掛起作品只是在其他service
腳本精細的語法,腳本的輸出傳遞給變量沒有問題。
下面是腳本的完整代碼:(註釋去掉,自然是$ SOLR_DIR路徑是真正的腳本是真實的)
SOLR_DIR="[path/to/application]"
JAVA_OPTIONS="-Xms64m -Xmx64m -DSTOP.PORT=8079 -DSTOP.KEY=mustard -jar start.jar"
LOG_FILE="/var/log/solr.log"
JAVA="/usr/bin/java"
case $1 in
start)
echo "Starting Solr"
cd $SOLR_DIR
$JAVA $JAVA_OPTIONS 2> $LOG_FILE &
;;
stop)
echo "Stopping Solr"
cd $SOLR_DIR
$JAVA $JAVA_OPTIONS --stop
;;
restart)
$0 stop
sleep 1
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart}" >&2
exit 1
;;
esac
沒有錯誤或任何不尋常var/log/solr.log
(日誌在腳本中命名的文件)。 Centos Linux服務器,如果這是相關的。
在回答這個問題的早期版本,@cdarke建議我在腳本中調用這個腳本運行strace -f -o strace.out /path/to/script
,並期待在(龐大!)輸出文件strace.out
。這幾乎是3mbs,這裏的一些意見:
開始有很多的活動,看起來像腳本功能按預期的。
然後,在過去的15%左右的日誌文件是這樣的,重複用不同的整數,但看似相同的十六進制代碼:
...
25687 futex(0x688d454, FUTEX_WAIT_PRIVATE, 1, {0, 49980000}) = -1 ETIMEDOUT (Connection timed out)
25687 futex(0x688d428, FUTEX_WAKE_PRIVATE, 1) = 0
25687 clock_gettime(CLOCK_MONOTONIC, {39074112, 932735888}) = 0
25687 clock_gettime(CLOCK_REALTIME, {1355007234, 333458000}) = 0
這些PID即使我在腳本仍在運行時輸入ps -p
也沒有任何結果,而輸出文件仍然變大,而這些代碼行仍在寫入。我不太確定這是可能的。
這裏的前的最後位了輸出它得到永無止境的futex的/ clock_gettime循環,後的最後一部分,這顯然是正確執行腳本(solr/solr.xml
是Solr的配置文件,這需要讀取啓動Solr的過程):
25874 stat("solr/solr.xml", {st_mode=S_IFREG|0777, st_size=1320, ...}) = 0
25874 write(2, "Dec 8, 2012 5:12:05 PM org.apach"..., 106) = 106
25874 socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 89
25874 fcntl(89, F_GETFL) = 0x2 (flags O_RDWR)
25874 fcntl(89, F_SETFL, O_RDWR|O_NONBLOCK) = 0
25874 setsockopt(89, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
25874 bind(89, {sa_family=AF_INET, sin_port=htons(8983), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
25874 listen(89, 50) = 0
25874 setsockopt(89, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
25874 lseek(12, 57747, SEEK_SET) = 57747
25874 read(12, "PK\3\4\n\0\0\0\10\0\221Vi>F\347\254\364\325\4\0\0002\t\0\0002\0\0\0", 30) = 30
25874 lseek(12, 57827, SEEK_SET) = 57827
25874 read(12, "\225V\377oSU\24\377\334\273\256\257_\36l\216m\254\262\351\224\241]\273\255\200\314/\5\246c\200"..., 1237) = 1237
25874 futex(0x2aaab0173054, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x2aaab0173050, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1} <unfinished ...>
25894 <... futex resumed>) = 0
25894 futex(0x2aaab0173028, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
25874 <... futex resumed>) = 1
25874 futex(0x2aaab0173028, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
25894 <... futex resumed>) = 0
25894 futex(0x2aaab0173028, FUTEX_WAKE_PRIVATE, 1) = 0
25894 clock_gettime(CLOCK_REALTIME, {1355008325, 376033000}) = 0
25894 futex(0x2aaab0173054, FUTEX_WAIT_PRIVATE, 3, {0, 983000} <unfinished ...>
25874 <... futex resumed>) = 1
25874 futex(0x2aaab0173054, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x2aaab0173050, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1} <unfinished ...>
25894 <... futex resumed>) = 0
25894 futex(0x2aaab0173028, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
25874 <... futex resumed>) = 1
25874 futex(0x2aaab0173028, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
25894 <... futex resumed>) = 0
25894 futex(0x2aaab0173028, FUTEX_WAKE_PRIVATE, 1) = 0
25894 poll([{fd=89, events=POLLIN|POLLERR}], 1, -1 <unfinished ...>
25874 <... futex resumed>) = 1
25874 write(2, "2012-12-08 17:12:05.376:INFO::St"..., 66) = 66
25874 write(2, "\n", 1) = 1
25874 mmap(0x41348000, 12288, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x41348000
25874 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
25874 sched_getaffinity(25874, 32, { ffff, 0, 0, 0 }) = 32
25874 sched_getaffinity(25874, 32, { ffff, 0, 0, 0 }) = 32
25874 gettid() = 25874
25874 rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
25874 rt_sigprocmask(SIG_UNBLOCK, [HUP ILL BUS FPE SEGV USR2 TERM], NULL, 8) = 0
25874 rt_sigprocmask(SIG_BLOCK, [QUIT], NULL, 8) = 0
25874 mmap(0x41348000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x41348000
25874 mprotect(0x41348000, 12288, PROT_NONE) = 0
25874 futex(0x10632d54, FUTEX_WAIT_PRIVATE, 1, NULL <unfinished ...>
25882 <... futex resumed>) = -1 ETIMEDOUT (Connection timed out)
25882 futex(0x106cc428, FUTEX_WAKE_PRIVATE, 1) = 0
25882 clock_gettime(CLOCK_MONOTONIC, {39075204, 21489888}) = 0
25882 clock_gettime(CLOCK_REALTIME, {1355008325, 422198000}) = 0
25882 futex(0x106cc454, FUTEX_WAIT_PRIVATE, 1, {0, 49984000}) = -1 ETIMEDOUT (Connection timed out)
25882 futex(0x106cc428, FUTEX_WAKE_PRIVATE, 1) = 0
25882 clock_gettime(CLOCK_MONOTONIC, {39075204, 72479888}) = 0
25882 clock_gettime(CLOCK_REALTIME, {1355008325, 473185000}) = 0
25882 futex(0x106cc454, FUTEX_WAIT_PRIVATE, 1, {0, 49987000}) = -1 ETIMEDOUT (Connection timed out)
25882 futex(0x106cc428, FUTEX_WAKE_PRIVATE, 1) = 0
因此死亡纏繞之前的最後一行是在信道12上read()
然後,它只是循環futex的和clock_gettime直到它的手動殺死。
最後這一點可能是無關緊要的,但如果similar to in this question,我運行使用nohup
和轉移輸出到/dev/null
調用該腳本的劇本,我得到附近展開以下(約100KB到輸出文件) :巨大的,這些號碼:
25664 close(67) = -1 EBADF (Bad file descriptor)
他們從67去,增加+1每次到:
25664 close(1023) = -1 EBADF (Bad file descriptor)
然後他們接着
25664 open("/dev/null", O_RDWR) = 3
同樣,PID是空的,到目前爲止,我所看到的。不知道這是否是相關的 - 我想這會打開使用nohup與輸出到/ dev/null真的是一個像這樣的問題的一般修復,但我做錯了某種方式,導致這些錯誤。
哪個shell?例如,ksh93將使用'exec'在腳本中執行最終命令,所以您不一定會看到兩個進程。我們需要知道'掛'是否在等待某件事情,如信號。嘗試運行'strace -f -o strace.out ScriptB'。然後看看strace.out(它會很大)。這應該跟蹤內核調用並顯示它是否在等待任何內容。 – cdarke
@cdarke感謝您的帖子。回覆。哪個shell:'ps -p $$ -o comm,args'給我''bash'帶參數'-bash'。回覆。 'strace' - 你是對的,差不多3mbs!我將把該文件中的觀察結果編輯到問題中。 – user568458
@cdarke我已經編輯了所有看起來相關的輸出,以及通過查找這些進程的PID可以獲得的非常有限的信息。非常感謝您的幫助,請確定是否有任何特定的內容我應該在輸出中查找。 – user568458