【问题标题】:Bash : read + completionBash:阅读+完成
【发布时间】:2016-04-09 18:46:18
【问题描述】:

我是 bash 的新手,我正在尝试编写一个 bash 脚本来保存用户的输入(一些标签),以帮助这个用户我希望只允许基于我个人的预定义标签列表而不是关于常见的 TAB 文件补全(文件夹中的文件名)。

predefinedtags=(one two three four five)
echo "enter tags (separate multiple values by space)"
read -e tags
echo $tags

我希望在read 输入期间,用户可以按TAB 来完成带有预定义标签列表的单词。我认为这是一个常见的问题和方法,但我没有找到一个好的方法。我发现一些帖子对我来说有点太复杂了,他们似乎解释了这不是一个那么简单的问题。我什至不知道这是否可能。

Changing tab-completion for read builtin in bash

bash and readline: tab completion in a user input loop?

你有什么想法吗?或者可能有一种完全不同的方式来做到这一点?感谢您的帮助。

【问题讨论】:

  • 这可能有点棘手,因为第一个单词作为命令完成,后面的单词作为该命令的参数完成。您可以将每个标签配置为将其视为一个命令,该命令将任何标签作为参数,但我不确定如何防止第一个单词作为一个标签以外的任何内容完成。

标签: bash


【解决方案1】:

在第二部分,有一个简单的版本。

试试这个经过测试的版本:

#!/bin/bash --

reade () {
  tmpdir=$(date "+/tmp/%Y%m%d%H%M%S$$")
  mkdir "${tmpdir}"
  for ptag in "${predefinedtags[@]}" ; do
    touch "${tmpdir}"/"${ptag}"
  done
  readetags=$(cd "${tmpdir}" || printf "internal error" ; read -re usertags ; printf "%s" "${usertags}")
  rm -rf "${tmpdir}" 2>/dev/null >/dev/null
  eval "${1}"=\"\$\{readetags\}\"
}
predefinedtags=(one two three four five)
printf "enter tags (separate multiple values by space)\n"
reade tags
printf "%s\n" "${tags}"

这可能看起来很奇怪,但很有趣! (并用 shellcheck 检查)

它定义了一个新的 reade 函数,该函数创建一个具有唯一名称的临时目录,并为 predefinedtags 中的每个元素创建一个空文件。它将当前目录更改为新的临时目录并运行 read -e

TAB 键将按预期工作。

最终用户输入的标签全部赋值给tags

注意不要在预定义的标签中插入带有空格或特殊字符(如 '" 等)的标签。

----

第二部分

您可能想要定义一个已经包含空文件(预定义标签)的configuration 目录,而不是创建和删除一个临时目录。

在下面的脚本中将/path/to/configuration 替换为configuration 目录的真实路径名:

#!/bin/bash --

printf "enter tags (separate multiple values by space)\n"
tags=$(cd /path/to/configuration || printf "internal error" ; read -re usertags ; printf "%s" "${usertags}")
printf "%s\n" "${tags}"

测试(TAB 键按下的地方):

$ ls configuration/
five  four  one  three  two

$ ./script.sh
enter tags (separate multiple values by space)
TAB
five   four   one    three  two
five ten
five ten

$ touch configuration/cat
$ ls configuration/
cat  five  four  one  three  two

$ ./script.sh
enter tags (separate multiple values by space)
TAB
cat    five   four   one    three  two
cat hello
cat hello

【讨论】:

  • 您好,谢谢您的回答,我想到了这种解决方案,我喜欢您这样做的方式。这对我来说可能是一个非常好的临时和有效的解决方案,而不是基于我的数组的“真正”完成。我必须找到管理带有空格的标签的方法,因为我需要使用多字标签(作者、标题等)来完成。感谢您提供此解决方案,如果有人对基于数组的完成有更多了解,请随时在此处编写信息。
猜你喜欢
  • 1970-01-01
  • 2011-06-17
  • 2017-12-11
  • 2011-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-21
相关资源
最近更新 更多