2015-05-22 15 views
-3

我想用多选的脚本创建菜单。 喜欢:在脚本外壳中选择多个选项?

1) 

2) 

3) 

4) 

5) 

我可以在相同的时间选择1和3,和5。

+0

用户如何进入他的选择? '1 [ENTER] 3 [ENTER] 5 [ENTER]运行[ENTER]或[1,3,5 [ENTER]'?解析他的回应并调用正确的功能。 –

+0

用户可以这样输入他的选择:1,2,3 [ENTER] –

+1

为了回答以及未来读者的好处:如果答案解决了您的问题,请点击旁边的大复选标记以接受它。它;如果您找到答案_helpful_,请点击向上箭头图标(您可以同时执行这两个操作),然后点击投票。请参阅[相关帮助中心文章](http://stackoverflow.com/help/someone-answers)。如果您的问题尚未得到充分解答,请提供反馈。 – mklement0

回答

4

bashselect复合命令不直接支持多种选择,但你仍然可以基地您的IT解决方案,采取的,无论用户输入被记录在特殊$REPLY变量的事实优势:

#!/usr/bin/env bash 

choices=('one' 'two' 'three' 'four' 'five') # sample choices 
select dummy in "${choices[@]}"; do # present numbered choices to user 
    # Parse ,-separated numbers entered into an array. 
    # Variable $REPLY contains whatever the user entered. 
    IFS=', ' read -ra selChoices <<<"$REPLY" 
    # Loop over all numbers entered. 
    for choice in "${selChoices[@]}"; do 
    # Validate the number entered. 
    ((choice >= 1 && choice <= ${#choices[@]})) || { echo "Invalid choice: $choice. Try again." >&2; continue 2; } 
    # If valid, echo the choice and its number. 
    echo "Choice #$((++i)): ${choices[choice-1]} ($choice)" 
    done 
    # All choices are valid, exit the prompt. 
    break 
done 

echo "Done." 

至于如何select命令正常作品,具有选择:

  • 运行man bash并在标题为“复合命令”
  • 寻找一个注解的示例,请参见this answer

答案实现定制逻辑如下:

  • select命令,dummy的指定的目标变量,将被忽略,并且$REPLY变量来代替,因为击设置它无论用户输入什么(未验证)。
  • IFS=', ' read -ra selChoices <<<"$REPLY"标记化的用户输入的值:
    • 它通过一个here-string<<<)进料至使用逗号和空间(,<space>)作为[内部]字段分隔符的实例的read命令
    • IFS=...
      • 请注意,作为副作用,用户可以使用空格来分隔他们的选择。
    • 并将得到的标记存储为数组的元素(-aselChoices; -r只是关闭\字符的解释。在输入
    • for choice in "${selChoices[@]}"; do在所有令牌上循环,即用户选择的单个号码。
    • ((choice >= 1 && choice <= ${#choices[@]})) || { echo "Invalid choice: $choice. Try again." >&2; continue 2; }确保每个令牌都是有效的,即它是介于1和所呈现的选择计数之间的数字。使用arithmetic expansion$((...))
  • echo "Choice #$((++i)): ${choices[choice-1]} ($choice)"输出每个选择和选择号码
    • 与正在运行的索引(i),其递增(++i)前缀 - 因为在算术上下文的可变默认为0 ,第一个指数产出将是1;
    • 后面跟着${choices[choice-1]},即由输入的数字表示的选择串,递减1,因为Bash阵列是基于0的;请注意0​​在数组下标中不需要$前缀,因为在算术上下文中评估下标(就像在$((...))内部一样),如上所述。
    • 终止于($choice),括号内为选定的数字。
  • break需要退出提示;默认情况下,select将继续提示。
+0

其工作非常感谢你,但我想了解你是如何做到的? 并再次感谢你;) –

+0

@zakariagatter:我的荣幸;看到我的更新。 – mklement0