Bash 脚本在执行过程中卡住

Bash 脚本在执行过程中卡住

我有一个 bash 脚本正在读取一个CSV文件,其中包含source IP地址、destination IP地址和destination port.

我的脚本基本上做了两个测试:

1 性能 2 连接性。

在性能测试下,我将文件从 复制sourcedestination(使用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之间的差异是\"'quotedunquoted 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 <<< herestringcat.我不知道具体是如何herestring有效,但我愿意打赌cat's已经参与了。所以cat连接它是<&0stdin以其stdout>&1这就是它的全部作用。所以你不必要地使事情复杂化<<STDIN当你<<< cat它。

这可能是一个真正的问题,如果cat最终消耗了您不希望它消耗的输入流。只跑% cat在你的终端上,看起来好像什么也没发生,因为终端的stdinstdout是同一个文件 - 你的$(tty)但当它们不同时,cat联合起来不管怎样,如果你不是故意的,那可能会变得非常混乱。

在我看来就像一些\'quotes正在跳过扩展时$(date)$expanded那么可能是: null shell builtin被调用并且|piped到下一个不带引号的命令ssh这将是cat >> report.fail应该不会在该文件中生成任何内容。所以cat>>appending /dev/nullreport.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被发送为stdincat当它达到一个时就会退出EOF(或者CTRL-D所以一旦消耗PARAMS每次都会停下来。如果您在以下环境中运行此程序,这一点尤其重要heredoc这是<&0因为PARAMS将阻碍cat在执行过程中吃掉你的脚本。

无论如何,希望这会有所帮助。如果我错过了什么,请随时询问。

相关内容