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

时间:2017-06-08 18:50:36

标签: linux bash shell ubuntu devops

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

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

我知道问题是函数内的回声​​是变量数据的一部分,但我希望打印出来。

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

4 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:0)

使用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

答案 3 :(得分:0)

使用@ 123,@ruslan和@chepner的答案我做了这个:

function prompt() {
  printf '%s\n' "$1" > /dev/tty
  read "$2"
  echo $response
}
function confirm() {
  local key
  printf '%s\n' "$1" > /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 [[ "$2" ]]; then
    printf -v "$2" "$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