Vahagn
Vahagn

Reputation: 4840

rlwrap hangs jobs while running at the background

I have a problem with rlwrap (see the man page here). Consider this situation: empty.tcl is an empty file. At bash this line

tclsh empty.tcl &

runs the job in the background and exits it, so i get this prompt

[1]+ Done tclsh empty.tcl.

While this line

rlwrap tclsh empty.tcl &

runs the job in the background and doesn't exit it, so i get this prompt

[1]+ Stopped rlwrap tclsh empty.tcl.

The corresponding job hangs at the background. My question is how to make it exit the job rather then hang?

rlwrap is a Linux utility command which runs the specified command, intercepting user input in order to provide readline’s line editing, persistent history and completion. As it is mentioned there, the main property of rlwrap is you shouldn’t notice any difference between command and rlwrap command, however, as it is described above, this property doesn't hold.

Maybe one can suggest an alternative for rlwrap which functions as expected?

Upvotes: 2

Views: 678

Answers (3)

Hans Lub
Hans Lub

Reputation: 1

Any command that is run in the background will get a SIGTTY as soon as it tries to read from stdin (standard input) (try tclsh &). rlwrap will always read from stdin, even when the rlwrapped command doesn't. Strictly speaking, the original poster is right in saying that this breaks rlwrap's purported transparency

Is this a serious problem? I don't think so - rlwrap is of course only useful for commands that read from stdin anyway, and there is no point in running those commands in the background, with or without rlwrap

Hans Lub (rlwrap author)

Upvotes: 0

Donal Fellows
Donal Fellows

Reputation: 137717

Basically, you can't do this and have it work. The problem (from your perspective) is that if you pass a script file argument to tclsh, it will execute it and then exit. Either use rlwrap tclsh with no further arguments (so it works in interactive mode) or use a script that emulates Tcl's interactive REPL. That's not too hard to write:

fconfigure stdout -buffering none
set command ""
puts -nonewline "% "
while {[gets stdin line] >= 0} {
    append command $line "\n"
    if {[info complete $command]} {
        # Got a complete command; evaluate and catch result
        if {[catch $command msg]} {
            puts "error: $msg"
        } elseif {$msg ne ""} {
            puts $msg
        }
        set command ""
        puts -nonewline "% "
    }
}

OK, you could tweak it a bit more, but it shows how to do it. Stick it at the end of your real script and rlwrap should cope just fine with the result.

Upvotes: 2

Gadolin
Gadolin

Reputation: 2686

I got similar issue in bash, rlwrap bash ./t.sh & , solved that by escaping &, rlwrap bash ./t.sh \& .

That is not good here, it will pass & as an input param.

Upvotes: 0

Related Questions