Accept Multiple Lines of Input in a Bash Script

Accept multiple lines of input in a bash script

Yes, you can: use readarray:

printf "Enter the domain names: "
readarray -t arr
# Do something...
declare -p arr

The last line above just documents what bash now sees as the array.

The user can type or copy-and-paste the array names. When the user is done, he types Ctrl-D at the beginning of a line.

Example:

$ bash script
Enter the domain names: domain1.com
domain2.com
domain3.com
domain4.com
declare -a arr='([0]="domain1.com" [1]="domain2.com" [2]="domain3.com" [3]="domain4.com")'

Run linux program from shell script with multi-line input

Prime use case for a here-document:

prog <<EOF
t
3
12
e
EOF

How to read multi-line input in a Bash script?

You just have to decide how much to read.

If this is the only input, you could read until end of file. This is how most UNIX utilities work:

#!/bin/bash
echo "Pipe in certificate, or paste and it ctrl-d when done"
keyvariable=$(cat)

If you want to continue reading things later in the script, you can read until you see a blank line:

#!/bin/bash
echo "Paste certificate and end with a blank line:"
keyvariable=$(sed '/^$/q')

If you want it to feel more like magic interactively, you could read until the script has gone two seconds without input:

#!/bin/bash
echo "Paste your certificate:"
IFS= read -d '' -n 1 keyvariable
while IFS= read -d '' -n 1 -t 2 c
do
keyvariable+=$c
done
echo "Thanks!"

how to read multiline input into an array in bash shell script

Several points to address:

First, don't use Ctrl-C but Ctrl-D to end the input: Ctrl-C will break the script (it sends the SIGINT signal), whereas Ctrl-D is EOF (end of transmission).

To print the array, one field per line, use

printf '%s\n' "${arr[@]}"

Now, the bad way:

arr=( $(cat) )
printf '%s\n' "${arr[@]}"

This is bad since it's subject to word splitting and pathname expansion: try to enter hello word or * and you'll see bad things happen.

To achieve what you want: with Bash≥4 you can use mapfile as follows:

mapfile -t arr
printf '%s\n' "${arr[@]}"

or, with legacy Bash, you can use a loop:

arr=()
while IFS= read -r l; do
arr+=( "$l" )
done
printf '%s\n' "${arr[@]}"

If you want to print each line as it's typed, it's probably easier to use the loop version:

arr=()
while IFS= read -r l; do
printf '%s\n' "$l"
arr+=( "$l" )
done

If you're feeling adventurous, you can use mapfile's callback like so:

cb() { printf '%s\n' "$2"; }
mapfile -t -c1 -C cb arr

Bash multi-line command with input | output

The reason for this happening to me was a unique issue I was having with my IDE .. It was inserting an actual character for a line break rather than just a physical line-break itself. The problem wasn't the syntax I was attempting, rather the inserted characters on save. Thanks to all who thoughtfully answered my question. My original un-escaped syntax was correct to begin with.

Indenting read input when it contains multiple lines

It sounds like the issue is with the way read works. Read echos back keystrokes and I think perhaps because of stdout buffer it is writtern before the echo statements are flushed.

Using a combo of echo command and the -e argument to read (interactive) fixes this in my testing.

#!/bin/bash
echo "Provide inputs:"
until [[ "$message" = "three" ]]; do
echo -ne "> "
read -e message
myArray+=($message) #Input added to array for later processing
done

BASH - Prompt paste multiple lines of input save to file

You can use this read:

read -rp 'Please enter the details: ' -d $'\04' data

and press ctrl-D on terminal after entering your multiline data.

Check content of data variable by using

declare -p data

Running a bash command with multiple lines of input via ssh

To script a command and send it multiple lines of input you can use a here document.

ldapmodify -h server.example.com -p 1389 -w '1234' -D "cn=Directory\ Manager" -a <<INPUT
dn:ou=test1,dc=example,dc=com
objectclass:top
objectclass:organizationalUnit
ou:test1
INPUT

To do it over SSH, do the same thing, but add the ssh command in front.

ssh user@host.name ldapmodify -h server.example.com -p 1389 -w '1234' -D "cn=Directory\ Manager" -a <<INPUT
dn:ou=test1,dc=example,dc=com
objectclass:top
objectclass:organizationalUnit
ou:test1
INPUT

How to write a script bash to enter multi-line input in jupyter-notebook?

For your particular case, you can simply use semicolon at the end to run it i.e.

!(python --version; \
which python; \
pip --version; \
conda --version; \
which conda) >> config-environment.txt

For general case, you can use %%bash cell magic command to run the cell in bash i.e.

%%bash script magic

Run cells with bash in a subprocess.

%%bash

(python --version
which python
pip --version
conda --version
which conda) >> config-environment.txt

You can also have a look at subprocess python module.

Read command is parsing multiline input

You can just do this while read loop:

u="*
john
dan"
while IFS= read -r user; do
echo "drop user $user"
done <<< "$u"

Output:

drop user *
drop user john
drop user dan


Related Topics



Leave a reply



Submit