Run ssh and immediately execute command

Learn run ssh and immediately execute command with practical examples, diagrams, and best practices. Covers bash, unix, ssh development techniques with visual explanations.

Executing Commands Remotely with SSH: A Comprehensive Guide

Hero image for Run ssh and immediately execute command

Learn how to immediately execute commands on a remote server using SSH, covering various methods, best practices, and common pitfalls for efficient remote administration.

Secure Shell (SSH) is an indispensable tool for system administrators and developers, enabling secure remote access to servers. Beyond simply logging in, SSH offers powerful capabilities for executing commands directly on a remote machine without an interactive shell session. This article explores the various ways to run commands immediately upon connecting via SSH, from basic single commands to complex scripts, ensuring you can automate tasks and manage remote systems efficiently.

Basic Command Execution

The most straightforward way to execute a command remotely is to append it directly to your ssh command. When you do this, SSH connects to the remote host, executes the specified command, and then immediately disconnects. This is ideal for one-off tasks or simple automation.

ssh user@remote_host "command_to_execute"

Basic SSH command execution

For example, to check the disk usage on a remote server, you would use:

ssh user@remote_host "df -h"

Checking disk usage on a remote host

Executing Multiple Commands or Scripts

When you need to run more than one command or an entire script, you have several options. You can chain commands using shell operators like && or ;, or you can pipe a local script directly to the remote SSH session.

flowchart TD
    A[Local Machine] --> B{"SSH Connection"}
    B --> C{"Execute Command(s)"}
    C --> D[Remote Machine]
    D --> E{"Return Output & Exit"}
    E --> A

Flow of an SSH command execution

Chaining Commands

To execute multiple commands sequentially, you can separate them with a semicolon (;) or use && for conditional execution (where the next command only runs if the previous one succeeded).

ssh user@remote_host "cd /var/log && ls -l | grep auth.log"
ssh user@remote_host "mkdir -p /tmp/my_dir; echo 'Hello' > /tmp/my_dir/file.txt"

Chaining multiple commands

Piping Local Scripts

For more complex operations, it's often cleaner to write a script locally and then pipe its content to the remote SSH session. The remote shell will execute the piped script as if it were a local input.

# Create a local script
echo '#!/bin/bash\nDATE=$(date)\necho "Current date on remote: $DATE"' > local_script.sh

# Execute the local script remotely via pipe
cat local_script.sh | ssh user@remote_host bash

Piping a local script to a remote host

Handling Input and Output

When executing commands remotely, understanding how standard input (stdin), standard output (stdout), and standard error (stderr) are handled is crucial. By default, stdout and stderr from the remote command are sent back to your local terminal.

Redirecting Output

You can redirect output on the remote host just as you would locally. For example, to save the output of a remote command to a file on the remote server:

ssh user@remote_host "ls -l /var/log > /tmp/remote_logs.txt"

Redirecting remote command output to a file on the remote host

To redirect output to a local file, you would use local shell redirection:

ssh user@remote_host "df -h" > local_disk_usage.txt

Redirecting remote command output to a local file

Advanced Scenarios and Considerations

Beyond basic execution, SSH offers options for pseudo-terminal allocation, background processes, and environment variables.

Pseudo-Terminal Allocation (-t)

By default, when you execute a command remotely, SSH does not allocate a pseudo-terminal. This means that interactive commands or programs that expect a TTY might behave unexpectedly. The -t option forces pseudo-terminal allocation.

ssh -t user@remote_host "sudo apt update"

Forcing pseudo-terminal allocation for interactive commands

Running Commands in the Background

To run a command on the remote host and have it continue running after your SSH session disconnects, you can use nohup or screen/tmux.

ssh user@remote_host "nohup /path/to/long_running_script.sh > /dev/null 2>&1 &"

Running a script in the background using nohup

Passing Environment Variables

You can pass local environment variables to the remote session using the SendEnv directive in your SSH client configuration or the -o SendEnv option on the command line. However, the remote SSH server must be configured to accept these variables (via AcceptEnv in sshd_config). A more common and reliable approach is to explicitly pass them as part of the command string.

LOCAL_VAR="my_value"
ssh user@remote_host "REMOTE_VAR=$LOCAL_VAR echo \"Remote variable is: $REMOTE_VAR\""

Passing a local variable to a remote command