Thread: [JSch-users] pl. help - exec and threads.
Status: Alpha
Brought to you by:
ymnk
From: Satish A <sa...@my...> - 2005-01-23 09:54:23
|
Hello, I am new user to jsch. I am basically trying to do this: cat "hello world" | ssh -i <priv_key> user@remhost 'cat >> remfile' ie., append the output of a local program to a remote file over ssh. Basically, I am trying to do this in a method that starts a session, appends to remote file and ends the session. I figured that Exec.java example is the closest to this. With little mods, I have the code below. It works in that the remfile is appended to. But, the problem is that after channel.connect() is done executing, the program still runs because thread(s) are still alive. If I add session.disconnect() right after it, the file is not getting appended to. If I add a slight delay (in comments below), it works. So, I guess the actual write is happening in a different thread. How can I tell when the write is complete (ie., all the bytes from input stream are transferred to the remote file). Btw, I am using openssh-3.6.1p2-34 on the remote system. The local system is Fedora core 3. java 1.4.2-6. JSch jsch=new JSch(); jsch.addIdentity(privKeyFile.getAbsolutePath()); Session session=jsch.getSession(username, remHost.getHostAddress(), remPort); // establish ssh session UserInfo userInfo = new UserInfo() { public String getPassphrase() { return pass; } public String getPassword() { return pass; } public boolean promptPassword(String message) { System.out.println("passwd prompt: "+message); return false; } public boolean promptPassphrase(String message) { System.out.println("passphrase prompt: "+message); return false; } public boolean promptYesNo(String message) { return true; } public void showMessage(String message) { System.out.println(message); } }; session.setUserInfo(userInfo); session.connect(); // execute command on remote system String cmd = "cat >> "+remFile; Channel channel = session.openChannel("exec"); ((ChannelExec)channel).setCommand(cmd); InputStream bis = new ByteArrayInputStream(buf); channel.setInputStream(bis); channel.setOutputStream(System.out); ((ChannelExec)channel).setErrStream(System.err); channel.connect(); // try { // Thread.sleep(1000); // } catch (InterruptedException ex) { // ex.printStackTrace(); // } // disconnect session // session.disconnect(); Thanks, Satish. |
From: Kevin K. <ka...@um...> - 2005-01-23 22:43:33
|
Where you have your slight delay, I'd suggest instead doing something like while (!channel.isEOF()) { // Wait for the remote process to complete. Thread.sleep(500); } Ideally, you should be able to register a listener with the Channel object which would be notified of EOF events, but for right now you'll just have to poll. Hope this helps, -Kevin ----- Original Message ----- From: "Satish A" <sa...@my...> To: <jsc...@li...> Sent: Sunday, January 23, 2005 4:54 AM Subject: [JSch-users] pl. help - exec and threads. > Hello, > > I am new user to jsch. > > I am basically trying to do this: > > cat "hello world" | ssh -i <priv_key> user@remhost 'cat >> remfile' > > ie., append the output of a local program to a remote file over ssh. > > Basically, I am trying to do this in a method that starts a session, > appends to remote file and ends the session. > > I figured that Exec.java example is the closest to this. With little > mods, I have the code below. It works in that the remfile is appended > to. But, the problem is that after channel.connect() > is done executing, the program still runs because thread(s) are still > alive. If I add session.disconnect() right after it, the file is not > getting appended to. If I add a slight delay (in comments below), it > works. > > So, I guess the actual write is happening in a different thread. How can > I tell when the write is complete (ie., all the bytes from input > stream are transferred to the remote file). > > Btw, I am using openssh-3.6.1p2-34 on the remote system. The local > system is Fedora core 3. java 1.4.2-6. > > JSch jsch=new JSch(); > jsch.addIdentity(privKeyFile.getAbsolutePath()); > Session session=jsch.getSession(username, > remHost.getHostAddress(), remPort); > // establish ssh session > UserInfo userInfo = new UserInfo() { > > public String getPassphrase() { > return pass; > } > > public String getPassword() { > return pass; > } > > public boolean promptPassword(String message) { > System.out.println("passwd prompt: "+message); > return false; > } > > public boolean promptPassphrase(String message) { > System.out.println("passphrase prompt: "+message); > return false; > } > > public boolean promptYesNo(String message) { > return true; > } > > public void showMessage(String message) { > System.out.println(message); > } > }; > > session.setUserInfo(userInfo); > session.connect(); > > // execute command on remote system > String cmd = "cat >> "+remFile; > Channel channel = session.openChannel("exec"); > ((ChannelExec)channel).setCommand(cmd); > InputStream bis = new ByteArrayInputStream(buf); > channel.setInputStream(bis); > channel.setOutputStream(System.out); > ((ChannelExec)channel).setErrStream(System.err); > channel.connect(); > > // try { > // Thread.sleep(1000); > // } catch (InterruptedException ex) { > // ex.printStackTrace(); > // } > > // disconnect session > // session.disconnect(); > > Thanks, > Satish. > > > > > ------------------------------------------------------- > This SF.Net email is sponsored by: IntelliVIEW -- Interactive Reporting > Tool for open source databases. Create drag-&-drop reports. Save time > by over 75%! Publish reports on the web. Export to DOC, XLS, RTF, etc. > Download a FREE copy at http://www.intelliview.com/go/osdn_nl > _______________________________________________ > JSch-users mailing list > JSc...@li... > https://lists.sourceforge.net/lists/listinfo/jsch-users > > > |
From: Satish A <sa...@my...> - 2005-01-24 23:13:38
|
Thanks Kevin. Your solution works well. I was wondering if there was any way to get the exit status of the remote command like openSSH does? Satish. On Sun, 2005-01-23 at 17:43 -0500, Kevin Kane wrote: > Where you have your slight delay, I'd suggest instead doing something like > > while (!channel.isEOF()) > { > // Wait for the remote process to complete. > Thread.sleep(500); > } > > Ideally, you should be able to register a listener with the Channel object which > would be notified of EOF events, but for right now you'll just have to poll. > > Hope this helps, > -Kevin > > ----- Original Message ----- > From: "Satish A" <sa...@my...> > To: <jsc...@li...> > Sent: Sunday, January 23, 2005 4:54 AM > Subject: [JSch-users] pl. help - exec and threads. > > > > Hello, > > > > I am new user to jsch. > > > > I am basically trying to do this: > > > > cat "hello world" | ssh -i <priv_key> user@remhost 'cat >> remfile' > > > > ie., append the output of a local program to a remote file over ssh. > > > > Basically, I am trying to do this in a method that starts a session, > > appends to remote file and ends the session. > > > > I figured that Exec.java example is the closest to this. With little > > mods, I have the code below. It works in that the remfile is appended > > to. But, the problem is that after channel.connect() > > is done executing, the program still runs because thread(s) are still > > alive. If I add session.disconnect() right after it, the file is not > > getting appended to. If I add a slight delay (in comments below), it > > works. > > > > So, I guess the actual write is happening in a different thread. How can > > I tell when the write is complete (ie., all the bytes from input > > stream are transferred to the remote file). > > > > Btw, I am using openssh-3.6.1p2-34 on the remote system. The local > > system is Fedora core 3. java 1.4.2-6. > > > > JSch jsch=new JSch(); > > jsch.addIdentity(privKeyFile.getAbsolutePath()); > > Session session=jsch.getSession(username, > > remHost.getHostAddress(), remPort); > > // establish ssh session > > UserInfo userInfo = new UserInfo() { > > > > public String getPassphrase() { > > return pass; > > } > > > > public String getPassword() { > > return pass; > > } > > > > public boolean promptPassword(String message) { > > System.out.println("passwd prompt: "+message); > > return false; > > } > > > > public boolean promptPassphrase(String message) { > > System.out.println("passphrase prompt: "+message); > > return false; > > } > > > > public boolean promptYesNo(String message) { > > return true; > > } > > > > public void showMessage(String message) { > > System.out.println(message); > > } > > }; > > > > session.setUserInfo(userInfo); > > session.connect(); > > > > // execute command on remote system > > String cmd = "cat >> "+remFile; > > Channel channel = session.openChannel("exec"); > > ((ChannelExec)channel).setCommand(cmd); > > InputStream bis = new ByteArrayInputStream(buf); > > channel.setInputStream(bis); > > channel.setOutputStream(System.out); > > ((ChannelExec)channel).setErrStream(System.err); > > channel.connect(); > > > > // try { > > // Thread.sleep(1000); > > // } catch (InterruptedException ex) { > > // ex.printStackTrace(); > > // } > > > > // disconnect session > > // session.disconnect(); > > > > Thanks, > > Satish. > > > > > > > > > > ------------------------------------------------------- > > This SF.Net email is sponsored by: IntelliVIEW -- Interactive Reporting > > Tool for open source databases. Create drag-&-drop reports. Save time > > by over 75%! Publish reports on the web. Export to DOC, XLS, RTF, etc. > > Download a FREE copy at http://www.intelliview.com/go/osdn_nl > > _______________________________________________ > > JSch-users mailing list > > JSc...@li... > > https://lists.sourceforge.net/lists/listinfo/jsch-users > > > > > > > > > > _________________________________________________ > Scanned on 23 Jan 2005 22:43:46 > -- Satish Annapureddy Myrio Corporation sa...@my... tel 425-368-4472 fax 425-368-4500 |
From: <ym...@jc...> - 2005-01-24 05:04:38
|
Hi, +-From: "Kevin Kane" <ka...@um...> --- |_Date: Sun, 23 Jan 2005 17:43:06 -0500 __ | |Ideally, you should be able to register a listener with the Channel object |which would be notified of EOF events, but for right now you'll just |have to poll. I agree there should be the listener mechanism for Channel. Do you have a proposal for the listener's interface? |Where you have your slight delay, I'd suggest instead doing something like | while (!channel.isEOF()){ | // Wait for the remote process to complete. | Thread.sleep(500); | } Here is an yet another suggestion for Salish's program, // execute command on remote system String cmd = "cat >> "+remFile; Channel channel = session.openChannel("exec"); ((ChannelExec)channel).setCommand(cmd); InputStream bis = new ByteArrayInputStream(buf); channel.setInputStream(bis); InputStream in=channel.getInputStream(); // //channel.setOutputStream(System.out); // ((ChannelExec)channel).setErrStream(System.err); channel.connect(); byte[] tmp=new byte[1024]; // while(true){ // if(channel.isEOF() && in.available()<=0) break; // while(in.available()>0){ // int i=in.read(tmp, 0, 1024); // if(i<0)break; // System.out.print(new String(tmp, 0, i)); // } // } // channel.disconnect(); // Thanks, -- ymnk |
From: Kevin K. <ka...@um...> - 2005-01-24 18:37:54
|
Atsuhiko Yamanaka wrote: > I agree there should be the listener mechanism for Channel. Do you have > a proposal for the listener's interface? Actually, I think Holger Klawitter came up with one last month (Dec 3, "suggestions on how to recognize closed channels"), though I don't have his original message with the proposed code. Holger, if you're still on the list, could you propose it again? Thanks, -Kevin |
From: Kevin K. <ka...@um...> - 2005-01-24 23:20:44
|
Satish A wrote: > I was wondering if there was any way to get the exit status of the > remote command like openSSH does? Yes, use channel.getExitStatus(). -Kevin |
From: Satish A <sa...@my...> - 2005-01-25 11:28:29
|
I was wondering if there could be a potential issue with channel.getExitStatus(). I am noticing that the exit status when it reports a non-zero value does not always seem right. For example, echo "hello world" | ssh -i <priv key> user@remotehost 'cat >> /tmp/foo 2>&1' (with or without stderr redirection) always returns 0 as exit status. However, done using jsch, the exit status is rarely 0 even though the command works every time. I was wondering if you had any pointers. Satish. On Mon, 2005-01-24 at 18:20 -0500, Kevin Kane wrote: > Satish A wrote: > > I was wondering if there was any way to get the exit status of the > > remote command like openSSH does? > > Yes, use channel.getExitStatus(). > -Kevin > > > > ------------------------------------------------------- > This SF.Net email is sponsored by: IntelliVIEW -- Interactive Reporting > Tool for open source databases. Create drag-&-drop reports. Save time > by over 75%! Publish reports on the web. Export to DOC, XLS, RTF, etc. > Download a FREE copy at http://www.intelliview.com/go/osdn_nl > _______________________________________________ > JSch-users mailing list > JSc...@li... > https://lists.sourceforge.net/lists/listinfo/jsch-users > > > _________________________________________________ > Scanned on 24 Jan 2005 23:33:24 > -- Satish Annapureddy Myrio Corporation sa...@my... tel 425-368-4472 fax 425-368-4500 |
From: Holger K. <li...@kl...> - 2005-01-25 07:58:31
Attachments:
listeners.tar.bz2
|
> Actually, I think Holger Klawitter came up with one last month (Dec 3, > "suggestions on how to recognize closed channels"), though I don't have his > original message with the proposed code. Holger, if you're still on the > list, could you propose it again? Sure, here we go again. Mit freundlichem Gruß / With kind regards Holger Klawitter -- lists <at> klawitter <dot> de |
From: Kevin K. <ka...@um...> - 2005-01-25 16:23:12
|
Holger Klawitter wrote: > > Actually, I think Holger Klawitter came up with one last month (Dec 3, > > "suggestions on how to recognize closed channels"), though I don't have his > > original message with the proposed code. Holger, if you're still on the > > list, could you propose it again? > > Sure, here we go again. Thanks Holger! So, here is Holger's proposed interface: --------- /** * A ChannelCloseListener is being invoked when a channel is being closed, after * the internal cleanup has taken place. */ public interface ChannelCloseListener { /** * Being called then the channel is being closed. * @param ch the channel being closed. */ public void channelClosed( Channel ch ); } --------- My only comment is to change the interface name to ChannelListener, so that it can extended in the future with other events. -Kevin |
From: <ym...@jc...> - 2005-01-25 13:44:35
|
Hi, +-From: Satish A <sa...@my...> ------ |_Date: Tue, 25 Jan 2005 03:28:18 -0800 __ | |I was wondering if there could be a potential issue with |channel.getExitStatus(). |I am noticing that the exit status when it reports a non-zero value |does not always seem right. |For example, | echo "hello world" | \ | ssh -i <priv key> user@remotehost 'cat >> /tmp/foo2>&1' |(with or without stderr redirection) always returns 0 as exit status. |However, done using jsch, the exit status is rarely 0 even though the |command works every time. On my environment, I get '0' every time. And, for example, for the command "cat > /", I get '1' as status code and that means 'Operation not permitted' on GNU/Linux as you know. So, it seems to me that it works fine at least on my environment. Do you really invoke 'channel.getExitStatus()' after channel.isEOF() becomes 'true'? Thanks, -- ymnk |
From: Satish A <sa...@my...> - 2005-01-26 01:18:35
|
I do call getExitStatus() after channel.isEOF returns true. On further testing, I noticed that the exit status was mostly incorrect against ssh -V = OpenSSH_3.9p1, OpenSSL 0.9.7a Feb 19 2003 (on Fedora Core 3) and was 0 every time against ssh -V = OpenSSH_3.6.1p2, SSH protocols 1.5/2.0, OpenSSL 0x0090701f (on Fedora Core 2) Satish. On Tue, 2005-01-25 at 22:39 +0900, Atsuhiko Yamanaka wrote: > Hi, > > +-From: Satish A <sa...@my...> ------ > |_Date: Tue, 25 Jan 2005 03:28:18 -0800 __ > | > |I was wondering if there could be a potential issue with > |channel.getExitStatus(). > |I am noticing that the exit status when it reports a non-zero value > |does not always seem right. > |For example, > | echo "hello world" | \ > | ssh -i <priv key> user@remotehost 'cat >> /tmp/foo2>&1' > |(with or without stderr redirection) always returns 0 as exit status. > |However, done using jsch, the exit status is rarely 0 even though the > |command works every time. > > On my environment, I get '0' every time. > And, for example, for the command "cat > /", I get '1' as status code > and that means 'Operation not permitted' on GNU/Linux as you know. > So, it seems to me that it works fine at least on my environment. > > Do you really invoke 'channel.getExitStatus()' > after channel.isEOF() becomes 'true'? > > Thanks, > -- > ymnk > > > ------------------------------------------------------- > This SF.Net email is sponsored by: IntelliVIEW -- Interactive Reporting > Tool for open source databases. Create drag-&-drop reports. Save time > by over 75%! Publish reports on the web. Export to DOC, XLS, RTF, etc. > Download a FREE copy at http://www.intelliview.com/go/osdn_nl > _______________________________________________ > JSch-users mailing list > JSc...@li... > https://lists.sourceforge.net/lists/listinfo/jsch-users > > > _________________________________________________ > Scanned on 25 Jan 2005 20:43:00 |
From: Holger K. <li...@kl...> - 2005-01-26 08:26:09
Attachments:
jsch-0.1.20.listener.tar.bz2
|
On Tuesday 25 January 2005 17:23, Kevin Kane wrote: > public interface ChannelCloseListener { >[...] > My only comment is to change the interface name to ChannelListener, so that > it can extended in the future with other events. That's a good point! Here is an improved version. Mit freundlichem Gruß / With kind regards Holger Klawitter -- lists <at> klawitter <dot> de |
From: <ym...@jc...> - 2005-01-26 16:16:12
|
Hi, Thank you for feedback. +-From: Holger Klawitter <li...@kl...> -- |_Date: Wed, 26 Jan 2005 08:36:01 +0100 ________ | |That's a good point! Here is an improved version. ... How about listening for the event at opening or establishing connection, and how about monitoring data in inbound and outbound streams? There should be many possibilities, but I'm still hesitated to add listers. Do you know the reason why JDK API does not have listeners for java.net.Socket, java.io.FileInputStream, etc.? Thanks, -- ymnk |
From: Eric D. <eri...@iu...> - 2005-02-02 09:51:59
|
> How about listening for the event at opening or establishing connection, > and how about monitoring data in inbound and outbound streams? > There should be many possibilities, but I'm still hesitated to add > listers. Do you know the reason why JDK API does not have listeners > for java.net.Socket, java.io.FileInputStream, etc.? > > Thanks, > -- > ymnk I'm not a =AB java guru =BB but why not considering the use of =20 java.lang.Object.notifyAll() and java.lang.Object.wait() instead of callbac= k=20 functions ? http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#notifyAll() http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#wait() with some nicely placed this.notifyAll() in jsch, we could write some: session.connect(); /* session is running */ session.wait(); /* we are sure session ended */ and eventually for channels, on so on for all runnable objects... It would be close to java.lang.Thread.join() without the nice feature of=20 waiting but only until a certain amount of time as in join(long) http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Thread.html#join() But in this case sessions and channels objects should be some childs of=20 Thread. Then we could write : session.connect(); /* session has started and may be running */ session.join(); /* we are sure session's thread has ended or died */ IMO second way may be better as in the first case, if an exception accurs,= =20 this.notifyAll() may not be reached and our user-thread would be endlessly= =20 blocked at wait()... Anyway i'm needing some solution to this problem as i need a way to lanch=20 remote commands, wait for some result and some others that depends on the=20 results ; or close some local ressources as some remote op as ended ; or=20 establish, close and reuse direct-tcpip raw data connections... =2D-=20 Eric D=C9CORNOD Ing=E9nieur en D=E9veloppement d'Applications ULP Multim=E9dia courriel: eri...@iu... |
From: Holger K. <li...@kl...> - 2005-02-02 14:56:02
Attachments:
jsch-patch.diff.tar.bz2
|
On Wednesday 02 February 2005 10:51, Eric DECORNOD wrote: > > How about listening for the event at opening or establishing connection, > > and how about monitoring data in inbound and outbound streams? > > There should be many possibilities, but I'm still hesitated to add > > listers. Do you know the reason why JDK API does not have listeners > > for java.net.Socket, java.io.FileInputStream, etc.? > > I'm not a « java guru » but why not considering the use of > java.lang.Object.notifyAll() and java.lang.Object.wait() instead of > callback functions ? While looking at it, I suspect that *Readers and *Writers themsselves should be considered as listeners. That way, what's missing is just a close being sent to the output/err stream of a ChannelExec (other Channels may vary). Patch included :-) > http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#notifyAll() > http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#wait() I just tried that but I don't get the "owner of the monitor" thing right. It's really tough when it comes to GUI threads... Mit freundlichem Gruß / With kind regards Holger Klawitter -- lists <at> klawitter <dot> de |
From: Kevin K. <ka...@um...> - 2005-02-03 23:30:20
|
Eric DECORNOD wrote: > I'm not a =AB java guru =BB but why not considering the use of > java.lang.Object.notifyAll() and java.lang.Object.wait() instead of > callback functions ? I'd say the listener approach is more elgant, in that those who don't wan= t to wait() on the remote command to finish can go on and do other things. I h= ave some occasions where I wait on the command to finish, and others where I = let it run asynchronously. If you really want to wait() on the remote execution = to complete, you can create your own lock object and wait on it in your thre= ad, and then let the ChannelListener's channelClosed method notify() the lock whe= n the listener is called by the channel's thread. To my way of thinking, it's much more straightforward to just let the lis= tener do the work for you rather than manage the wait/notify thing, and make su= re you have the monitor and that there isn't any other reason for notify to be c= alled on the synchronization object. The listener design is in keeping with the event-driven programming model, and I think it helps to decouple your app= code from the details of the Channel design. -Kevin |