Thursday, February 8, 2024

[SOLVED] How to use variable from previous function iteration in bash script

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)