Return 来自 Bash 函数的文件描述符

Return file descriptor from Bash function

我现在有这个 Bash 函数,它是 "hardcoded" 将 JSON 消息写入文件描述符:

ql_connect(){
   port_file="$HOME/.quicklock/server-port.json"

   my_str=$(cat "$port_file");
   typeset -i my_num="${my_str:-"1"}"

    exec 3<>"/dev/tcp/localhost/$my_num"  # persistent file descriptor

    exit_code=$?

    if [[ ${exit_code} -ne 0 ]]; then
      echo "quicklock: could not connect.";
      return 1;
    fi

    echo "{\"init\":true,\"quicklock\":true,\"pid\":${BASH_PID},\"cwd\":\"$(pwd)\"}"  >&3
    echo "" >&3
    ql_node_receiver <&3 | ql_conditional_release &

}

我想让它变得通用——我不想将我写入文件描述符的内容硬编码,而是想return它给调用者;在 Bash 中可能吗?

改为:

ql_connect(){
   port_file="$HOME/.quicklock/server-port.json"

   my_str=$(cat "$port_file");
   typeset -i my_num="${my_str:-"1"}"

    exec 3<>"/dev/tcp/localhost/$my_num"  # persistent file descriptor

    exit_code=$?

    if [[ ${exit_code} -ne 0 ]]; then
      echo "quicklock: could not connect.";
      return 1;
    fi

  return &3; # return reference

}

但显然这是行不通的 - 如何做到这一点?

您不需要 return 任何类型的特殊引用类型。假设 bash 4.1 或更新版本,您可以让 shell 自动分配一个可用的 FD 号码,然后进行间接分配以将其存储在调用者指定的变量中:

# accept variable name to store FD in as an argument
ql_connect() {
  local _qlfd _fd_var=
  exec {_qlfd}<>"/dev/tcp/localhost/$(<~/.quicklock/server-port)" || return
  printf -v "$_fd_var" %s "$_qlfd"
}

if ql_connect qlfd; then
  echo "hello" >&$qlfd
fi

与bash3相比,让用户显式分配一个FD比较好:

ql_connect() {
  local eval_str
  printf -v eval_str \
    'exec %q<>%q\n' "$fd_num" "/dev/tcp/localhost/$(<~/.quicklock/server-port)"
  eval "$eval_str"
}
if ql_connect 3; then
  echo "hello" >&3
fi