首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Shell:以参数作为函数参数传递函数

Shell:以参数作为函数参数传递函数
EN

Stack Overflow用户
提问于 2019-07-11 10:11:13
回答 1查看 291关注 0票数 1

我正在编写一个shell程序来自动化我的Arch (强制性的顺便说一句)安装。为了使其更具交互性,我构建了以下功能:

代码语言:javascript
复制
  # READYN
  #   ARGS:
  #   - Yes/no question
  #   - Command to run if yes
  #   - Command to run if no
  #
  #   Prompts the user with a yes/no question (with precedence for yes) and
  #   run an order if the answer is yes or another if it's no.

readyn () {
  while :
  do
    local yn;

    printf "%s? [Y/n]: " "$1";
    read yn;

    if [[ "$yn" =~ ^([yY][eE][sS]|[yY])?$ ]]; then
      $2;
      break;
    elif [[ "$yn" =~ ^([nN][oO]|[nN])+$ ]]; then
      $3;
      break;
    fi
  done
}

--我成功地将作为参数传递给"echo Hello World!"并运行它。我还传递了另一个函数。例如:

代码语言:javascript
复制
yayprompt () {
  printf "yay is required to install %s.\n" "$1"
  readyn "Install yay, the AUR manager" "yayinstall" ""
}

如果是,这将调用yayinstall,如果不,则不做任何操作。

我的问题在于更复杂的函数,这些函数被作为参数传递,但它们要么不被识别,要么在它们不应该被识别时运行。问题在于以下功能:

代码语言:javascript
复制
  # MANAGEPGK
  #   ARGS:
  #   - Package name
  #   - Package variable
  #   - Yay required
  #
  #   Checks if the package is added to the pkglist to either add or remove it.
  #   If yay is required to install it, it prompts the user whether they wish
  #   to install yay or don't install the package (if yay is not installed).
  #   This functions DOES NOT prompt any installation options on the user. To
  #   do this, use PROMPTPKG.

managepkg () {
  local pkgvar=$2

  if [ $pkgvar == 0 ]; then
    if [ $3 == 1 ] && [ $yay == 0 ]; then
      yayprompt;
    fi

    if [ $3 == 0 ] || [ $yay == 1 ]; then
      addpkg "$1";
      pkgvar=1;
    fi
  else
    rmpkg "$1";
    pkgvar=0;
  fi

  echo "$pkgvar";
}

要使它正常工作,就必须(或者至少我不得不)这样称呼它:

代码语言:javascript
复制
dewm_cinnamon=$(managepkg cinnamon $dewm_cinnamon 0)

现在,我试图将它作为参数传递给readyn,但这些输出取决于格式(我总是将yes回答为空字符串:

单引号:

代码语言:javascript
复制
readyn "Install gaps" \
       'dewm_i3gaps=$(managepkg i3-gaps $dewm_i3gaps 0)' \
       'dewm_i3=$(managepkg i3-wm $dewm_i3 0)';
代码语言:javascript
复制
Install gaps? [Y/n]:
./architup.sh: line 341: dewm_i3gaps=$(managepkg: command not found

双引号:

代码语言:javascript
复制
readyn "Install gaps" \
       "dewm_i3gaps=$(managepkg i3-gaps $dewm_i3gaps 0)" \
       "dewm_i3=$(managepkg i3-wm $dewm_i3 0)";
代码语言:javascript
复制
Install gaps? [Y/n]: 
./architup.sh: line 341: dewm_i3gaps=1: command not found

随附的美元:(这个命令运行两个命令,如cat pkglist中所示)

代码语言:javascript
复制
readyn "Install gaps" \
       $(dewm_i3gaps=$(managepkg i3-gaps $dewm_i3gaps 0)) \
       $(dewm_i3=$(managepkg i3-wm $dewm_i3 0));
代码语言:javascript
复制
Install gaps? [Y/n]: 
Install compton? [Y/n]: ^C

Documents/Repositories/architup took 5s 
➜ cat pkglist
i3-gaps
i3-wm

我应该使用什么语法让readyn只运行基于用户输入的一个命令?

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-11 10:23:44

函数参数只是字符串。更好的设计是让readyn返回true (0)表示“是”,否则返回false,并让调用代码在此基础上实现任何条件逻辑。

代码语言:javascript
复制
readyn () {
    read -p "$@"
    case $REPLY in
        [Yy] | [Yy][Ee][Ss]) return 0;;
    esac
    return 1
} 

readyn "Are you ready San Antonio?" &&
rock and roll

if readyn "Let me hear you say yeah"; then
    echo "Let's go!"
else
     echo "If you feel mellow, get outta here"
fi

(向各地的摇滚音乐会道歉,)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56986826

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档