Liu
Liu

Reputation: 67

How to avoid the read command cutting the user input which is a string by space

I wrote a bash script to read multiple inputs from the user Here is the command:

read -a choice

In this way, I can put all the inputs in the choice variable as an array so that I can extract them using an index.

The problem is that when one of the inputs, which is a string has space in it, like

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

the read command will split the quoted string into 3 words. How can I stop this from happening?

Upvotes: 0

Views: 171

Answers (3)

dash-o
dash-o

Reputation: 14424

Given risk of using eval, and the fact the input seems to have only two types of tokens: unquoted, and quoted, consider using scripting engine that will put all text into proper format that will be easy to read.

It's not clear from the example what other quoting rules are used. Example assume 'standard' escaped that can be processed with bash @E processor.

The following uses Perl one liner to generate TAB delimited tokens (hopefully, raw tabs can not be part of the input, but other character can be used instead).

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}")

Or using a function to get more readable code

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")

Upvotes: 0

Matias Barrios
Matias Barrios

Reputation: 5056

You can use a tab instead of space as a field delimiter. For instance :

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

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

Regards!

Upvotes: 0

Barmar
Barmar

Reputation: 780673

bash doesn't process quotes in user input. The only thing I can think of is to use eval to execute an array assignment.

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

Unfortunately this is dangerous -- if the input contains executable code, it will be executed by eval.

Upvotes: 1

Related Questions