【问题标题】:Why does my menu with select fail the first time?为什么我的选择菜单第一次失败?
【发布时间】:2016-02-08 17:04:05
【问题描述】:

我尝试使用内置的 select 语句通过一个简单的菜单来回答 another SO question。代码显示来自/etc/passwd 的名称,并让您通过提供数字来选择名称:

PS3="Enter a number: "
select name in $(cut -d: -f1 /etc/passwd) ; do
   if [ -n "${name}" ]; then
      break
   fi
   echo "Sorry, please enter a number as shown."
done
echo "Entry from passwd is: ${name}"

除了第一次外,一切正常。当您第一次给出正确答案时,它会要求您再试一次。
我试图获得第一次更详细的解释,但我无法获得可复制的烹饪书。当您将此代码复制粘贴到服务器上并给出正确答案时,您可能会遇到同样的问题。当您重复命令(从历史记录或新粘贴)时,代码现在显示问题。我尝试通过注销并登录(有时可以)或重新启动来再次解决问题。
我尝试了不同的方法在其他情况下重现问题(使用不同的变量名、取消设置变量、使用带有select name in $(echo One; sleep 1; echo Two; sleep 2; echo Three; sleep 1); 的慢速值列表并打开一个新的 shell。

我用select 搜索了其他示例,但在https://stackoverflow.com/a/16750755/3220113https://askubuntu.com/a/1716 等其他帖子中找不到线索。

我尝试通过同步来修复我的代码,这似乎是一种解决方法:

PS3="Enter a number: "
select name in $(cut -d: -f1 /etc/passwd) ; do
   # is sync needed here?
   sync
   if [ -n "${name}" ]; then
      break
   fi
   echo "Sorry, please enter a number as shown."
done
echo "Entry from passwd is: ${name}"

当我包含同步命令时,我无法重现错误。同步真的是一个有效的补丁吗?为什么我需要这个?

我不需要其他方式来编写菜单。我已经找到了图形对话框Dialog from bash script,并正在寻找一个简单的替代我自己过于复杂的https://unix.stackexchange.com/a/115371/57293

【问题讨论】:

  • sync 用于将缓冲区刷新到文件中,与shell变量无关。
  • 我无法重现该问题。它第一次对我有用。 ideone.com/ogpver
  • 好的,我可以通过将命令粘贴到交互式外壳中来重现它,而不是在脚本中运行它们。

标签: bash menu


【解决方案1】:

仅当您以交互方式而不是在脚本中键入命令时才会出现此问题。原因是您在select 行之后键入的行被用作对提示的响应。由于if 不在菜单中,所以会报错。然后它不会执行if 命令,因为它被读取为对提示的响应。

在脚本中这不是问题,因为脚本中的命令不用作标准输入。

【讨论】:

  • 粘贴是一个神奇的词。而不是粘贴 select name in $(cut -d: -f1 /etc/passwd) ; do 2 ; if [ -n "${name}" ]; then break; fi; echo "Sorry, please enter a number as shown."; done; echo "Entry from passwd is: ${name}" 而是带有换行符的东西。 2 试图粘贴 2 作为答案,但首先选择读取输入,然后 bash 报告 2 不是命令。
猜你喜欢
  • 2018-06-06
  • 1970-01-01
  • 2012-12-06
  • 2020-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-16
  • 1970-01-01
相关资源
最近更新 更多