Issue
I have the following bash script:
#!/bin/bash
r () {
read -rp "Give text: " var
}
m () {
if [ -n "$2" ] ; then
echo " && $1"
g='1'
else
echo "$1"
g=''
fi
}
r
t1="$g"
a="$(m "$var" "")"
r
t2="$g"
b="$(m "$var" "$t1")"
r
c="$(m "$var" "$t2")"
echo "$a$b$c"
I want to run this script with a combination of the following input:
Enter "fire" or just hit enter to leave empty.
Enter "water" or just hit enter to leave empty.
Enter "air" or just hit enter to leave empty.
By that I mean just the words or nothing.
Currently when I run this, I get the following possible combinations:
firewaterair
firewater
waterair
fire
water
air
What I am trying to achieve is these possible outcomes:
fire && water && air
fire && water
water && air
fire
water
air
I tried several things but not sure why this script does not work as intended. Help is much appreciated.
Solution
Using single-letter variables obscures your code. I can understand that r
probably stands for "read", but what's the purpose exactly of the function you simply called m
? Giving it a useful name also helps yourself understand your code. But more fundamentally, a function should ideally not have any side effects outside of its own scope.
A better design altogether is to accept a list of words on the command line, and put them in an array.
#!/bin/bash
subsequences () {
local array=("$@")
local this=${array[0]}
local tail
echo "$this"
[ "${#array[@]}" -eq 1 ] && return
subsequences "${array[@]:1}" |
while IFS='' read -r tail; do
printf '%s && %s\n' "$this" "$tail"
echo "$tail"
done
}
subsequences "$@"
If you saved this as subsequences
(in a directory in your PATH
, and chmod +x subsequences
), you'd run this like
subsequences fire water air
Demo: https://ideone.com/jfBwTr
The output order is different than in your example; if the order is significant, it should not be hard to refactor this (though then perhaps an iterative solution would be better than a recursive one).
Answered By - tripleee Answer Checked By - Gilberto Lyons (WPSolving Admin)