If you are writing a Bash shell script, you should read command-line arguments into an array for some time. This allows us to process any number of arguments provided when the script is run. This makes the script adaptable to different use cases. Instead of dealing with fixed variables like $1, $2, $3, etc., you can work with any number of arguments more dynamically using bash for loop or bash while loop, depending upon your needs. Arrays make it simple to loop through each argument and perform operations on them,Β whether basic printing or complex processing. Bash provides a mapfile (readarray command) internal built-in command to read lines from a file into an array variable. Let us see how to use mapfile to read all command line arguments into an array.

mapfile command syntax and examples

As I mentioned earlier, mapfile is a built-in Bash command. It reads lines from standard input (keyboard) into an indexed array variable. Here are some basic examples of how to use mapfile. Let us print three lines using echo command or printf command

echo -n -e "Foo\nBar\nTest\n"
## OR
printf "Foo\nBar\nTest\n"

Here is how to put those three lines into an array called my_lines:

command | mapfile -t my_lines
echo -n -e "Foo\nBar\nTest\n" | mapfile -t my_lines
mapfile my_lines < <(printf "Foo 1\nBar 2\nDemo 3\n")

Of course, you can read line from a file into an array as follows:

mapfile -t my_lines < /path/to/my/file.txt
mapfile -t my_password_file < /etc/passwd
# OR #
mapfile my_password_file < /etc/passwd

After running these commands, you can access the elements of the array my_password_file” like any other indexed array in Bash. For example, to print first and second line, run:

echo "${my_password_file[0]}"
echo "${my_password_file[1]}"
echo "${my_lines[0]}"

OR dump everything:

echo "${my_password_file[@]}"
echo "${my_lines[@]}"

For you can print first five lines:

for i in {0..4}
do 
  echo "${my_password_file[$i]}"
done
Linux and Unix mapfile command syntax and examples

Say hello to $@ parameter

In Bash scripts, $@ is a special shell parameter that expands to represent all command-line arguments passed to the script or function. For example:

#!/bin/bash
# read all args into an array called cmd_args
cmd_args=("$@")
 
# now print everything
for arg in "${cmd_args[@]}"
do
  echo "$arg"
done

Now you can run this script like this:
$ ./my_array_demo_script.sh foo bar
$ ./my_array_demo_script.sh "this is a test" foo bar 1000

Sample outputs:

this is a test
foo
bar
1000

A Bash Script to Read All Command Line Arguments into an Array

#!/bin/bash
set -e
 
cmds=("$@") # array name
cmd_before_last_item=""
 
# This will sort all my CLI args stored in the "${cmds[@]}",
# into an array called 'sorted_cmds'
mapfile -t sorted_cmds < <(printf '%s\n' "${cmds[@]}" | sort)
 
# Calculate the index of the second-to-last element
second_to_last_index=$((${#sorted_cmds[@]} - 2))
 
# Check if there's at least a second-to-last element
if [[ $second_to_last_index -ge 0 ]]; then
    # Print the second-to-last element
    cmd_before_last_item="${sorted_cmds[$second_to_last_index]}"
fi
 
# Build short tag for each input 
for c in "${sorted_cmds[@]}"
do
    [ "$c" == "$cmd_before_last_item" ] && add_modifer_word="or " || add_modifer_word=""
    echo -n "\"[nixcmd name='$c' txt='${c},']\" $add_modifer_word"
done
echo

Run it as follows:
$ ./quickcmdbuilder.sh more less cat bat
This will product shorcut codes for my CMS:

"[nixcmd name='bat' txt='bat,']" "[nixcmd name='cat' txt='cat,']" "[nixcmd name='less' txt='less,']" or "[nixcmd name='more' txt='more,']"

Summing up

This script is designed to handle unlimited arguments while preserving spaces within each argument. It can sort and perform other operations before generating the final outputs. The data is stored in an array, allowing you to pass all the original arguments to nested functions or other commands within your script if required. The mapfile makes it really easier to read all command line args into an array. It has many more options. You can read its help page using the man command or help command:
$ man bash
$ help mapfile

πŸ₯Ί Was this helpful? Please add a comment to show your appreciation or feedback.

nixCrat Tux Pixel Penguin
Hi! 🀠
I'm Vivek Gite, and I write about Linux, macOS, Unix, IT, programming, infosec, and open source. Subscribe to my RSS feed or email newsletter for updates.

0 comments… add one

Leave a Reply

Your email address will not be published. Required fields are marked *

Use HTML <pre>...</pre> for code samples. Your comment will appear only after approval by the site admin.