bash 대기 프로세스는 프로세스가 종료된 후에도 중지됩니다.

bash 대기 프로세스는 프로세스가 종료된 후에도 중지됩니다.

mariadb 테스트 컨테이너의 시작을 결정하는 스크립트를 작성하려고 합니다. port: 3306는 마지막 줄입니다 . 이후에는 많은 내용이 예상되지 않습니다(따라서 SIGPIPE에 의존하는 대신 프로세스를 podman logs -f종료해 보십시오 ).podman logs

  set -x -v; \
  podman run -d --name mdb_test -P -e MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=1  mariadb:10.6 ; \
  podman logs -f mdb_test 2>&1 | grep -m1 'port: 3306' & \
  pid_grep=$! ; \
  pid_podman_logs=$(jobs -p); \
  jobs; \
  wait $pid_grep; \
  kill $pid_podman_logs; \
  port=$(podman port mdb_test 3306); \
  mysql -u root --protocol tcp --port ${port#*:}  -e 'select version()';

산출:

+ set -x -v
+ podman run -d --name mdb_test -P -e MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=1 mariadb:10.6
299b645a84b278d2ffcfb776bf12cf282a0695131bf77a02f0c7701a9ea1868b
[1]+  Done                    podman logs -f mdb_test 2>&1 | grep -m1 'port: 3306'
[1] 2414801
+ pid_grep=2414801
+ podman logs -f mdb_test
+ grep -m1 'port: 3306'
++ jobs -p
+ pid_podman_logs=2414800
+ jobs
[1]+  Running                 podman logs -f mdb_test 2>&1 | grep -m1 'port: 3306' &
+ wait 2414801
Version: '10.6.1-MariaDB-1:10.6.1+maria~focal'  socket: '/run/mysqld/mysqld.sock'  port: 3306  mariadb.org binary distribution

쉘이 종료되었고( 아직 실행 중임 wait에도 불구하고) 왜 중지되고 진행되지 않는지 궁금합니다 .greppodman logs

다른 스크립트 개선도 환영합니다.

더 간단한 버전 편집:

set -x -v ; (echo "bob"; sleep 100000) | grep -m1 bob & pid_grep=$!; pid_echo=$(jobs -p); jobs ; wait $pid_grep; kill $pid_echo; echo ready
+ set -x -v
[1] 2417616
+ pid_grep=2417616
+ grep -m1 bob
+ echo bob
+ sleep 100000
++ jobs -p
+ pid_echo=2417615
+ jobs
[1]+  Running                 ( echo "bob"; sleep 100000 ) | grep -m1 bob &
+ wait 2417616
bob

다른 쉘에서 ps를 확인하면 grep이 완료되었습니다.

답변1

IMO, 당신이 진행하는 방식은 완전히 잘못되었습니다.

프로세스가 포트에서 수신 대기하고 올바르게 응답하는지 확인하는 올바른 방법은 포트에 연결하여 쿼리하는 것입니다. grep 로그의 가장 좋은 효과는 지금 실제로 듣고 있는 것이 아니라 과거 어느 시점에 듣고 있었다는 것을 알려주는 것입니다. 로그 항목과 지금 사이에 어느 시점에 죽었을 수도 있습니다.

따라서 mysql을 시작하고 while 루프를 사용하여 mysql이 올바르게 응답하는지 확인하십시오. 루프가 반복될 때마다 몇 초 동안 휴면 상태를 유지합니다.

전체 스크립트를 다음과 같이 대체할 수 있습니다. 백그라운드 작업, 대기, PID 종료 등이 필요하지 않습니다.

podman run -d --name mdb_test -P -e MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=1  mariadb:10.6

# I'm not sure why you need to do this rather than just 'port=3306', but I don't
# know podman. Maybe it's necessary for some kind of namespace port mapping.
port=$(podman port mdb_test 3306)
port=${port#*:}

MYSQL_VERSION=""
while [[ ! "$MYSQL_VERSION" =~ ^Version ]] ; do
   sleep 2
   MYSQL_VERSION=$(mysql -u root --protocol tcp --port "$port"  -e 'select version()')
done
echo "$MYSQL_VERSION"

답변2

coproc은 한 가지 방법입니다.

set -x -v; \
podman run -d --name mdb_test -P -e MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=1  mariadb:10.6 ; \
coproc podman logs -f mdb_test 2>&1; \
pid_podman_logs=${COPROC_PID}; \
grep -m1 'port: 3306' <&"${COPROC[0]}"; \
kill $pid_podman_logs; \
port=$(podman port mdb_test 3306); \
mysql -u root --protocol tcp --port ${port#*:}  -e 'select version()';

산출:

+ set -x -v
+ podman run -d --name mdb_test -P -e MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=1 mariadb:10.6
c8bc23b8b7b0c34e1037f28797f34184e768f7def9ee220f2b8760484a2d798e
[1] 2420140
+ pid_podman_logs=2420140
+ grep -m1 'port: 3306'
+ podman logs -f mdb_test
Version: '10.6.1-MariaDB-1:10.6.1+maria~focal'  socket: '/run/mysqld/mysqld.sock'  port: 3306  mariadb.org binary distribution
+ kill 2420140
++ podman port mdb_test 3306
+ port=0.0.0.0:34497
+ mysql -u root --protocol tcp --port 34497 -e 'select version()'
+-------------------------------------+
| version()                           |
+-------------------------------------+
| 10.6.1-MariaDB-1:10.6.1+maria~focal |
+-------------------------------------+
[1]+  Exit 1                  coproc COPROC podman logs -f mdb_test 2>&1

따라서 더 간단한 버전의 경우:

set -x -v ; coproc (echo "bob"; sleep 100000) ; pid_echo=${COPROC_PID};  grep -m1 bob  <&"${COPROC[0]}" <&"${COPROC[0]}" ; kill $pid_echo; echo ready
+ set -x -v
[1] 2418707
+ pid_echo=2418707
+ grep -m1 bob
+ echo bob
+ sleep 100000
bob
+ kill 2418707
+ echo ready
ready

관련 정보