Docker容器中的管道和grep似乎被阻止

时间:2019-03-06 11:13:07

标签: bash docker grep

我有一个简单的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

1 个答案:

答案 0 :(得分:1)

这个让我感到困惑!但我有一个解决方案:

使用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字符有关,但我不确定。