将 stderr 重定向到一个函数,看来 2> 是非阻塞的,我需要它

将 stderr 重定向到一个函数,看来 2> 是非阻塞的,我需要它

请注意,我包含了有关正在发生的事情的上下文的函数。 ibmcloud CLI 本身并不相关,它只是有一个提示,这就是问题所在。

我在用着zsh。我有以下功能:

kcu() {
  kcu_match=`kcg | grep $1 | awk '{print $2}'`
  if [[ -z $kcu_match ]]; then
    echo No match for context \"$1\"
  else
    kc use-context $kcu_match
    # Do a trivial operation to determine login
    k get namespace 1>/dev/null 2> >(kcu-iferror $kcu_match)
  fi
}
# version for the first screenshot..
# kcu-iferror() {
#  while read line; do
#    # if we are here we have an error
#    slm-login-ic $1
#    # first line is enough
#    break
#  done
# }

#version for the second screenshot..
kcu-iferror() {
  login=0
  while read line; do
    login=1
    # shows the output (in this case 2 lines but doesn't matter)
    echo "line: $line"
    break
  done
  echo "value: $login"
  if [[ $login -eq 1 ]]; then
    slm-login-ic $1
  fi
}


slm-login-ic() {
  echo Log in to $1..
  echo ">> " ibmcloud login -a cloud.ibm.com -r us-south -g Default --sso
  ibmcloud login -a cloud.ibm.com -r us-south -g Default --sso
  echo ">> " ibmcloud ks cluster config --cluster $1
  ibmcloud ks cluster config --cluster $1
}

如果我slm-login-ic my-cluster-id直接打电话就可以了。

但是,如果我运行,kcu my-cluster-id就会遇到问题:错误输出被用作提示ibmcloud“在默认浏览器中打开 URL?”的输入。并提交(下面的屏幕截图)。

如何阻止这种情况发生以便用户可以输入Y
额外问题:如何将“错误”更改为 aY以便用户不需要回答提示?

在此输入图像描述

更新——故事还在继续

因此,经过一些实验,真正的问题似乎是2> >(something)非阻塞的。这意味着我的 CLI 命令已经关闭,但错误重定向(需要一些时间)仍在输出内容,并且通常会使事情变得混乱。

那么问题就变成了:如何使 STDERR 的重定向成为阻塞?谢谢

更新 - 直至最终的“非阻塞”拦截器

通过让整个错误消息循环通过,我至少可以停止实际的错误消息线从发布到ibmcloudY/n 提示。但我无法完全阻止它发布。整个问题的关键在于如何a)让父shell/进程等待,b)让错误对象停止被吐出(在这种情况下)到子shell/进程中的提示。谢谢

我已尝试以下所有方法:

      k get namespace -A 2>&1 1>/dev/null | kcu-iferror $kcu_match
    { k get namespace -A } 1>/dev/null 2> >(kcu-iferror $kcu_match)
      k get namespace -A 2>&1 1>/dev/null | kcu-iferror $kcu_match
    { k get namespace -A } 2>&1 1>/dev/null | kcu-iferror $kcu_match

在此输入图像描述

答案1

正如手册中所述,解决方案是运行要从中重定向输出的进程,作为当前 shell 中的作业:

    # Do a trivial operation to determine login
    { k get namespace } 1>/dev/null 2> >(kcu-iferror $kcu_match)

这将导致父 shell 等待进程完成。

相关内容