I prefer to program my bash scripts as procedurally as possible. One of the difficulties that I encountered when trying to do this occurs when passing array data between functions, a task that is not supported in bash.
As an example, it is trivial to start an array in bash with several hard-coded quotes, each of which may contain several words:
declare -a LINES=( "Hello there" "loyal user" )
echo "Line 0: '${LINES[0]}'"
echo "Line 1: '${LINES[1]}'"
However, replacing such hard-coded values with a function output does not work so well:
getLines() {
echo "\"Hello there\" \"loyal user\""
}
local LINE_STR=$( getLines )
declare -a LINES=( ${LINE_STR} )
echo "Line 0: '${LINES[0]}'"
echo "Line 1: '${LINES[1]}'"
I tried almost every permutation of allowed bash statements to overcome this problem. One approach that seems to work well is "eval":
local LINE_STR=$( getLines )
eval declare -a LINES=( ${LINE_STR} )
echo "Line 0: '${LINES[0]}'"
echo "Line 1: '${LINES[1]}'"
However, this approach is related to security issues, as shown here:
emulateUnsafeInput() {
echo "\"\`whoami\` just got haxxored\" \"Hahaha!\""
}
local LINE_STR=$( emulateUnsafeInput )
eval declare -a LINES=( "${LINE_STR}" )
echo "Line 0: '${LINES[0]}'"
echo "Line 1: '${LINES[1]}'"
'read -a' , , "" -, , script.
"eval"? script, , :
#!/bin/bash
getLines() {
echo "\"Hello there\" \"loyal user\""
}
emulateUnsafeInput() {
echo "\"\`whoami\` just got haxxored\" \"Hahaha!\""
}
execute() {
(
echo Test 01
declare -a LINES=( "Hello there" "loyal user" )
echo "Line 0: '${LINES[0]}'"
echo "Line 1: '${LINES[1]}'"
);(
echo Test 02
local LINE_STR=$( getLines )
declare -a LINES=( ${LINE_STR} )
echo "Line 0: '${LINES[0]}'"
echo "Line 1: '${LINES[1]}'"
);(
echo Test 03
local LINE_STR=$( getLines )
declare -a LINES=( "${LINE_STR}" )
echo "Line 0: '${LINES[0]}'"
echo "Line 1: '${LINES[1]}'"
);(
echo Test 04
local LINE_STR=$( getLines )
eval declare -a LINES=( ${LINE_STR} )
echo "Line 0: '${LINES[0]}'"
echo "Line 1: '${LINES[1]}'"
);(
echo Test 05
local LINE_STR=$( getLines )
eval declare -a LINES=( "${LINE_STR}" )
echo "Line 0: '${LINES[0]}'"
echo "Line 1: '${LINES[1]}'"
);(
echo Test 06
local LINE_STR=$( getLines )
declare -a LINES=( $( echo ${LINE_STR} ) )
echo "Line 0: '${LINES[0]}'"
echo "Line 1: '${LINES[1]}'"
);(
echo Test 07
local LINE_STR=$( getLines )
declare -a LINES=( $( echo "${LINE_STR}" ) )
echo "Line 0: '${LINES[0]}'"
echo "Line 1: '${LINES[1]}'"
);(
echo Test 08
local LINE_STR=$( getLines )
declare -a LINES=( $( eval echo ${LINE_STR} ) )
echo "Line 0: '${LINES[0]}'"
echo "Line 1: '${LINES[1]}'"
);(
echo Test 09
local LINE_STR=$( getLines )
declare -a LINES=( $( eval echo "${LINE_STR}" ) )
echo "Line 0: '${LINES[0]}'"
echo "Line 1: '${LINES[1]}'"
);(
echo Test 10
local LINE_STR=$( emulateUnsafeInput )
eval declare -a LINES=( ${LINE_STR} )
echo "Line 0: '${LINES[0]}'"
echo "Line 1: '${LINES[1]}'"
);(
echo Test 11
local LINE_STR=$( emulateUnsafeInput )
eval declare -a LINES=( "${LINE_STR}" )
echo "Line 0: '${LINES[0]}'"
echo "Line 1: '${LINES[1]}'"
);(
echo Test 12
local LINE_STR=$( emulateUnsafeInput )
declare -a LINES=( $( eval echo ${LINE_STR} ) )
echo "Line 0: '${LINES[0]}'"
echo "Line 1: '${LINES[1]}'"
);(
echo Test 13
local LINE_STR=$( emulateUnsafeInput )
declare -a LINES=( $( eval echo "${LINE_STR}" ) )
echo "Line 0: '${LINES[0]}'"
echo "Line 1: '${LINES[1]}'"
)
}
execute