Skip to content

Instantly share code, notes, and snippets.

@jarib
Created July 24, 2008 21:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jarib/2298 to your computer and use it in GitHub Desktop.
Save jarib/2298 to your computer and use it in GitHub Desktop.
require 'java'
require 'jsch-0.1.38.jar'
class SSH
include_package "com.jcraft.jsch"
def initialize(host, username, password)
@client = JSch.new
@session = @client.getSession(username, host, 22)
@session.setPassword(password)
@session.setConfig("StrictHostKeyChecking", "no")
@session.connect(5000)
@channels = []
end
def execute_command(command)
channel, input = channel_input_for_command(command)
channel.connect
@channels << channel
tmp = ('0'*1024).to_java_bytes
result = ''
until channel.isClosed
while input.available > 0
i = input.read(tmp, 0, 1024)
break if i < 0
result << java.lang.String.new(tmp, 0, i).to_s
end
end
result
end
def tail(files, &block)
channel, input = channel_input_for_command("tail -F -n 1 #{files}")
channel.setPty(true)
@channels << channel
channel.connect
tmp = ('0'*1024).to_java_bytes
string = ''
until channel.isClosed
while input.available > 0
i = input.read(tmp, 0, 1024)
break if i < 0
string << java.lang.String.new(tmp, 0, i).to_s
end
unless string.empty?
yield string
string = ''
end
end
end
def close
@channels.each { |c| c.disconnect }
@session.disconnect
true
end
private
def channel_input_for_command(command)
channel = @session.openChannel("exec")
channel.setCommand(command)
channel.setInputStream(nil)
[channel, channel.getInputStream]
end
end
at_exit { puts "main thread exiting" }
ssh = SSH.new('localhost', 'jarib', 'foo')
puts ssh.execute_command("ls")
# prints "main thread exiting", then just hangs
# if ssh.close is called, it exits fine
Full thread dump Java HotSpot(TM) 64-Bit Server VM (1.6.0_05-b13-52 mixed mode):
"DestroyJavaVM" prio=5 tid=0x0000000101801000 nid=0x100401000 waiting on condition [0x0000000000000000..0x0000000100400aa0]
java.lang.Thread.State: RUNNABLE
"Connect thread localhost session" prio=5 tid=0x000000010197c800 nid=0x12aafa000 runnable [0x000000012aaf9000..0x000000012aaf9ad0]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at com.jcraft.jsch.IO.getByte(IO.java:82)
at com.jcraft.jsch.Session.read(Session.java:795)
at com.jcraft.jsch.Session.run(Session.java:1160)
at java.lang.Thread.run(Thread.java:637)
"Low Memory Detector" daemon prio=5 tid=0x0000000101844800 nid=0x12a0f7000 runnable [0x0000000000000000..0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"CompilerThread1" daemon prio=9 tid=0x0000000101843000 nid=0x129ff4000 waiting on condition [0x0000000000000000..0x0000000129ff23e0]
java.lang.Thread.State: RUNNABLE
"CompilerThread0" daemon prio=9 tid=0x0000000101841800 nid=0x129ef1000 waiting on condition [0x0000000000000000..0x0000000129eef3e0]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" daemon prio=9 tid=0x0000000101841000 nid=0x129dee000 waiting on condition [0x0000000000000000..0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" daemon prio=8 tid=0x0000000101829800 nid=0x129ceb000 in Object.wait() [0x0000000129cea000..0x0000000129ceaad0]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000010f73b138> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:116)
- locked <0x000000010f73b138> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:132)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
"Reference Handler" daemon prio=10 tid=0x0000000101828800 nid=0x129be8000 in Object.wait() [0x0000000129be7000..0x0000000129be7ad0]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000010f73b218> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:485)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
- locked <0x000000010f73b218> (a java.lang.ref.Reference$Lock)
"VM Thread" prio=9 tid=0x0000000101820800 nid=0x129ae5000 runnable
"VM Periodic Task Thread" prio=10 tid=0x0000000101846000 nid=0x12a1fa000 waiting on condition
"Exception Catcher Thread" prio=10 tid=0x0000000101802000 nid=0x100504000 runnable
JNI global references: 782
Heap
def new generation total 2304K, used 1932K [0x0000000105000000, 0x0000000105290000, 0x000000010f6a0000)
eden space 1984K, 88% used [0x0000000105000000, 0x00000001051b6708, 0x00000001051f0000)
from space 320K, 55% used [0x0000000105240000, 0x000000010526c930, 0x0000000105290000)
to space 320K, 0% used [0x00000001051f0000, 0x00000001051f0000, 0x0000000105240000)
tenured generation total 5312K, used 4069K [0x000000010f6a0000, 0x000000010fbd0000, 0x0000000124400000)
the space 5312K, 76% used [0x000000010f6a0000, 0x000000010fa99770, 0x000000010fa99800, 0x000000010fbd0000)
compacting perm gen total 21248K, used 18600K [0x0000000124400000, 0x00000001258c0000, 0x0000000129800000)
the space 21248K, 87% used [0x0000000124400000, 0x000000012562a360, 0x000000012562a400, 0x00000001258c0000)
No shared spaces configured.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment