我有一个简单的bash脚本如下所示,它是docker镜像的一部分。
test.sh
,
#!/bin/bash
set -e
logit() {
log_date=`date +"%F %T"`
echo "[$log_date][INFO] $1"
}
waitForServerToStart() {
while true; do
logit "Testing .... 1"
netstat -anpt
logit "Testing .... 2"
netstat -anpt | grep tcp
logit "Testing .... 3"
sleep 5
logit "Testing .... 4"
done
}
waitForServerToStart
run.sh
,
#!/bin/sh
/test.sh &
# Run forever
while true; do sleep 5; done
Dockerfile,
FROM openjdk:8u191-jre-alpine3.9
COPY files/run.sh /
COPY files/test.sh /
CMD ["/run.sh"]
如果我运行这个容器我只得到以下输出,这让我相信不知何故grep
和“管道”似乎被阻止。
[2019-03-06 11:10:45][INFO] Testing .... 1
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 172.17.0.2:58278 xxx.xxx.xx.xx:443 FIN_WAIT2 -
[2019-03-06 11:10:45][INFO] Testing .... 2
有人可以为此解释一下吗?
它工作正常如果我评论netstat -anpt | grep tcp
。然后我会看到后续的日志行,它也会在循环中继续。
[2019-03-06 11:25:36][INFO] Testing .... 3
[2019-03-06 11:25:41][INFO] Testing .... 4
这让我感到困惑!但我有一个解决方案:
使用awk而不是grep
在test.sh
中使用此代替:
netstat -anpt | awk /tcp/
这样文件看起来像这样:
#!/bin/bash
set -e
logit() {
log_date=`date +"%F %T"`
echo "[$log_date][INFO] $1"
}
waitForServerToStart() {
while true; do
logit "Testing .... 1"
netstat -anpt
logit "Testing .... 2"
netstat -anpt | awk /tcp/
logit "Testing .... 3"
sleep 5
logit "Testing .... 4"
done
}
waitForServerToStart
由于我无法解释的原因 - 当从脚本调用时从管道读取时grep
不会返回。我在本地创建了你的容器,运行它并输入它 - 命令netstat -anpt | grep tcp
运行得很好并退出。如果你用netstat -anpt | cat
脚本中的test.sh
替换它,那么它也会通过就好了。
我在整个地方寻找与你正在使用的发行版的容器中的grep相同问题的人,版本等 - 但空手而归。
我相信这可能与grep等待一个永不落地的EOF角色有关 - 但我不确定。