Force Bash-Script to wait for a Perl-Script that a

2019-07-09 14:14发布

问题:

I'm having a Bash-Script that sequentially runs some Perl-Scripts which are read from a file. These scripts require the press of Enter to continue.

Strangely when I run the script it's never waiting for the input but just continues. I assume something in the Bash-Script is interpreted as an Enter or some other Key-Press and makes the Perl continue.

I'm sure there is a solution out there but don't really know what to look for.

My Bash has this while-Loop which iterates through the list of Perl-Scripts (which is listed in seqfile)

while read zeile; do
    if [[ ${datei:0:1} -ne 'p' ]]; then
        datei=${zeile:8}
    else
        datei=$zeile
    fi
    case ${zeile: -3} in
    ".pl")
    perl  $datei  #Here it just goes on...
    #echo "Test 1"
    #echo "Test 2"
    ;;
    ".pm")
        echo $datei "is a Perl Module" 
    ;;
    *)
        echo "Something elso"
    ;;
    esac
done <<< $seqfile;

You notice the two commented lines With echo "Test 1/2". I wanted to know how they are displayed. Actually they are written under each other like there was an Enter-Press:

Test 1
Test 2

The output of the Perl-Scripts is correct I just have to figure out a way how to force the input to be read from the user and not from the script.

回答1:

Have the perl script redirect input from /dev/tty.

Proof of concept:

while read line ; do
    export line
    perl -e 'print "Enter $ENV{line}: ";$y=<STDIN>;print "$ENV{line} is $y\n"' </dev/tty
done <<EOF
foo
bar
EOF

Program output (user input in bold):

Enter foo: 123 foo is 123
Enter bar: 456 bar is 456



回答2:

@mob's answer is interesting, but I'd like to propose an alternative solution for your use case that will also work if your overall bash script is run with a specific input redirection (i.e. not /dev/tty).

Minimal working example:

  • script.perl

    #!/usr/bin/env perl
    use strict;
    use warnings;
    {
        local( $| ) = ( 1 );
        print "Press ENTER to continue: ";
        my $resp = <STDIN>;
    }
    print "OK\n";
    
  • script.bash

    #!/bin/bash
    
    exec 3>&0 # backup STDIN to fd 3
    
    while read line; do
        echo "$line"
        perl "script.perl" <&3 # redirect fd 3 to perl's input
    done <<EOF
    First
    Second
    EOF
    
    exec 3>&- # close fd 3
    

So this will work with both: ./script.bash in a terminal and yes | ./script.bash for example...

For more info on redirections, see e.g. this article or this cheat sheet.

Hoping this helps