Home > OS >  Bash script on remote terminal issue with user imput
Bash script on remote terminal issue with user imput

Time:09-24

I am fairly new to programming in general and I am having trouble with a simple bash script running on a remote workstation in Ubuntu. Here is the script:

#!/bin/bash
while true; do
  echo "Generate new input file?"
  read  yn
  case $yn in
    [Yy]* )./data/Input/Input_f90_generation.py; break;;
    [Nn]* ) break;;
    * ) echo "Please answer yes or no.";;
  esac
done
echo -------------------
echo Parallel simulation
echo -------------------
echo How many processors?
read proc
LD_LIBRARY_PATH= /usr/bin/mpirun.mpich -np=$proc ./Core.out
echo -------------------
while true; do
  echo "Plot results?"
  read  yn
  case $yn in
    [Yy]* )
    echo -------------------
    echo Plotting results
    echo -------------------
    ./src/parallel_post.py; break;;
    [Nn]* ) break;;
    * ) echo "Please answer yes or no.";;
  esac
done

If I try to run this on my computer it works fine every time, once a simulation is finished I can lunch another one by running again the script. On the other hand, if I copy the script on the remote workstation and I run it from the remote terminal, I experience the following result:

  • The first two user inputs, generate file and proc, work correctly. The simulation starts as it should

  • Once the simulation is finished (the elapsed time is printed out on the terminal from the fortran code), the third user input (plot stuff) is ignored and the script loops indefinitely between "plot results?" and "Please answer yes or no." If I remove the loop it just skip that part without waiting for an input.

  • If the last loop is removed and I try to run again the script, it loops on the first input in the same fashion as before.

The only way to recover from this is to abort the script and close and open again the terminal, which is very annoying.

I want to stress the fact that on my computer it works correctly without any issue. What could be the cause of this behavior?

Following the suggestions in the comments I also attach a screenshot of the terminal. Outcome of running the script

The problem seems to be "line 22: read: read error: 0: Resource temporarily unavailable" as this occurs also in the aforementioned case of trying to run the script twice. Apparently as soon as the simulation runs and prints out the elapsed time, the bash script stops working. I noted also that if I don't run the simulation (for example using a non valid number of processors), or to better say if the simulation does not print the elapsed time (apparently MPI runtime error are not an issue), the script works correctly each time and the one after.

CodePudding user response:

Per the debug output, you have a few failures here:

  • you need to pip install click on the target machine, otherwise python is failing (silently before, it seems).
  • stdin is going down sometimes. Speculations below. You are better off as one comment says getting arguments from the cli, but if it is just a network/timeout error (unlikely) you could write a robust input function with something like
while 1; do
    (read myvar && break) || sleep 1
done

to try to work around broken stdin, but there's no gaurantee that would work if you're not seeing a network outage.

In any case fixing click isn't going to hurt, and refactoring for cli input (with getopt or just $1 $2 etc) is probably easiest.

Speculations on stdin

Apparently printing the time (which is in your simulation code) causes the problem. It could be doing something funny with the terminal to display it, in which case adding reset after the simulation might fix it.

CodePudding user response:

Here I think is a reproducible example of this problem:

#!/bin/bash
set -x
exec 3<&0 0</dev/null
reset
while true; do
    echo "Generate new input file?"
    read  yn
    case $yn in
        [Yy]* )echo "new input file"; break;;
        [Nn]* ) break;;
        * ) echo "Please answer yes or no.";;
    esac
done

Thus I think something is redirecting stdin, probably to /dev/null.

Solution: spawn a new bash to run the bad code:

#!/bin/bash
set -x
bash -c "exec 3<&0 0</dev/null"
reset
while true; do
    echo "Generate new input file?"
    read  yn
    case $yn in
        [Yy]* )echo "new input file"; break;;
        [Nn]* ) break;;
        * ) echo "Please answer yes or no.";;
    esac
done

So if you wrap your call to to the simulation code in bash -c does it behave itself?

References

Bash shell read error: 0: Resource temporarily unavailable

  •  Tags:  
  • bash
  • Related