从Bash函数返回文件描述符

时间:2018-04-20 20:53:30

标签: bash shell file-descriptor

我现在有这个Bash函数,它是“硬编码”将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 &

}

我想把它变成通用的 - 而不是硬编码我写入文件描述符的内容,我想将它返回给调用者;在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

}

但显然这不起作用 - 如何做到这一点?

1 个答案:

答案 0 :(得分:3)

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

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

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

相比之下,使用bash 3,让用户明确指定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