Bash:从套接字文件描述符读取总是返回相同的数据而不是阻塞

Bash:从套接字文件描述符读取总是返回相同的数据而不是阻塞

我有一个像这样启动的 postgres:

exec 3< <(su -l postgres -c "/usr/local/pgsql/bin/postmaster -p '$port' -d 3 -D '$backupDir' 2>&1 & echo \$!")

这会将所有日志重定向到套接字文件描述符 3

postgres postgres 64 Mar 19 16:32 3 -> socket:[7119806]

然后我读到:

while [ true ]
do
   read -u 3 line
   ... //Listening for an event, then kill 
done

哪个很好用

一旦发生某个事件,我就用“kill”停止postgres

通常情况下,它会关闭,一切正常。但偶尔,关闭不起作用。因此,为了看看会发生什么,我在 kill 之后再次开始监听该套接字

在这种情况下,我总是得到相同的行,这是我之前得到的最后一行。为什么?如果该套接字上没有新内容,我预计它会阻塞。

Postgres: 2021-03-18 23:52:22.234 GMT [4775] DEBUG:  switched WAL source from archive to stream after failure
Postgres: 2021-03-18 23:52:22.234 GMT [4775] DEBUG:  switched WAL source from archive to stream after failure
Postgres: 2021-03-18 23:52:22.234 GMT [4775] DEBUG:  switched WAL source from archive to stream after failure
Postgres: 2021-03-18 23:52:22.234 GMT [4775] DEBUG:  switched WAL source from archive to stream after failure

更新

好的,如果我对 filedescriptor 进行手动 cat 操作cat /proc/13458/fd/3,我会收到我想要收到的所有消息,并且该进程最终会正常退出。因此,Postgres 进程似乎在尝试写入接收器时卡住了,这就是它卡住的原因。

还有一个问题是,为什么我再次尝试接收数据会失败。此行为是在我们的 centos 7 更新后引入的。之前从未发生过这种情况。

更新2

我按照建议对脚本进行了 strace。这是脚本陷入的循环和堆栈跟踪。它以 sleep 开始,以 sleep 结束。我也尝试不使用 -t 0,结果相同。

while [ true ]
do
  #Checking if postgres is still running
  ps -q $postgresPid aux | tail -n1
  if [ $? -ne 0 ]
  then
    break
  else
    #Try reading postgres logs
    lastLine=""
    line=""
    while [ true ]
    do
      read -t 0 -u 3 line
      if [ $? -ne 0 ]
      then
        break
      fi
      if [ "$lastLine" == "$line" ]
      then
        break
      fi
      lastLine=$line
      echo "Postgres: $line"
    done
    
    sleep 5
  fi
done

一个周期内输出(始终相同)

2021-03-19 21:33:45:  postgres 27807  0.0  0.0 410588 19864 ?        S    17:02   0:00 /usr/local/pgsql/bin/postmaster -p 57943 -d 3 -D /tank/backups/cv17/databases/postgres/data
2021-03-19 21:33:45:  Postgres: 2021-03-19 17:39:20.733 GMT [27808] DEBUG:  switched WAL source from archive to stream after failure

斯特拉斯:

strace: Process 9703 attached
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 350
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=350, si_uid=0, si_status=0, si_utime=0, si_stime=0} ---
wait4(-1, 0x7ffd1dbd6a50, WNOHANG, NULL) = -1 ECHILD (No child processes)
rt_sigreturn({mask=[]})                 = 0
rt_sigaction(SIGINT, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
pipe([4, 5])                            = 0
rt_sigprocmask(SIG_BLOCK, [INT CHLD], [CHLD], 8) = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f915b541a10) = 1686
rt_sigprocmask(SIG_SETMASK, [CHLD], NULL, 8) = 0
close(5)                                = 0
close(5)                                = -1 EBADF (Bad file descriptor)
rt_sigprocmask(SIG_BLOCK, [INT CHLD], [CHLD], 8) = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f915b541a10) = 1691
rt_sigprocmask(SIG_SETMASK, [CHLD], NULL, 8) = 0
close(4)                                = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [CHLD], 8) = 0
rt_sigprocmask(SIG_SETMASK, [CHLD], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [CHLD], 8) = 0
rt_sigaction(SIGINT, {sa_handler=0x43e910, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, 8) = 0
rt_sigaction(SIGINT, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, {sa_handler=0x43e910, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, 8) = 0
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 1691
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 1686
rt_sigprocmask(SIG_SETMASK, [CHLD], NULL, 8) = 0
rt_sigaction(SIGINT, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, 8) = 0
close(4)                                = -1 EBADF (Bad file descriptor)
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=1691, si_uid=0, si_status=0, si_utime=0, si_stime=0} ---
wait4(-1, 0x7ffd1dbd6c50, WNOHANG, NULL) = -1 ECHILD (No child processes)
rt_sigreturn({mask=[]})                 = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
fcntl(3, F_GETFD)                       = 0
select(4, [3], NULL, [3], {tv_sec=0, tv_usec=0}) = 1 (in [3], left {tv_sec=0, tv_usec=0})
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
write(1, "Postgres: 2021-03-19 17:39:20.73"..., 111) = 111
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
fcntl(3, F_GETFD)                       = 0
select(4, [3], NULL, [3], {tv_sec=0, tv_usec=0}) = 1 (in [3], left {tv_sec=0, tv_usec=0})
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [INT CHLD], [], 8) = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f915b541a10) = 1734
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGINT, {sa_handler=0x43e910, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, 8) = 0
rt_sigaction(SIGINT, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, {sa_handler=0x43e910, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, 8) = 0
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 1734
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=1734, si_uid=0, si_status=0, si_utime=0, si_stime=0} ---
wait4(-1, 0x7ffd1dbd6a50, WNOHANG, NULL) = -1 ECHILD (No child processes)
rt_sigreturn({mask=[]})                 = 0
rt_sigaction(SIGINT, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
pipe([4, 5])                            = 0
rt_sigprocmask(SIG_BLOCK, [INT CHLD], [CHLD], 8) = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f915b541a10) = 1903
rt_sigprocmask(SIG_SETMASK, [CHLD], NULL, 8) = 0
close(5)                                = 0
close(5)                                = -1 EBADF (Bad file descriptor)
rt_sigprocmask(SIG_BLOCK, [INT CHLD], [CHLD], 8) = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f915b541a10) = 1904
rt_sigprocmask(SIG_SETMASK, [CHLD], NULL, 8) = 0
close(4)                                = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [CHLD], 8) = 0
rt_sigprocmask(SIG_SETMASK, [CHLD], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [CHLD], 8) = 0
rt_sigaction(SIGINT, {sa_handler=0x43e910, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, 8) = 0
rt_sigaction(SIGINT, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, {sa_handler=0x43e910, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, 8) = 0
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 1904
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 1903
rt_sigprocmask(SIG_SETMASK, [CHLD], NULL, 8) = 0
rt_sigaction(SIGINT, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, 8) = 0
close(4)                                = -1 EBADF (Bad file descriptor)
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=1904, si_uid=0, si_status=0, si_utime=0, si_stime=0} ---
wait4(-1, 0x7ffd1dbd6c50, WNOHANG, NULL) = -1 ECHILD (No child processes)
rt_sigreturn({mask=[]})                 = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
fcntl(3, F_GETFD)                       = 0
select(4, [3], NULL, [3], {tv_sec=0, tv_usec=0}) = 1 (in [3], left {tv_sec=0, tv_usec=0})
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
write(1, "Postgres: 2021-03-19 17:39:20.73"..., 111) = 111
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
fcntl(3, F_GETFD)                       = 0
select(4, [3], NULL, [3], {tv_sec=0, tv_usec=0}) = 1 (in [3], left {tv_sec=0, tv_usec=0})
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [INT CHLD], [], 8) = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f915b541a10) = 1905
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGINT, {sa_handler=0x43e910, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, 8) = 0
rt_sigaction(SIGINT, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, {sa_handler=0x43e910, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f915ab7f450}, 8) = 0
wait4(-1, 

更新 3

好的,我的问题的一部分是,exec 3< <(command)如果没有人使用文件描述符 3 提供的输出,那么执行确实会在几行之后阻塞。并且这个缓冲区大小可能是我更新后发生变化的,并导致了我最初的问题,因为我在发送 kill 命令后停止了使用。

我仍然不知道为什么在杀死失败后继续消费,但我想我现在可以重写我的代码,从一开始就不会真正停止消费。

相关内容