linux – Shell脚本挂起,但只有在调用变量或strace时才会挂起
一般问题:什么可能导致脚本本身工作正常,如果调用它的脚本或
shell(bash)命令将其调用为变量,则挂起?
换句话说,怎么会有一个脚本在这样调用时工作… / 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,它也会挂起. 奇怪的是,其他脚本以相同的方式使用相同的语法调用,例如sbin / service httpd start,调用变量时工作得很好.因此,当输出存储为变量时,显然可能存在一些脚本会使其挂起,但在不是这种情况时可以很好地运行. 这是测试挂起的内容和不挂起的内容的结果: 挂勾———————————————— > VAR = $(/ sbin / service solr start); (因此调用它的过程并不重要)此外,编辑脚本文件以使用源启动服务会导致服务无法正常工作. 不要挂————————————- > VAR = $(/ sbin / service solr start>> / dev / null); 输出到/ dev / null允许我们请求输出而不会导致它挂起.然而,它并没有多大用处,因为没有收到实际的输出. > / sbin / service solr start 与我最初的想法相反.这会输出一条简单的更新消息,理想情况下,我们会在变量和日志中捕获它 – 但尝试这样做会导致它挂起. > VAR = $(/ sbin / service httpd restart); 挂起的语法在其他服务脚本上运行得很好,并且脚本的输出会毫无问题地传递给变量. 这是该脚本的完整代码:(注释已删除,自然$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,这里有一些观察: >从大量活动开始,看起来脚本按预期运行. … 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,4) = 0 25874 lseek(12,57747,SEEK_SET) = 57747 25874 read(12,"PK34n 10 221Vi>F3472543643254 002t 002 ",30) = 30 25874 lseek(12,57827,SEEK_SET) = 57827 25874 read(12,"225V377oSU24377334273256257_36l216m254262351224241]273255200314/5246c200"...,1237) = 1237 25874 futex(0x2aaab0173054,FUTEX_WAKE_OP_PRIVATE,0x2aaab0173050,{FUTEX_OP_SET,FUTEX_OP_CMP_GT,1} <unfinished ...> 25894 <... futex resumed> ) = 0 25894 futex(0x2aaab0173028,2,NULL <unfinished ...> 25874 <... futex resumed> ) = 1 25874 futex(0x2aaab0173028,1 <unfinished ...> 25894 <... futex resumed> ) = 0 25894 futex(0x2aaab0173028,1) = 0 25894 clock_gettime(CLOCK_REALTIME,{1355008325,376033000}) = 0 25894 futex(0x2aaab0173054,3,983000} <unfinished ...> 25874 <... futex resumed> ) = 1 25874 futex(0x2aaab0173054,1) = 0 25894 poll([{fd=89,events=POLLIN|POLLERR}],-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 }) = 32 25874 sched_getaffinity(25874,0 }) = 32 25874 gettid() = 25874 25874 rt_sigprocmask(SIG_BLOCK,8) = 0 25874 rt_sigprocmask(SIG_UNBLOCK,[HUP ILL BUS FPE SEGV USR2 TERM],8) = 0 25874 rt_sigprocmask(SIG_BLOCK,[QUIT],8) = 0 25874 mmap(0x41348000,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,0) = 0x41348000 25874 mprotect(0x41348000,PROT_NONE) = 0 25874 futex(0x10632d54,NULL <unfinished ...> 25882 <... futex resumed> ) = -1 ETIMEDOUT (Connection timed out) 25882 futex(0x106cc428,1) = 0 25882 clock_gettime(CLOCK_MONOTONIC,{39075204,21489888}) = 0 25882 clock_gettime(CLOCK_REALTIME,422198000}) = 0 25882 futex(0x106cc454,49984000}) = -1 ETIMEDOUT (Connection timed out) 25882 futex(0x106cc428,72479888}) = 0 25882 clock_gettime(CLOCK_REALTIME,473185000}) = 0 25882 futex(0x106cc454,49987000}) = -1 ETIMEDOUT (Connection timed out) 25882 futex(0x106cc428,1) = 0 所以死亡螺旋之前的最后一行是通道12上的read().然后它只是循环futex和clock_gettime直到它被手动杀死. 最后一点可能无关紧要,但是,如果,similar to in this question,我运行使用nohup调用此脚本并将输出转移到/ dev / null的脚本,我在开始附近得到以下内容(大约100kb到输出文件中):一个巨大的数字这些: 25664 close(67)= -1 EBADF(错误的文件描述符) 他们从67,每次增加1,到: 25664 close(1023)= -1 EBADF(错误的文件描述符) 然后他们跟着 25664 open(“/ dev / null”,O_RDWR)= 3 同样,就我所见,PID是空的.不确定这是否相关 – 我想这开启了将nohup与输出一起使用到/ dev / null的可能性确实是对这类问题的一般修复,但我在某种程度上做错了,导致这些错误. 解决方法
我很确定问题是shell正在从/ sbin / service脚本和它启动的solr服务捕获输出,因此在继续之前会等待服务退出(或者至少关闭它的stdout).这是一个简单的演示:
$bg_service() { while true; do sleep 10; done; } $start_bg_service() { echo "starting"; bg_service& echo "running"; } $start_bg_service starting [1] 8656 running $var=$(start_bg_service) [It hangs at this point... until I open another shell and kill the background process] (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |