如何在不使用 netcat 的情况下使用 oneliner 命令检查 shell 中的连接?

如何在不使用 netcat 的情况下使用 oneliner 命令检查 shell 中的连接?

在 docker 映像中,我想避免安装 netcat 以便在入口点脚本中 ping 数据库连接:

/bin/sh

MOODLE_DB_HOST="xxxx"
MOODLE_DB_PORT=80

function pingdb {
    OK=0
    for count in {1..100}; do
      echo "Pinging database attempt ${count} into ${MOODLE_DB_HOST}:${MOODLE_DB_PORT}" 
      if  $(nc -z ${MOODLE_DB_HOST} ${MOODLE_DB_PORT}) ; then
        echo "Can connect into database"
        OK=1
        break
      fi
      sleep 5
    done

    echo "Is ok? "$OK

    if [ $OK -eq 1 ]; then
      echo "Database type: "${MOODLE_DB_TYPE}
      echo "DB Type: "${MOODLE_DB_TYPE}
    else
      echo >&2 "Can't connect into database"
      exit 1
    fi
}

但相反,我想使用ncphp 来替代在 docker 映像上运行的入口点脚本。

还有其他选择吗?

我想要这样做的原因是因为我有 2 个 Dockerfile,一个基于 debian,一个基于 alpine:

基于 debian 的 php 镜像:

ARG PHP_VERSION="7.4"
FROM  php:${PHP_VERSION}-fpm as base

RUN --mount=type=bind,from=mlocati/php-extension-installer:latest,source=/usr/bin/install-php-extensions,target=/usr/local/bin/install-php-extensions \
    /usr/local/bin/install-php-extensions xmlrpc mbstring zip xml intl soap gd opcache &&\
    echo "PHP_EXTENTION_DIR="$(php -i | grep extension_dir  | cut -d " " -f 5) >> /etc/environment &&\
    cat /etc/environment &&\
    apt-get update &&\
    apt-get install -y netcat &&\
    apt-get autopurge -y &&\
    apt-get autoremove -y &&\
    apt-get autoclean &&\
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* cache/* /var/lib/log/* &&\
    echo "max_input_vars=5000" > ${PHP_INI_DIR}/conf.d/moodle.ini

COPY ./scripts/entrypoint.sh /usr/local/bin/entrypoint.sh

RUN chown root:root /usr/local/bin/entrypoint.sh &&\
    chmod +x /usr/local/bin/entrypoint.sh

ENTRYPOINT ["/bin/sh","/usr/local/bin/entrypoint.sh"]
CMD ["php-fpm"]

以高山为基础:


ARG PHP_VERSION="7.4"
FROM  php:${PHP_VERSION}-fpm-alpine as base

RUN --mount=type=bind,from=mlocati/php-extension-installer:latest,source=/usr/bin/install-php-extensions,target=/usr/local/bin/install-php-extensions \
    /usr/local/bin/install-php-extensions xmlrpc mbstring zip xml intl soap gd opcache &&\
    apk update &&\
    apk add netcat-openbsd &&\
     rm -rf /var/cache/apk/* /var/tmp/* cache/* /var/lib/log/* &&\
    echo "max_input_vars=5000" > ${PHP_INI_DIR}/conf.d/moodle.ini

COPY ./scripts/entrypoint.sh /usr/local/bin/entrypoint.sh

RUN chown root:root /usr/local/bin/entrypoint.sh &&\
    chmod +x /usr/local/bin/entrypoint.sh

ENTRYPOINT ["/bin/sh","/usr/local/bin/entrypoint.sh"]
CMD ["php-fpm"]

有时,根据参数PHP_VERSION可能或可能不存在用于安装 netcat 的包(或以不同的名称存在)。此外apk add,还apt-get显着增加了构建时间。

那么有没有替代方法呢?

答案1

就在这里:

function pingdb {
    OK=0
    for i in $(seq 1 100); do
      echo "Pinging database attempt ${count} into ${MOODLE_DB_HOST}:${MOODLE_DB_PORT}" 
      if  $(php -r "is_resource(@fsockopen(\"${MOODLE_DB_HOST}\",intval(\"${MOODLE_DB_PORT}\")))?exit(0):exit(1);") ; then
        echo "Can connect into database"
        OK=1
        break
      fi
      sleep 5
    done


    if [ $OK -eq 1 ]; then
      echo "Database type: "${MOODLE_DB_TYPE}
      echo "DB Type: "${MOODLE_DB_TYPE}
    else
      echo >&2 "Can't connect into database"
      exit 1
    fi
}

正如你所看到的,nc被替换如下:

php -r "is_resource(@fsockopen(\"${MOODLE_DB_HOST}\",intval(\"${MOODLE_DB_PORT}\")))?exit(0):exit(1);"

需要fsockopen2 个参数:

  • host
  • port

我所做的是尝试在 php 中打开一个套接字并检查套接字是否已打开。如果是,则我以0状态代码退出,否则我以1.每个参数都使用来自 shell 脚本的字符串传递,因此我"使用字符进行编码\,以便将值转换为 php 字符串。

不使用 vars 你可以这样做:

php -r "is_resource(@fsockopen(\"google.com",80)))?exit(0):exit(1);"

但是为了安全起见,我使用了使用 bash 参数的版本中的 intval。

相关内容