Sample code for 30+ languages & platforms
Lazarus Pascal

Read Data from an SSH Channel

See more SSH Examples

Demonstrates the Chilkat Ssh.ChannelRead method, which reads incoming SSH channel messages. The only argument is the channel number; the ReadTimeoutMs property limits how long it waits. Received data is appended to the channel's receive buffer, then retrieved with a GetReceived... method.

The integer return value is -1 on error, -2 if nothing arrived before the timeout, 0 if EOF or channel close was processed, or — when greater than 0 — the total bytes currently buffered for the channel (not the bytes newly received by this call).

Background: SSH reading is a two-step pattern that trips people up at first: the Channel* read/poll methods move bytes from the network into an internal per-channel buffer, and a separate GetReceived... call hands that buffer to your code. A positive return is therefore a buffer total, not a count of what this call fetched. Note that a 0 return means EOF or close — buffered data can still remain and should be drained.

Chilkat Lazarus Pascal Downloads

Lazarus Pascal
program ChilkatDemo;

// Demonstrates using the Chilkat Pascal wrapper via the C bridge DLL.
// Builds as a console application under Lazarus (FPC) or Delphi.

{$IFDEF FPC}
  {$MODE DELPHI}
{$ENDIF}
{$APPTYPE CONSOLE}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  SysUtils,
  CkDllLoader,
  Chilkat.Ssh;

// ---------------------------------------------------------------------------

procedure RunDemo;
var
  success: Boolean;
  ssh: TSsh;
  sshPort: Integer;
  password: string;
  channelNum: Integer;
  result: Integer;
  output: string;

begin
  success := False;

  //  Demonstrates the Ssh.ChannelRead method, which reads incoming SSH channel messages.  The only
  //  argument is the channel number.  The ReadTimeoutMs property limits how long it waits.

  ssh := TSsh.Create;

  sshPort := 22;
  success := ssh.Connect('ssh.example.com',sshPort);
  if (success = False) then
    begin
      WriteLn(ssh.LastErrorText);
      Exit;
    end;

  //  Normally you would not hard-code the password in source.  You should instead obtain it
  //  from an interactive prompt, environment variable, or a secrets vault.
  password := 'mySshPassword';

  success := ssh.AuthenticatePw('mySshLogin',password);
  if (success = False) then
    begin
      WriteLn(ssh.LastErrorText);
      Exit;
    end;

  channelNum := ssh.OpenSessionChannel();
  if (channelNum < 0) then
    begin
      WriteLn(ssh.LastErrorText);
      Exit;
    end;

  //  Start a shell WITHOUT requesting a PTY.  Without a PTY the shell sees it is connected to a
  //  raw data pipe and enters non-interactive mode: it suppresses the command prompt, does not
  //  echo typed commands back, and skips interactive login scripts.  The output is therefore
  //  clean and easily parseable -- but because no prompt is ever sent, code must not wait for
  //  one.  Instead, have each command print a predictable marker, or wait for EOF / channel close.
  success := ssh.SendReqShell(channelNum);
  if (success = False) then
    begin
      WriteLn(ssh.LastErrorText);
      Exit;
    end;

  success := ssh.ChannelSendString(channelNum,'uname -a' + #10,'utf-8');
  if (success = False) then
    begin
      WriteLn(ssh.LastErrorText);
      Exit;
    end;

  //  The return value is: -1 on error, -2 if nothing arrived before the timeout, 0 if EOF or
  //  channel close was processed, or the total number of buffered bytes when greater than 0.
  result := ssh.ChannelRead(channelNum);
  if (result = -1) then
    begin
      WriteLn(ssh.LastErrorText);
      Exit;
    end;

  if (result = -2) then
    begin
      WriteLn('No channel data arrived before the timeout.');
    end;

  if (result = 0) then
    begin
      WriteLn('EOF or channel close was processed.  Buffered data may still remain.');
    end;

  if (result > 0) then
    begin
      WriteLn('Total bytes buffered: ' + result);
    end;

  output := ssh.GetReceivedText(channelNum,'utf-8');
  if (ssh.LastMethodSuccess = False) then
    begin
      WriteLn(ssh.LastErrorText);
      Exit;
    end;
  WriteLn(output);

  ssh.Disconnect();


  ssh.Free;

end;

// ---------------------------------------------------------------------------

begin

  try
    RunDemo;
  except
    on E: Exception do
      WriteLn('Unhandled exception: ', E.ClassName, ': ', E.Message);
  end;

  WriteLn;
  {$IFDEF MSWINDOWS}
  WriteLn('Press Enter to exit...');
  ReadLn;
  {$ENDIF}
end.