简体   繁体   中英

Using a pipe inside a for loop. How do I preserve the value of the variable inside the for loop

I've been stuck for quite some time with the following code. It works but the variable loses the value that was set during the iterations.

I have the following code

  mistakes=0
  entered_chars=()


 word_length=0
 answer=""
 answer_guess=""


checkIfLetterInsideWord(){

exists=0
letter=$2

    word_array=`echo $1 | grep -o . `;

for (( i=1; i <= $word_length; i++))
    do
       if [[ "${1:$i-1:1}" = ${letter} ]]; then

          exists=1

          answer_guess=$(echo $answer_guess | sed "s/-/${letter}/{i}" )

       fi

 done

 echo $exists

}

askUserInput(){

    answer=$answer
    echo $answer
    echo "Please type a letter"
    read user_input


    if [ ! -z $user_input ]; then

    user_input=$(echo $user_input | tr '[:upper:]' '[:lower:]')

     if [ $(checkIfAlreadyEntered "$user_input") -eq 0 ]; then

        if [ $(checkIfLetterInsideWord $answer $user_input) -eq 0 ]; then 
        mistakes=$((mistakes + 1)); fi

        echo "Current mistake count; $mistakes "

        entered_chars+=($user_input)

    else
        echo "Char has already been entered"
    fi
else
    echo "You haven't entered any input!"
fi

}


guessTheWord() {

answer=$OPTARG
word_length=$(printf $answer | wc -m)

temp=$(echo $answer | sed 's/\(.\)/\1 /g')
array=($temp)


echo "The chosen word is $word_length long" 

gameOngoing=true


      for(( i=1; i<=$word_length; i++)) do
            answer_guess="$answer_guess-"
     done



while $gameOngoing
 do

echo $answer_guess

askUserInput $answer    



done




 }

I want to preserve the value of the variable answer_guess. I understand that it loses the value because of the usage of a pipeline inside the loop but I don't know to approach this problem.

The problem has nothing do to with the pipe. Rather, it is that you call checkIfLetterInsideWord inside a command-substitution ( $(...) ). Command substitution executes in a subshell so environment changes in the function will not persist.

It would be better to rewrite checkIfLetterInsideWord so that it returns an exit status. Something like:

if [[ $exists ]]; then
  return 0 # Success
else
  return 1 # Failure
end

Then you could simply call it without worrying about a subshell:

if checkIfLetterInsideWord "$answer" "$user_input"; then
  # letter is in word
else
  # letter is not in word
fi

There are other issues with the code. I've limited this answer to the question about preserving the value of variables.

answer_guess=$(echo $answer_guess | sed "s/-/${letter}/{i}" )

replace the - with .

so your code becomes

answer_guess=$(echo $answer_guess | sed "s/./${letter}/{i}" )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM