Bash 如何避免read命令按空格剪切用户输入的字符串

Bash 如何避免read命令按空格剪切用户输入的字符串,bash,Bash,我编写了一个bash脚本来读取用户的多个输入 命令如下: read -a choice 通过这种方式,我可以将choice变量中的所有输入作为一个数组,以便使用索引提取它们 问题是,当其中一个输入(字符串)中有空格时,如 user1 google.com "login: myLogin\npassword: myPassword" read命令将带引号的字符串拆分为3个单词。如何阻止这种情况发生?bash不处理用户输入中的引号。我唯一能想到的就是使用eval执行数组赋值 IFS= read

我编写了一个bash脚本来读取用户的多个输入 命令如下:

read -a choice
通过这种方式,我可以将
choice
变量中的所有输入作为一个数组,以便使用索引提取它们

问题是,当其中一个输入(字符串)中有空格时,如

user1 google.com "login: myLogin\npassword: myPassword"

read
命令将带引号的字符串拆分为3个单词。如何阻止这种情况发生?

bash
不处理用户输入中的引号。我唯一能想到的就是使用
eval
执行数组赋值

IFS= read -r input
eval "choice=($input)"

不幸的是,这是危险的——如果输入包含可执行代码,它将由
eval

执行。您可以使用制表符而不是空格作为字段分隔符。例如:

 $ IFS=$'\t' read -a choice
value1  value2  a value with many words ## This is typed

 $ echo ${choice[2]}
a value with many words

问候

< P>使用<代码> EVA<代码>的风险,事实上,输入似乎只有两种类型的标记:未引用的和引用的,考虑使用脚本引擎,将所有文本放入适当的格式,这将是易于阅读的。 从示例中不清楚使用了哪些其他引用规则。示例假定可以使用bash@E处理器处理的“标准”转义

下面使用Perl one liner生成制表符分隔的标记(希望原始制表符不能成为输入的一部分,但可以使用其他字符)

input='user1 google.com“登录名:myLogin\n密码:myPassword”
tsv_input=$(perl-e'$=“$ARGV[0]”打印$2//$3,“\t”而(/\s+([^“]*)”)“|”(\s*))/g);“$input”)

如果不想在空格处拆分输入,为什么要使用
read-a
“。它应该有3个参数,但字符串被分成3个部分。3个参数和3个部分之间有什么区别?
read
不处理引号以将内容保留为一个单词。它只使用
$IFS
将其拆分为单词。
input='user1 google.com "login: myLogin\npassword: myPassword"'
tsv_input=$(perl -e '$_ = " $ARGV[0]" ; print $2 // $3, "\t" while ( /\s+("([^"]*)"|(\S*))/g) ;' "$input")
IFS=$'\t' read -d '' id domain values <<< $(echo -e "${tsv_input@E}")
function data_to_tsv {
    # Translate to TSV
    local tsv_input=$(perl -e '$_ = " $ARGV[0]" ; print $2 // $3, "\t" while ( /\s+("([^"]*)"|(\S*))/g) ;' "$1")
    # Process escapes
    echo -n "${tsv_input@E}"
}

input='user1 google.com "login: myLogin\npassword: myPassword"'
IFS=$'\t' read -d '' id domain values <<< $(data_to_tsv "$input")