Expect: how to tell if stdin is redirected from /dev/null? - TCL

This is a discussion on Expect: how to tell if stdin is redirected from /dev/null? - TCL ; In expect (5.43.0), is there any way to tell if stdin has been redirected from /dev/null? I.e., what would the code be to differentiate running myscript without input redirected and running "myscript < /dev/null"? - John...

+ Reply to Thread
Results 1 to 6 of 6

Expect: how to tell if stdin is redirected from /dev/null?

  1. Default Expect: how to tell if stdin is redirected from /dev/null?

    In expect (5.43.0), is there any way to tell if stdin has been redirected
    from /dev/null? I.e., what would the code be to differentiate running
    myscript without input redirected and running "myscript < /dev/null"?

    - John

  2. Default Re: Expect: how to tell if stdin is redirected from /dev/null?

    On Nov 24, 12:55 am, John Caruso <johnSPAMcarAWAY...@myprivacy.ca>
    wrote:
    > In expect (5.43.0), is there any way to tell if stdin has been redirected
    > from /dev/null? I.e., what would the code be to differentiate running
    > myscript without input redirected and running "myscript < /dev/null"?


    Why do you care ? The answer to this may lead to a better-fit reply...

    -Alex

  3. Default Re: Expect: how to tell if stdin is redirected from /dev/null?

    John Caruso wrote:
    > In expect (5.43.0), is there any way to tell if stdin has been redirected
    > from /dev/null? I.e., what would the code be to differentiate running
    > myscript without input redirected and running "myscript < /dev/null"?


    On Linux, you can use [file readlink /proc/[pid]/fd/0] to find out
    what stdin really is. That might or might not help. :-)

    Donal.

  4. Default Re: Expect: how to tell if stdin is redirected from /dev/null?

    John Caruso wrote:
    > In expect (5.43.0), is there any way to tell if stdin has been redirected
    > from /dev/null? I.e., what would the code be to differentiate running
    > myscript without input redirected and running "myscript < /dev/null"?
    >
    > - John


    #!/usr/bin/expect

    if {[ catch {fconfigure stdin -mode} cerr]} {
    puts stderr "stdin is not a tty : $cerr"
    read stdin 1
    if {[eof stdin]} {
    puts stderr "stdin could be /dev/null"
    }
    } else {
    puts stderr "stdin is a tty : $cerr"
    }

    # end

    the -mode test will not differentiate between
    a real tty and and a (faked) pty
    seeking on a pipe is a catchable error.
    seeking on /dev/null is ok
    but you are at eof if you read 1 byte

    uwe

  5. Default Re: Expect: how to tell if stdin is redirected from /dev/null?

    On 2007-11-24, Uwe Klein <uwe_klein_habertwedt@t-online.de> wrote:
    > John Caruso wrote:
    >> In expect (5.43.0), is there any way to tell if stdin has been redirected
    >> from /dev/null? I.e., what would the code be to differentiate running
    >> myscript without input redirected and running "myscript < /dev/null"?
    >>
    >> - John

    >
    > #!/usr/bin/expect
    >
    > if {[ catch {fconfigure stdin -mode} cerr]} {
    > puts stderr "stdin is not a tty : $cerr"
    > read stdin 1
    > if {[eof stdin]} {
    > puts stderr "stdin could be /dev/null"
    > }
    >} else {
    > puts stderr "stdin is a tty : $cerr"
    >}


    Perfect, many thanks. In fact I was really looking for an isatty function
    (just as you've provided), but I didn't want to ask the question in those
    words since I didn't want to constrain the solution. It's a bit surprising
    that expect doesn't provide one.

    For those wondering why: I have an expect script (below) that exhibits bad
    behavior when it's run with input redirected from /dev/null, apparently
    caused by the interact statement handling EOF (if a preceding expect
    statement sees the EOF, all's well). BTW, this is a minimal test script
    culled from a much longer script, which is the reason for some of the odd
    bits of code. Here are sample run lines:

    ./script --user test --hosts "host1 host2 host3" "date; sleep 2; id"
    ./script --rsh --hosts "filer1 filer2 filer3" "date; version"

    The key is to specify multiple hosts, which causes the script to spawn
    multiple remote sessions (you'll need to have trust relationships with
    the remote hosts for this version of the script, and you can specify a
    single host multiple times). When the script is run with input coming
    from the tty it behaves fine, but when it's run with input redirected from
    /dev/null it will do one of the following after the 2nd or 3rd host:

    1) "error writing "stdout": invalid argument
    while executing
    "puts -nonewline $savedoutput"
    2) "interact: spawn id exp0 not open" -- If the catch statement is removed
    from the interact statement.

    (In the first case it may also fail without producing the error message--
    but it will also stop producing output, as though the puts statements are
    having their output thrown away.)

    The weirder failure mode is 1. In this case (with the catch protecting
    the interact statement), it appears that merely calling interact with
    stdin redirect from /dev/null causes *stdout* to be closed, which makes
    the puts (or send_user, if you switch it out for that) fail. Is that the
    expected behavior of interact? It certainly wasn't for me.

    As I said, the difference in whether it produces the above error or not
    appears to be whether or not the expect statement consumes the EOF from
    the child. If it does, all's well, but if the EOF is still out there when
    the interact statement is executed the script will die on the next host.

    Anyway, your code will allow me to work around this issue (by never calling
    interact if there's not a tty attached), but I'd certainly be interested
    to hear if anyone has an idea of why calling interact would cause stdout
    to be closed.

    - John

    #!/usr/bin/expect --

    set hosts ""
    set remotecommand "ssh"
    set user "root"

    while {[llength $argv] > 0} {
    switch -regexp -- [lindex $argv 0] {
    ^--(h|ho|hos|host|hosts)$ {
    append hosts " " [lindex $argv 1]
    set argv [lrange $argv 1 end]
    }
    ^--(r|rs|rsh)$ {
    set remotecommand "rsh"
    }
    ^--(u|us|use|user)$ {
    set user [lindex $argv 1]
    set argv [lrange $argv 1 end]
    }
    default {
    break
    }
    }
    set argv [lrange $argv 1 end]
    }

    send_user "DEBUG: hosts='$hosts', argv='$argv'\n"

    foreach host $hosts {

    log_user 0

    eval spawn $remotecommand -l $user $host $argv

    expect {
    -re ".+" { }
    }
    set savedoutput "$expect_out(buffer)"

    puts -nonewline "***** $remotecommand command output for $host *****\n"
    puts -nonewline $savedoutput
    interact
    catch {
    }

    wait -nowait
    }

  6. Default Re: Expect: how to tell if stdin is redirected from /dev/null?

    On 2007-11-24, John Caruso <johnSPAMcarAWAYuso@myprivacy.ca> wrote:
    > puts -nonewline "***** $remotecommand command output for $host *****\n"
    > puts -nonewline $savedoutput
    > interact
    > catch {
    > }


    This last bit should have been:

    > catch {
    > interact
    > }


    The first way (at the top) will cause failure mode 2, and this way will
    cause the more interesting failure mode 1 (I was switching back and forth
    during testing, and didn't notice that I'd left it this way).

    I should have mentioned that I've seen this on expect 5.43.0 and 5.42.1,
    and on Linux (RHEL4) and Solaris (8). The fact that stdout is somehow
    closed feels like a bug; I can understand that interact wouldn't work
    desirably when input is redirected from a file, but closing stdout was
    pretty surprising behavior.

    - John

+ Reply to Thread

Similar Threads

  1. A redirected web.confg problem
    By Application Development in forum DOTNET
    Replies: 1
    Last Post: 08-01-2007, 09:43 AM
  2. Replies: 6
    Last Post: 07-29-2007, 05:39 PM
  3. email being redirected
    By Application Development in forum Microsoft Exchange
    Replies: 7
    Last Post: 06-12-2007, 10:23 AM
  4. ftp gets redirected.
    By Application Development in forum Inetserver
    Replies: 4
    Last Post: 11-01-2006, 10:21 PM
  5. URL being redirected
    By Application Development in forum Inetserver
    Replies: 3
    Last Post: 09-06-2004, 02:25 PM