On 2012-05-04, Adriana <
adriana...@gmail.com> wrote:
> On May 4, 12:47?am, Eric <
e...@deptj.eu> wrote:
>> On 2012-05-03, Adriana <
adriana.tele...@gmail.com> wrote:
>>
>> > Hello,
>> > I am stuck on a problem and I think that tcl/tk gurus could help me.
>>
>> > I am launching the following command:
>>
>> > if { [catch {exec "ssh" "$user@machine" "-2" "nohup myprogram 2>&1 | ./
>> > log &"} msg] } {
>> > ? ? ? ? puts "$msg"
>> > }
>> > where myprogram is a program that should continuously run and output
>> > text.
>>
>> > It happens that the pipe in the ssh command makes the catch not
>> > return.
>> > This must be a known problem.
>> > Does anyone know how to overcome it?
>> > Thanks in advance.
>> > Adriana
>>
>> From the manpage for exec:
>>
>> "If standard output has not been redirected then the exec command
>> returns the standard output from the last command in the pipeline..."
>>
>> which is ./log in your case. The standard output of ./log (on the
>> remote machine) is provided by ssh which connects it to the local
>> machine where it is connected to the tcl exec command which waits
>> patiently for it to be closed so that exec can return the contents!
>>
>> And catch, of course, waits for exec to complete. So there is nothing
>> wrong whatsoever, and all the software is doing what it is supposed to.
>>
>> All you have to do is close the standard output of ./log , so instead of
>>
>> ?| ./log &
>>
>> you need
>>
>> ?| ./log >/dev/null &
>>
>> and then it will do what you expect.
>>
> Hello, thanks for your answer.
> It does not change anything if I do that.
There must be something in your environment that is different from
mine, or something you are not telling us. I did do all the following
without recording it before replying to your original post.
Last login: Fri May 4 19:39:03 BST 2012 from
teckel.deptj.eu on ssh
test1@teckel ~ $ id
uid=1006(test1) gid=100(users) groups=100(users)
test1@teckel ~ $ pwd
/home/test1
test1@teckel ~ $ ls -l
total 12
-rwxr-xr-x 1 test1 users 14 May 4 19:24 log
-rwxr-xr-x 1 test1 users 38 May 4 19:23 myprog
test1@teckel ~ $ cat myprog
while true; do echo hi; sleep 1; done
The above just something to produce output.
test1@teckel ~ $ cat log
cat > logfile
The above sends its input somewhere.
So I hope they are suitable representations of your programs.
test1@teckel ~ $ exit
Now see what processes exist:
teckel ~ # ps -Hfu test1
UID PID PPID C STIME TTY TIME CMD
teckel ~ # ps -Hfu eric
UID PID PPID C STIME TTY TIME CMD
eric 29401 29399 0 19:19 ? 00:00:00 sshd: eric@pts/2
eric 29402 29401 0 19:19 pts/2 00:00:00 -bash
In my own session:
eric@teckel ~ $ ssh test1@teckel -2 "nohup ./myprog 2>&1 | ./log &"
does not return. Now the processes are:
teckel ~ # ps -Hfu test1
UID PID PPID C STIME TTY TIME CMD
test1 30297 30295 0 19:48 ? 00:00:00 sshd: test1@notty
test1 30300 1 0 19:48 ? 00:00:00 bash -c nohup ./myprog 2>&1 | ./
test1 30301 30300 0 19:48 ? 00:00:00 cat
test1 30299 1 0 19:48 ? 00:00:00 /bin/sh ./myprog
test1 30374 30299 0 19:49 ? 00:00:00 sleep 1
teckel ~ # ps -Hfu eric
UID PID PPID C STIME TTY TIME CMD
eric 29401 29399 0 19:19 ? 00:00:00 sshd: eric@pts/2
eric 29402 29401 0 19:19 pts/2 00:00:00 -bash
eric 30294 29402 0 19:48 pts/2 00:00:00 ssh test1@teckel -2 nohup ./
Clean up:
teckel ~ # kill 30299
teckel ~ # ps -Hfu test1
UID PID PPID C STIME TTY TIME CMD
teckel ~ # ps -Hfu eric
UID PID PPID C STIME TTY TIME CMD
eric 29401 29399 0 19:19 ? 00:00:00 sshd: eric@pts/2
eric 29402 29401 0 19:19 pts/2 00:00:00 -bash
and now my session has returned, so try:
eric@teckel ~ $ ssh test1@teckel -2 "nohup ./myprog 2>&1 | ./log > /dev/null &"
eric@teckel ~ $
which has returned immediately. But now the processes are:
teckel ~ # ps -Hfu test1
UID PID PPID C STIME TTY TIME CMD
test1 30464 1 0 19:51 ? 00:00:00 bash -c nohup ./myprog 2>&1 | ./
test1 30465 30464 0 19:51 ? 00:00:00 cat
test1 30463 1 0 19:51 ? 00:00:00 /bin/sh ./myprog
test1 30535 30463 0 19:52 ? 00:00:00 sleep 1
teckel ~ # ps -Hfu eric
UID PID PPID C STIME TTY TIME CMD
eric 29401 29399 0 19:19 ? 00:00:00 sshd: eric@pts/2
eric 29402 29401 0 19:19 pts/2 00:00:00 -bash
No ssh in my session, but the expected processes for test1. So let's
do it all again with Tcl:
teckel ~ # kill 30463
teckel ~ # ps -Hfu test1
UID PID PPID C STIME TTY TIME CMD
teckel ~ # ps -Hfu eric
UID PID PPID C STIME TTY TIME CMD
eric 29401 29399 0 19:19 ? 00:00:00 sshd: eric@pts/2
eric 29402 29401 0 19:19 pts/2 00:00:00 -bash
eric@teckel ~ $ /usr/bin/tclsh
% set user test1
test1
% if { [catch {exec "ssh" "$user@teckel" "-2" "nohup ./myprog 2>&1 | ./log &"} msg] } {
puts "$msg"
}
doesn't return, and the processes are...
teckel ~ # ps -Hfu test1
UID PID PPID C STIME TTY TIME CMD
test1 31443 31441 0 20:09 ? 00:00:00 sshd: test1@notty
test1 31446 1 0 20:09 ? 00:00:00 bash -c nohup ./myprog 2>&1 | ./
test1 31447 31446 0 20:09 ? 00:00:00 cat
test1 31445 1 0 20:09 ? 00:00:00 /bin/sh ./myprog
test1 31614 31445 0 20:11 ? 00:00:00 sleep 1
teckel ~ # ps -Hfu eric
UID PID PPID C STIME TTY TIME CMD
eric 29401 29399 0 19:19 ? 00:00:00 sshd: eric@pts/2
eric 29402 29401 0 19:19 pts/2 00:00:00 -bash
eric 31436 29402 0 20:08 pts/2 00:00:00 /usr/bin/tclsh
eric 31440 31436 0 20:09 pts/2 00:00:00 ssh test1@teckel -2 nohup
Clean up ...
teckel ~ # kill 31445
teckel ~ # ps -Hfu test1
UID PID PPID C STIME TTY TIME CMD
teckel ~ # ps -Hfu eric
UID PID PPID C STIME TTY TIME CMD
eric 29401 29399 0 19:19 ? 00:00:00 sshd: eric@pts/2
eric 29402 29401 0 19:19 pts/2 00:00:00 -bash
eric 31436 29402 0 20:08 pts/2 00:00:00 /usr/bin/tclsh
... and try the other way:
% if { [catch {exec "ssh" "$user@teckel" "-2" "nohup ./myprog 2>&1 | ./log > /dev/null &"} msg] } {
puts "$msg"
}
%
which returns straight away, leaving us with:
teckel ~ # ps -Hfu test1
UID PID PPID C STIME TTY TIME CMD
test1 31701 1 0 20:16 ? 00:00:00 bash -c nohup ./myprog 2>&1 | ./
test1 31702 31701 0 20:16 ? 00:00:00 cat
test1 31700 1 0 20:16 ? 00:00:00 /bin/sh ./myprog
test1 31752 31700 0 20:17 ? 00:00:00 sleep 1
teckel ~ # ps -Hfu eric
UID PID PPID C STIME TTY TIME CMD
eric 29401 29399 0 19:19 ? 00:00:00 sshd: eric@pts/2
eric 29402 29401 0 19:19 pts/2 00:00:00 -bash
eric 31436 29402 0 20:08 pts/2 00:00:00 /usr/bin/tclsh
So myprog and log are running, and tclsh is free to do whatever
comes next! The difference in behaviour is just as I said before,
and Tcl has nothing to do with it anyway.
And just for the record:
% puts "$tcl_version $tcl_patchLevel"
8.5 8.5.9
% exit
eric@teckel ~ $ uname -a
Linux teckel 2.6.31-gentoo-r10 #4 SMP Mon Apr 5 22:10:54 BST 2010 i686 Intel(R) Core(TM)2 CPU 6300 @ 1.86GHz GenuineIntel GNU/Linux
eric@teckel ~ $ bash --version
GNU bash, version 4.1.9(2)-release (i686-pc-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <
http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Apologies for the long post (and the few long lines), but it looked
like evidence time :-)