1. Introduction

In today’s world, remote access to another machine is essential for many system administrators and developers. The most common way of accessing a remote machine is through the Secure Shell (SSH) protocol.

SSH provides secure, encrypted communication between two untrusted hosts over an insecure network. It’s widely used for managing remote machines and transferring files. However, we often need to send commands to a remote machine from a shell script that’s run on the local machine.

In this tutorial, we’ll discuss how to send commands to a remote machine from a shell script without starting another SSH session.

2. Using SSH

The most straightforward way of sending commands to the remote machine is by using the SSH protocol. The following is a sample command that sends a command to a remote machine and captures the output:

output=$(ssh user@remote_machine ls -l)
echo "$output"

The command sends the ls -l command to the remote machine and captures the output in the variable output. We nathen print the output to the terminal.

However, the above approach requires a new SSH session to be started for every command that we want to send. This can be slow and resource-intensive, especially when we want to send many commands in a short amount of time.

3. Using Expect

Expect is a tool that automates interactions with other programs. It can be used to send commands to a remote machine through an already open connection. The following is a sample script that uses Expect to send a command to a remote machine and captures the output:

#!/usr/bin/expect

set timeout 30
spawn ssh user@remote_machine
expect "$"
send "ls -l\r"
expect "$ "
set output $expect_out(buffer)
puts $output

The script uses Expect to spawn an SSH connection to the remote machine and sends the ls -l command. The output is captured in the variable output and printed to the terminal.

Expect can be difficult to use, especially for those who are unfamiliar with the syntax.

4. Using Netcat

Netcat is a simple and versatile tool that can be used to send commands to a remote machine through an already open connection. Let’s see a sample command that uses Netcat to send a command to a remote machine and captures the output:

output=$(echo "ls -l" | nc remote_machine 22)
echo "$output"

The command sends the ls -l command to the remote machine through port 22 (the default SSH port) and captures the output. We then print the output to the terminal.

It’s worth noting doesn’t provide the same level of security as the SSH protocol.

5. Using Named Pipes

Named pipes are a special type of file that can be used to communicate between two processes. The following is a sample script that uses a named pipe to send a command to a remote machine and captures the output:

#!/bin/bash

pipe_file="my_pipe"

# Create the named pipe
if [ ! -p "$pipe_file" ]; then
  mkfifo "$pipe_file"
fi

# Start a new ssh session and connect the input and output of the shell to the named pipe
ssh user@remote_machine < "$pipe_file" | tee "$pipe_file" &

# Wait for the ssh session to start
sleep 1

# Send commands to the remote machine through the named pipe
echo "ls -l" > "$pipe_file"
output=$(cat "$pipe_file")

# Clean up the named pipe
rm "$pipe_file"

# Print the output
echo "$output"

The above script creates a named pipe and starts a new SSH session. The input and output of the shell are connected to the named pipe. The script then sends commands to the remote machine through the named pipe and captures the output. Finally, the script cleans up the named pipe and prints the output.

Named pipes are not as well-known or widely used as other methods, such as Expect or Netcat.

6. Conclusion

In this article, we discussed various methods for sending commands to a remote machine from a shell script that’s run on the local machine, using the already open connection, and without starting another SSH session.

These methods include using SSH, Expect, Netcat, and named pipes. Each method has its own advantages and disadvantages, and the best method depends on our specific requirements and preferences.

Regardless of the method used, it’s important to carefully consider the security implications of sending commands to a remote machine.