1

I am initiating myself to shell scripting and I need to ask the user about confirmation.

I have this script, which I don't know why the following command is not working: read -p "Are you sure about this action?" yn

I use it twice, at the beggining of the script and in the middle. The first read works, but the second one... is not wrking...

Btw, my linux distribution is debian 9.3

#!/bin/bash

read -p "holaaa" yn #HERE THE COMMAND WORKS AS EXPECTED

if [[ -e "$1" && -f "$1" ]]; then
        while read nom grup permisos fitxer; do
                if [ -e $fitxer ]; then
                        #echo $fitxer
                        #f=$(stat -c %n $fitxer)        #jo voldria fer servir awk...
                        u=$(stat -c %U $fitxer)
                        g=$(stat -c %G $fitxer)
                        p=$(stat -c %a $fitxer)
                        if [[ "$p" != "$permisos" || "$u" != "$nom" || "$g" != "$grup" ]]; then
                                echo "Informacio al fitxer: $nom , $grup, $permisos, $fitxer"
                                echo "Informacio real: $u, $g, $p, $fitxer"
                                #posar confirmation
                                read -p "holaaaa" yn #HERE THE COMMAND IS NOT WORKING
                                chown $u:$g $fitxer
                                chmod $permisos $fitxer
                        fi
                else 
                        echo "file $fitxer does not exist"
                fi
        done < "$1"

else
        echo "error" >&2
fi

Does anyone know why this happens or what am I doing wrong?

6
  • 1
    How does the "not working" manifest itself? Commented Feb 7, 2019 at 20:30
  • The script should stop, asking for an action... but nothing really happens... it doesn’t prompt the text asking... It is as if there was not read command... Commented Feb 7, 2019 at 20:31
  • But you do get echo "Informacio real: $u, $g, $p, $fitxer" output? Commented Feb 7, 2019 at 20:32
  • Yes I do, the script enters into the if statement and perfroms the echo and the rest of commands Commented Feb 7, 2019 at 20:33
  • 1
    First, please cut your code down to a minimal reproducible example. Second, how do you tell the command is working or not? Third, have you considered the second call of read isn't executed because that branch is skipped? Fourth, you never use the variable yn anywhere. Commented Feb 7, 2019 at 20:33

2 Answers 2

5

The read inside the loop is reading from the same source the condition is (< "$1").

And the prompt is not displayed because it is only showed when input is coming from a terminal.

You can explicitly make the inner read to read from the terminal by adding < /dev/tty, example:

read -p "holaaaa" yn < /dev/tty

Or you can just can read from the standard input with <&0 redirection (file descriptor 0 is for stdin). This has the advantage that the caller of the command will be able to provide canned responses, as noted by the commenter. Example:

read -p "holaaaa" yn <&0
Sign up to request clarification or add additional context in comments.

2 Comments

Better to change the file descriptor the outer read uses, since it is hard-coded to read from "$1". Let the confirmation read continue to read from standard input, so the caller can decide to use the terminal or a file of canned responses to reply.
I couldn't understand the recommendation you provided, chepner. WHat you mean by saying to change the file descriptor of read...? Why you want me to try?
2

You have two read commands intended to read from different sources (one from a given file, the other from the script's standard input), using the same file descriptor (0). Use a different file descriptor for $1 so that the other read can continue to read from the script's standard input, instead of overwriting that with $1.

#!/bin/bash

read -p "holaaa" yn

if [[ -f "$1" ]]; then
    # Read from file descriptor 3
    while read nom grup permisos fitxer <&3; do
         if [ -e "$fitxer" ]; then
             #f=$(stat -c %n $fitxer)        #jo voldria fer servir awk...
             u=$(stat -c %U $fitxer)
             g=$(stat -c %G $fitxer)
             p=$(stat -c %a $fitxer)
             if [[ "$p" != "$permisos" || "$u" != "$nom" || "$g" != "$grup" ]]; then
                 echo "Informacio al fitxer: $nom , $grup, $permisos, $fitxer"
                 echo "Informacio real: $u, $g, $p, $fitxer"
                 #posar confirmation
                 read -p "holaaaa" yn
                 chown $u:$g $fitxer
                 chmod $permisos $fitxer
             fi
         else 
             echo "file $fitxer does not exist"
         fi
    done 3< "$1"  # Attach $1 to file descriptor 3
else
    echo "error" >&2
fi

1 Comment

Okay, chepner. Now I know what you mean, it is a very interesting approach to.Thanks a lot!!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.