libssh: Chapter 4: Passing a remote command

libssh 0.12.1 The SSH library

Loading...
Searching...
No Matches
Chapter 4: Passing a remote command

# Passing a remote command

Previous chapter has shown how to open a full shell session, with an attached terminal or not. If you only need to execute a command on the remote end, you don't need all that complexity.

The method described here is suited for executing only one remote command. If you need to issue several commands in a row, you should consider using a non-interactive remote shell, as explained in previous chapter.

See also
  shell

## Executing a remote command

The first steps for executing a remote command are identical to those for opening remote shells. You first need a SSH channel, and then a SSH session that uses this channel:

int show_remote_files(ssh_session session)
{
ssh_channel channel = NULL;
int rc;
channel = ssh_channel_new(session);
if (channel == NULL) return SSH_ERROR;
rc = ssh_channel_open_session(channel);
if (rc != SSH_OK)
{
ssh_channel_free(channel);
return rc;
}
ssh_channel_free
LIBSSH_API void ssh_channel_free(ssh_channel channel)
Close and free a channel.
Definition channels.c:1291
ssh_channel_new
LIBSSH_API ssh_channel ssh_channel_new(ssh_session session)
Allocate a new channel.
Definition channels.c:90
ssh_channel_open_session
LIBSSH_API int ssh_channel_open_session(ssh_channel channel)
Open a session channel (suited for a shell, not TCP forwarding).
Definition channels.c:1088

Once a session is open, you can start the remote command with ssh_channel_request_exec():

rc = ssh_channel_request_exec(channel, "ls -l");
if (rc != SSH_OK)
{
ssh_channel_close(channel);
ssh_channel_free(channel);
return rc;
}
ssh_channel_close
LIBSSH_API int ssh_channel_close(ssh_channel channel)
Close a channel.
Definition channels.c:1459
ssh_channel_request_exec
LIBSSH_API int ssh_channel_request_exec(ssh_channel channel, const char *cmd)
Run a shell command without an interactive shell.
Definition channels.c:2874

If the remote command displays data, you get them with ssh_channel_read(). This function returns the number of bytes read. If there is no more data to read on the channel, this function returns 0, and you can go to next step. If an error has been encountered, it returns a negative value:

char buffer[256];
int nbytes;
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
while (nbytes > 0)
{
if (fwrite(buffer, 1, nbytes, stdout) != nbytes)
{
ssh_channel_close(channel);
ssh_channel_free(channel);
return SSH_ERROR;
}
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
}
if (nbytes < 0)
{
ssh_channel_close(channel);
ssh_channel_free(channel);
return SSH_ERROR;
}
ssh_channel_read
LIBSSH_API int ssh_channel_read(ssh_channel channel, void *dest, uint32_t count, int is_stderr)
Reads data from a channel.
Definition channels.c:3136

Once you read the result of the remote command, you send an end-of-file to the channel, close it, and free the memory that it used:

ssh_channel_send_eof(channel);
ssh_channel_close(channel);
ssh_channel_free(channel);
return SSH_OK;
}
ssh_channel_send_eof
LIBSSH_API int ssh_channel_send_eof(ssh_channel channel)
Send an end of file on the channel.
Definition channels.c:1398

Warning: In a single channel, only ONE command can be executed! If you want to executed multiple commands, allocate separate channels for them or consider opening interactive shell. Attempting to run multiple consecutive commands in one channel will fail.