0

Following script statement for user input is nested in while loop under if block but it doesn't work and is being skipped. How do I get user input to work?

exec 3<&0 && read -p 'Enter your answer: ' uservar <&3

FILE="hostnames.txt"
echo $(sudo chmod +777 $FILE)
echo "Step 1. Checking if file with hostnames exists."

#exec 3<&0

if [ -f "$FILE" ]
then
  echo "PASSED: File hostnames.txt does exist." && echo ""
  while IFS= read -r hostname;
    do
     echo "Step 2. Checking Grph mgmt_con_ip4 exists for $hostname"
     mgmt_con_ip4="$(echo "$(llama-grph node show $hostname | grep mgmt_con_i$
     echo "Grph has management IPv4 address: $mgmt_con_ip4"
     if [ -z $mgmt_con_ip4 ]
       then
         echo "PASSED: Grph mgmt_con_ip4 == NULL" && echo ""
       else
         echo "FAILED: Grph mgmt_con_ip4 == NOT NULL" && echo ""
         echo "$(ipam --format json get-cidr-parent $mgmt_con_ip4)" && echo ""
         echo "WARNING: OOB networks shouldn't have $mgmt_con_ip4 IPv4 addres$
         exec 3<&0 && read -p 'Enter your answer: ' uservar <&3
     fi
  done < $FILE
fi


5
  • why? your user input question seem like it should be done outside of the while loop - you don't want it to ask for every line of $FILE, do you? It doesn't even seem to be asking a question, anyway - just stating "FAILED" and "WARNING" and then prompts the user for an answer - an answer to what? there's no question there.
    – cas
    Commented Mar 31, 2023 at 1:32
  • Other comments: 1. using sudo chmod 777 to brute-force RWX permissions is a bad idea. If the user running the script should have permission then it should be set up that way in the first place. 2. quote your variables - e.g. [ -z $mgmt_con_ip4 ] will be a syntax error if mgmt_con_ip4 is empty because it will expand to just [ -z ]. use [ -z "$mgmt_con_ip4" ] instead. See also $VAR vs ${VAR} and to quote or not to quote
    – cas
    Commented Mar 31, 2023 at 1:35
  • @cas Note: [ -z ] is not a syntax error. It should be equivalent to [ -n -z ] and this is true, like [ -z "$mgmt_con_ip4" ] is when $mgmt_con_ip4 expands to an empty string. So [ -z $mgmt_con_ip4 ] "would work" in case of an empty string; it's still bad code, but the result is as expected. Errors will happen if unquoted $mgmt_con_ip4 expands to multiple words. Commented Mar 31, 2023 at 5:20
  • 1
    @KamilMaciorowski that's true, i forgot that's how single args are handled by [ / test. the real problem with -z here is, as you say, word splitting of an unquoted var. also worth noting: the test would produce an incorrect result if -n were used instead of -z.
    – cas
    Commented Mar 31, 2023 at 5:32
  • Aside from the other problems mentioned, the one in the title is due to stdin (FD #0) being redirected from $FILE inside the loop, and copying it to FD #3 doesn't change that. Solution: read the file via FD #3 and leave stdin alone. Something like while IFS= read -r hostname <&3; ... done 3< "$FILE". See my answer to this previous question. Commented Mar 31, 2023 at 20:23

1 Answer 1

0

You should not mix to read commands and the same file descriptor input (FD). In the example bellow, I changed the outermost read do FD=3. Here's the code snippet:

  #!/bin/env bash

  FILE="/etc/hosts"
  exec 3<${FILE} 2>/dev/null || exit 1
  
  while IFS= read -ru3 TDATA ; do
      echo "${TDATA}"

      echo -n "Are you sure to loop again? (y/n) "
      read -rn1 YN
      echo
      if [[ ! ${YN} =~ ^[Yy]$ ]] ; then
          echo "No more turning around."
          exec 3<&- # close file
          exit 1
      fi
  done
  exec 3<&- # close file

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .