Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Docker Container Started With Docker-Compose and <STDIN>

by gflohr (Acolyte)
on Sep 12, 2019 at 15:46 UTC ( [id://11106075]=perlquestion: print w/replies, xml ) Need Help??

gflohr has asked for the wisdom of the Perl Monks concerning the following question:

A Perl script is supposed to run on a regular system, under Windows, and inside a docker container via docker-compose. The following line gives me a headache:

my $input = <STDIN>;

It is clear that this will not work in my container because there is no standard input. I want it to fail and bail out. The problem is that it never returns.

How can I detect that situation in a clean way?

One solution would be to check whether I'm running inside a container and then bail out right away. But that is ugly and maybe not very reliable. I could also try to set an alarm but that may not work under Windows.

Any better idea?

Replies are listed 'Best First'.
Re: Docker Container Started With Docker-Compose and <STDIN>
by roboticus (Chancellor) on Sep 12, 2019 at 17:06 UTC

    gflohr:

    Unless you explicitly close it, you do have an STDIN available, and the script is hanging because it's waiting for input that'll never arrive.

    If the script is yours or you can change it, I'd probably try:

    • Looking for an environment variable that can indicate whether you're in the Docker container and use it to bail out of your program, or
    • Use alarm() to add a timeout for user input so it can't hang indefinitely.

    If the script isn't yours, but you're using fork() to invoke the script, then you could try duplicating the STDIN stream and closing it before forking, so the child script won't have an open STDIN. That should make it immediately return with undef in $input. (That may require some jiggery-pokery with IO::Handle or maybe a double-fork, where the child of the initial fork can close its STDIN and then fork to the script you want to run.)

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: Docker Container Started With Docker-Compose and <STDIN>
by haukex (Archbishop) on Sep 12, 2019 at 17:53 UTC
    my $input = <STDIN>; It is clear that this will not work in my container because there is no standard input. I want it to fail and bail out. The problem is that it never returns. How can I detect that situation in a clean way?

    If you want to detect whether the user can enter input (not directly whether it's running inside a Docker container), I'd suggest IO::Interactive, or at the very least -t STDIN. Or, you could use a prompting module instead, depending on what you're actually trying to implement.

Re: Docker Container Started With Docker-Compose and <STDIN>
by Marshall (Canon) on Sep 12, 2019 at 16:50 UTC
    You are hanging because you have an open filehandle and nothing to read. If you close STDIN; you would get "readline() on closed filehandle STDIN" -the read won't "hang". Not sure if that helps?
Re: Docker Container Started With Docker-Compose and <STDIN>
by bliako (Monsignor) on Sep 12, 2019 at 21:16 UTC
Re: Docker Container Started With Docker-Compose and <STDIN>
by NERDVANA (Deacon) on Sep 14, 2019 at 02:05 UTC
    I think you have either mis-diagnosed the problem, or have a buggy version of docker. (maybe the Windows part, I've only used it on Linux) This behaves as expected for me, reading one line of input and printing it:
    $ echo "yes" | docker run --rm -i debian perl -e 'print(<STDIN>)' yes
    This also behaves as expected, reading nothing and exiting immediately:
    $ docker run --rm debian perl -e 'print(<STDIN> or "(EOF)")' (EOF)
    So, if you have a script that is reading STDIN inside docker and hanging, it sounds like you need to make sure not to specify "-i" from the docker-compose config, or maybe something else is happening entirely.
Re: Docker Container Started With Docker-Compose and <STDIN>
by kcott (Archbishop) on Sep 20, 2019 at 09:16 UTC

    G'day gflohr,

    I'm a bit late to the party on this one; however, I wondered if fileno might help you:

    $input = <STDIN> if defined fileno(STDIN);

    I don't have docker to test but it seems to work equally well on both UNIX-like and MSWin OSes.

    Cygwin:

    ken@titan ~/tmp $ perl -E 'my $input = "none"; $input = <STDIN> if defined fileno(STDI +N); say $input' qwerty qwerty ken@titan ~/tmp $ perl -E 'my $input = "none"; close STDIN; $input = <STDIN> if define +d fileno(STDIN); say $input' none ken@titan ~/tmp

    Win10 - cmd.exe:

    C:\Users\ken\tmp>perl -E "my $input = 'none'; $input = <STDIN> if def +ined fileno(STDIN); say $input" qwerty qwerty C:\Users\ken\tmp>perl -E "my $input = 'none'; close STDIN; $input = < +STDIN> if defined fileno(STDIN); say $input" none C:\Users\ken\tmp>

    Win10 - PowerShell:

    PS C:\Users\ken\tmp> perl -E 'my $input = "none"; close STDIN; eval { +defined fileno(STDIN) } and do { $input = <STDIN> }; say $input' none PS C:\Users\ken\tmp> perl -E 'my $input = "none"; $input = <STDIN> if +defined fileno(STDIN); say $input' qwerty qwerty PS C:\Users\ken\tmp> perl -E 'my $input = "none"; close STDIN; $input += <STDIN> if defined fileno(STDIN); say $input' none PS C:\Users\ken\tmp>

    And in case you were wondering, those are using different Perl installations for Cygwin and Win10:

    This is perl 5, version 30, subversion 0 (v5.30.0) built for cygwin-th +read-multi This is perl 5, version 30, subversion 0 (v5.30.0) built for MSWin32-x +64-multi-thread

    You don't need v5.30; that's just what I have installed. I suspect the guts of that code would work on pretty much any Perl 5.

    — Ken

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11106075]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (2)
As of 2024-04-19 18:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found