bash $(函数参数)没有参数

bash no parameters for $(function parameters)

我想创建一个多次使用基本(提示和确认)函数的脚本,当我尝试将 return 设置为任何变量时,该函数会忽略参数

function promp() {
    echo $*
    read response
    echo $response
}
function confirm() {
    echo $*
    read -rp $'(y/N) : ' -ei $'N' key;
    case "$key" in
        [yY][eE][sS]|[yY])
            echo true
            ;;
        *)
            echo false
            ;;
    esac
}

IS_RESPONSE=$(confirm "SOME QUESTION")
STRING_RESPONSE=$(promp "WRITE SOMETHING")
echo $IS_RESPONSE
echo $STRING_RESPONSE

预计:

SOME QUESTION
(y/N) : N
WRITE SOMETHING 
#<< "some text"
false
some text

获得:

(y/N) : N
#<< "some text"
SOME QUESTION false
WRITE SOMETHING some text

我知道问题是函数内的回显是可变数据的一部分,但我想打印出来。

我该怎么做或者哪种方法最好

使用 read 命令中的提示代替 echo:

#!/bin/bash
function promp() {
    read -p "$*"$'\n' response
    echo $response
}
function confirm() {
    read -rp "$*"$'\n'"(y/N) : " -ei $'N' key
    case "$key" in
        [yY][eE][sS]|[yY])
            echo true
            ;;
        *)
            echo false
            ;;
    esac
}

IS_RESPONSE=$(confirm "SOME QUESTION")
STRING_RESPONSE=$(promp "WRITE SOMETHING")
echo $IS_RESPONSE
echo $STRING_RESPONSE

结果:

$ ./test.sh
SOME QUESTION
(y/N) : N
WRITE SOMETHING
something
false
something

您的函数是在 command substitution 的上下文中调用的:

STRING_RESPONSE=$(promp "WRITE SOMETHING")

因此promp "WRITE SOMETHING"命令的标准输出附加到变量赋值的上下文中。

但是,标准错误仍然附加到终端。如果您将 echo 的输出重定向到文件描述符 2,那么输出将在 echo 被调用时显示给用户,例如:

function promp() {
    echo >&2 "$*"
    read response
    echo "$response"
}

另一种方法是使用 -p 选项:read -p "Your prompt: "prints the prompt string to the standard error

全局变量在 shell 脚本中比其他语言更常用;如果您的代码变得太复杂而无法轻松管理全局变量,那么可能是时候切换到另一种语言了。

# This is probably too trivial to even define as a function.
promp() {
    read -p "" ""
}

confirm() {
    printf '%s\n' "" >&2
    read -rp $'(y/N) : ' -ei N key
    case "$key" in
        [yY][eE][sS]|[yY])
            key=true
            ;;
        *)
            key=false
            ;;
    esac
    printf -v "" "$key"
}

# No expensive command substitutions needed;
# read and printf -v will both populate a global variable
# named by an argument.
confirm "SOME QUESTION" IS_RESPONSE
promp "WRITE SOMETHING" STRING_RESPONSE
echo "$IS_RESPONSE"
echo "$STRING_RESPONSE"

使用@123、@ruslan 和@chepner 的回答我做了这个:

function prompt() {
  printf '%s\n' "" > /dev/tty
  read ""
  echo $response
}
function confirm() {
  local key
  printf '%s\n' "" > /dev/tty
  read -rp $'(y/N) : ' -ei $'N' key;
  case "$key" in
    [yY][eE][sS]|[yY]|[sS][iIíÍ]|[sS])
      key=true
      ;;
    *)
      key=false
      ;;
  esac
  if [[ "" ]]; then
    printf -v "" "$key"
  else
    echo "$key"
  fi
}

函数执行的快速测试

$(confirm "SOME QUESTION") && echo "it works"
confirm "SOME OTHER QUESTION" IS_RESPONSE
prompt "WRITE SOMETHING" STRING_RESPONSE
echo $IS_RESPONSE
echo $STRING_RESPONSE