![Bash 脚本在执行过程中卡住](https://linux22.com/image/51784/Bash%20%E8%84%9A%E6%9C%AC%E5%9C%A8%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%E4%B8%AD%E5%8D%A1%E4%BD%8F.png)
我有一个 bash 脚本正在读取一个CSV
文件,其中包含source IP
地址、destination IP
地址和destination port
.
我的脚本基本上做了两个测试:
1 性能 2 连接性。
在性能测试下,我将文件从 复制source
到destination
(使用scp
)来计算网络 IO。之后,将同一文件从目标服务器的一个位置复制到目标服务器上的另一位置以计算磁盘 I/O。
在连接测试下,我正在执行nc
从 到source
检查destination
是否port
打开。
问题 :有时在执行脚本时,它会在某个时刻卡住,然后我必须按Ctrl+C
杀死该进程才能继续进一步执行。
在这里,我无法弄清楚为什么它会被卡住,甚至每次它卡在脚本中的不同位置时,行为也不一致。
请帮助我解决这个问题。如果需要,我可以在这里发布我的完整脚本。
更新 :
观察:我观察到的另一件事是,如果我不按 Ctrl+C ,则脚本会在 5 分钟后自动恢复。
实际脚本的一部分,它被卡住了。
#Connectivity Test
TMP=$(mktemp)
nc -z -v -n $lastDestinationIP $port >\$TMP
if grep -q "succeeded" <<< cat echo \$TMP;then
echo $x','$lastSourceIP','$lastDestinationIP','$sourceFqdn','$fqdn','$port',Connectivity,NA,NA,NA,Pass,'$(date) | ssh $username@$baseLocation 'cat >> report.txt'
else
echo $x','$lastSourceIP','$lastDestinationIP','$sourceFqdn','$fqdn','$port',Connectivity,NA,NA,NA,Fail,'$(date) | ssh $username@$baseLocation 'cat >> report.txt'
fi
rm $TMP
fi
exit
ENDSSH
大多数时候它在调用退出时卡住了。
这是大部分时间都卡住的代码片段(来自控制台)。
21 14:48:16 EDT 2014 | ssh [email protected] 'cat >> report.txt','Fri Mar
> fi
>
> #rm KB_33.txt
> #rm MB_10.txt
> #rm MB_100.txt
> rm -rf dummy
> else
> #Connectivity Test
> nc -z -v -n -w 2 10.X.X.17 1524 >/tmp/tmp.GJ1knZF5Jn
> if grep -q "succeeded" <<< cat echo /tmp/tmp.GJ1knZF5Jn;then
21 14:48:16 EDT 2014 | ssh [email protected] 'cat >> report.txt','Fri Mar
> else
21 14:48:16 EDT 2014 | ssh [email protected] 'cat >> report.Fail,'Fri Mar
> fi
> fi
> exit
>
答案1
这是简短而甜蜜- Aheredoc
基本上是一个流式传输到文件描述符的文件。
大多数人并不表示0<<descriptor
所以你就可以了<&0 stdin. ssh
通过stdin
到它调用的进程,所以如果你给它提供一个heredoc
它将把输入传递到调用的远程 shell。
一项非常特别的品质heredocs
之间的差异是\"'quoted
和unquoted heredoc LIMITER.
所以,<<'THIS'
不同于<<THIS.
当你不引用LIMITER,
评估此处文档的内容${shell:+expansion}
。一次一个${shell:+expansion}
通过完成后,几乎没有什么可以区分此处文档与任何其他文件作为<~/input
。
例如:
cat <<\QUOTED >~/file
$(echo "This is ${NOT:-} expanded.")
#END
QUOTED
cat <~/file
> $(echo "This is ${NOT:-} expanded.")
> #END
但...
cat <<UNQUOTED >~/file
$(echo "This is ${NOT:-} expanded.")
#END
UNQUOTED
cat <~/file
> This is expanded.
> #END
您继续使用bash <<< herestring
和cat.
我不知道具体是如何herestring
有效,但我愿意打赌cat's
已经参与了。所以cat
连接它是<&0stdin
以其stdout>&1
。这就是它的全部作用。所以你不必要地使事情复杂化<<STDIN
当你<<< cat
它。
这可能是一个真正的问题,如果cat
最终消耗了您不希望它消耗的输入流。只跑% cat
在你的终端上,看起来好像什么也没发生,因为终端的stdin
和stdout
是同一个文件 - 你的$(tty)
。但当它们不同时,cat
联合起来不管怎样,如果你不是故意的,那可能会变得非常混乱。
在我看来就像一些\'quotes
正在跳过扩展时$(date)
是$expanded
。那么可能是: null shell builtin
被调用并且|piped
到下一个不带引号的命令后ssh
这将是cat >> report.fail
应该不会在该文件中生成任何内容。所以cat
是>>appending /dev/null
到report.fail
,我想,只要它能忍受。或者,更有可能的是,只要exit
允许ssh
进行代理null stream.
另外,你检查过你是否有一个字面意思吗?$TMP
在你当前的工作目录中?我确实看到了ENDSSH
在底部看起来像heredoc LIMITER
对我来说,我相信这不是完整的剧本,或者是被错误编辑的。如果它是要使用的heredoc的主体,那就有意义了\$TMP,
但正如我所想nc
首先会>truncate
然后写出它的stdout
到一个名为$TMP.
再说一遍,我猜你rm
无论如何,所以也许你只是没有注意到。
并且因为你是rm
英$TMP
你可能没有意识到有人会问这个问题:
如何$(mktemp)
为您工作,无需filename.xxx
争论?
更新我仔细看了你的输出,绝对是>/tmp/tmp.GJ1knZF5Jn
方法$(mktemp)
正在工作 - 即使\$TMP
部分。所以你刚刚告诉我我只需要指定mktemp .xxx
如果我指定一个文件名的话。谢谢。
我仍然认为顶部某个地方有一个异端?可能没有并且\\
只是尝试解决该方法的副作用echo \$TMP <<<herestring,
但我不知道...有趣。
我不知道我是否完全正确,因为我不知道所有这些变量从何而来。但是,这与我的做法很接近:
(这实际上使得最后两个问题无关紧要)
_ssh() ( ssh "$1"@"$2" 'printf %s, `cat` >> '"$3"
) <<-PARAMS
"$lastSourceIP"
"$lastDestinationIP"
"$sourceFqdn"
"$fqdn"
"$port" "
"ConnectivityNA"
"NA"
"NA"
"Pas"
"$(date)"
PARAMS
nc -z -v -n $lastDestinationIP $port |\
grep -q "succeeded" && suffix=txt
_ssh user host report.${suffix:-fail}
unset suffix
?ENDSSH?
笔记:这"$quotes"
上面的内容是为了printf's
另一边的利益ssh
过程——不为别的。那些"quotes"
即使完成上述所有操作后仍保持原样PARAMS
被评估。
我之前已经介绍过那里发生的一些事情。例如func() ( scope )
我喜欢认为是在这里覆盖ok。这${parameter:-expansion}
也被覆盖在那里,但也展示得相当好这里和这里。我遇到了一些奇怪的heredoc问题这里,这里, 和这里。可能还有其他人——我想我喜欢弄乱我的外壳什么的。
不过,在这种情况下,使用我所拥有的函数和heredoc,cat
不能被卡住。PARAMS
被发送为stdin
和cat
当它达到一个时就会退出EOF
(或者CTRL-D
)所以一旦消耗PARAMS
每次都会停下来。如果您在以下环境中运行此程序,这一点尤其重要heredoc
这是还在<&0
因为PARAMS
将阻碍cat
在执行过程中吃掉你的脚本。
无论如何,希望这会有所帮助。如果我错过了什么,请随时询问。