How to Run Local Scripts or commands on Remote Servers Using SSH:
A Guide for System Administrators:
Introduction
Hello, friends! Today, I am very excited to share a wonderful tool I have developed. It's a bash shell script that uses SSH to run local scripts or commands on remote servers. This tool is a game-changer for all system administrators. It's designed to make your work easier, faster, and more efficient.
Introducing myssh: Simplified SSH Script
I've created a special tool called "myssh". It's a bash script that simplifies SSH (Secure Shell) usage, making it much easier and more efficient.
Key Features of myssh:
Easy Remote Commands: Quickly run commands on remote servers.
Default Root User: Automatically uses 'root' if no user is specified.
Batch Operations: Run commands on several servers simultaneously.
Error Handling: Identifies unreachable hosts.
Install: Place it in /usr/bin/myssh and set permissions with chmod 700 /usr/bin/myssh.
Usage: Just type myssh [user@]host [command] to run a command on a remote server. same as ssh command.
Multiple Hosts: Manage many servers easily.
When you use myssh followed by the hostname (e.g., myssh [user@]host), it functions in the same way as the SSH command, enabling you to connect to and run commands on the remote host.
Setting Up myssh for Passwordless SSH Access
Step 1: User Configuration:
Begin by setting the DEFAULT_USER variable in the script. If you are using a non-root user for passwordless SSH access, replace DEFAULT_USER with your username. If you're using the root user, no changes are required.
# Default SSH user
DEFAULT_USER="root"
(to)
# Default SSH user
DEFAULT_USER="user_name"
Step 2: Script Installation:
To install myssh, copy the provided source code into a new file named /usr/bin/myssh on your Linux Jump Host.
This host should be configured to access your remote hosts using passwordless authentication.
Step 3: Setting Permissions:
After saving the script, change its permissions to ensure security and proper functioning. Execute the following commands:
Change the permission: chmod 700 /usr/bin/myssh
Set the owner (change root:root to your username and group if different): chown root:root /usr/bin/myssh
Note: Adjust the ownership command (chown) according to your specific user and group requirements.
These steps will establish myssh on your system, enabling efficient, passwordless SSH access to your remote hosts.
In my case, this involves setting up passwordless authentication for the root user.
Source code for the myssh tool. click hear to Download the script
#!/bin/bash
# Author: virtualnetworkingconcept.com
# ANSI codes for text colors
RED="\033[31m"
GREEN="\033[32m"
YELLOW="\033[33m"
RESET="\033[0m"
# Default SSH user
DEFAULT_USER="root"
# Function to display help/usage details
display_help() {
echo "Usage: myssh [SSH_OPTIONS] [USER@]HOST [COMMAND]"
echo
echo "Remote SSH with simplified and streamlined options."
echo
echo "EXAMPLES:"
echo -e "# myssh user@host 'uptime'"
echo -e "# myssh host 'uptime'"
echo -e "# myssh user@host 'tail -f /var/log/messages'"
echo
echo "# Report bugs to virtualnetworkingconcept.com"
echo
exit 0
}
# Check if the first argument is --help or -h
if [[ "$1" == "--help" || "$1" == "-h" || -z "$1" ]]; then
display_help
fi
# Construct the SSH target (user@host)
SSH_TARGET="$1"
if [[ "$SSH_TARGET" != *@* ]]; then
SSH_TARGET="${DEFAULT_USER}@${SSH_TARGET}"
fi
# Shift off the first argument (user@host)
shift
# Continue with the SSH command
ssh -q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes -o ConnectTimeout=2 -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o TCPKeepAlive=yes -o LogLevel=ERROR "${SSH_TARGET}" "$@"
# Check the exit status of the ssh command
if [ $? -eq 255 ]; then
host_only="${SSH_TARGET#*@}"
echo -e "$host_only ${YELLOW}Unreachable${RESET}"
exit 1
fi
Setting Up RunOnClient for Local scripts or commands execution on remote hosts using myssh.
Step 1: User Configuration
Begin by identifying the user account you intend to use for SSH connections. If you're using the root account, no changes are needed.
For non-root users, replace root user in the script with your specific username to enable passwordless SSH access.
Step 2: Script Installation
Copy the Script: Place the provided bash script into a file named /usr/bin/RunOnClient on your SSH Linux Jump Host.
Step 3: Setting Permissions
Secure the Script:
Modify the script's permissions for security and functionality: chmod 700 /usr/bin/RunOnClient
Change ownership to match your usage scenario (default is root:root): chown root:root /usr/bin/RunOnClient
Source code for the RunOnClient tool. click hear to Download the script
#!/bin/bash
#Author:www.virtualnetworkingconcept.com
# ANSI escape codes for text colors
BLACK="\033[30m"
RED="\033[31m"
GREEN="\033[32m"
YELLOW="\033[33m"
BLUE="\033[34m"
MAGENTA="\033[35m"
CYAN="\033[36m"
WHITE="\033[37m"
NC="\033[0m"
# Default SSH user
DEFAULT_USER="root"
# Function to display help/usage details
display_help() {
echo "Usage: $0"
echo
echo "Remote SSH with simplified and streamlined options."
echo
echo "Local script execution on a remote host:"
echo -e "${YELLOW}# RunOnClient local_script.sh <remote_hostname>${NC}"
echo
echo -e "Local script parallel execution on a multiple remote hosts: ${MAGENTA}>>>> High Speed >>>>${NC}"
echo -e "${GREEN}# RunOnClient local_script.sh <hosts_inventory.txt>${NC}"
echo
echo "Local script serial execution on a multiple remote hosts:"
echo -e "${CYAN}# RunOnClient local_script.sh <hosts_inventory.txt> -wait${NC}"
echo
echo -e "Execute commands parallel on multiple remote hosts: ${MAGENTA}>>>> High Speed >>>>${NC}"
echo -e "${GREEN}# RunOnClient <hosts_inventory.txt> <command>${NC}"
echo -e "${GREEN}# RunOnClient <hosts_inventory.txt> \"<commands>\"${NC}"
echo
echo "Execute commands serially on multiple remote hosts:"
echo -e "${CYAN}# RunOnClient <hosts_inventory.txt> -wait <command>${NC}"
echo -e "${CYAN}# RunOnClient <hosts_inventory.txt> -wait \"<commands>\"${NC}"
echo
echo "Execute command on a remote hosts:"
echo -e "${YELLOW}# myssh <remote_hostname> <command>${NC}"
echo
echo "Report bugs to www.virtualnetworkingconcept.com"
exit 0
}
# Check if the first argument is --help or -h
if [[ "$1" == "--help" || "$1" == "-h" || -z "$1" ]] && [[ ! "$2" =~ \.(sh|ksh|bash|csh|tcsh|zsh)$ ]]; then
display_help
fi
#-----------------------------------------------------------------------------#
# Check if the script is called with exactly one argument inventory file
if [ -n "$1" ] && [ -n "$2" ] && [ -f "$2" ] && [ "$3" != "-wait" ] && [[ "$1" =~ \.(sh|ksh|bash|csh|tcsh|zsh)$ ]] && [[ ! "$2" =~ \.(sh|ksh|bash|csh|tcsh|zsh)$ ]]; then
script_execution="$1"
remote_hostname="$2"
# Maximum number of parallel connections
MAX_PARALLEL=100
count=0
# Read hosts into an array
mapfile -t hosts <<< "$(sed '/^$/d;s/ //g' "$remote_hostname" | grep '.'| sort -fu)"
# Start SSH connections
for host in "${hosts[@]}"; do
cat "$script_execution" | myssh "${DEFAULT_USER}"@$host 'bash -s' &
((count++))
# Wait for current batch to finish before starting new connections
if [[ $count -ge $MAX_PARALLEL ]]; then
wait
count=0
fi
done
wait
#-----------------------------------------------------------------------------#
# Check if the script is called for single hostname
elif [ -n "$1" ] && [[ "$1" =~ \.(sh|ksh|bash|csh|tcsh|zsh)$ ]] && [ -n "$2" ] && [ ! -f "$2" ] && [ "$3" != "-wait" ]; then
script_execution="$1"
remote_hostname="$2"
#Start SSH connections
cat "$script_execution" | myssh "${DEFAULT_USER}"@"$remote_hostname" 'bash -s'
#-----------------------------------------------------------------------------#
# Check if the script is called with an inventory file and a command
elif [[ -n "$1" ]] && [[ -n "$2" ]] && [[ -f "$1" ]] && [[ ! "$1" =~ \.(sh|ksh|bash|csh|tcsh|zsh)$ ]] && [[ ! -f "$2" ]] && [[ "$2" != "-wait" ]] && [[ "$3" != "-wait" ]]; then
inventory_file="$1"
command_to_execute="$2"
# Maximum number of parallel connections
MAX_PARALLEL=100
count=0
# Read hosts into an array
mapfile -t hosts <<< "$(sed '/^$/d;s/ //g' "$inventory_file" | grep '.'| sort -fu)"
# Start SSH connections to execute the command
for host in "${hosts[@]}"; do
myssh "${DEFAULT_USER}"@"$host" "$command_to_execute" 2>&1 | sed "s|^|$host: |" || true &
((count++))
# Wait for current batch to finish before starting new connections
if [[ $count -ge $MAX_PARALLEL ]]; then
wait
count=0
fi
done
wait
#-----------------------------------------------------------------------------#
# Check if the script is called with an inventory file and a command for single hostname from inventory file
elif [[ -n "$1" ]] && [[ -n "$2" ]] && [[ -n "$3" ]] && [[ -f "$1" ]] && [[ ! "$1" =~ \.(sh|ksh|bash|csh|tcsh|zsh)$ ]] && [[ ! -f "$2" ]] && [[ "$3" != "-wait" ]] && [[ "$2" == "-wait" ]]; then
inventory_file="$1"
command_to_execute="$3"
# Read hosts into an array
mapfile -t hosts <<< "$(sed '/^$/d;s/ //g' "$inventory_file" | grep '.'| sort -fu)"
# Start SSH connections to execute the command
for host in "${hosts[@]}"; do
myssh "${DEFAULT_USER}"@"$host" "$command_to_execute" 2>&1 | sed "s|^|$host: |" || true &
echo "-"
wait
done
#-----------------------------------------------------------------------------#
# Check if the script is called for single hostname from inventory file.
elif [ -n "$1" ] && [ -n "$2" ] && [ -f "$2" ] && [ "$3" == "-wait" ] && [[ "$1" =~ \.(sh|ksh|bash|csh|tcsh|zsh)$ ]]; then
script_execution="$1"
remote_hostname="$2"
# Read hosts into an array
mapfile -t hosts <<< "$(sed '/^$/d;s/ //g' "$remote_hostname" | grep '.'| sort -fu)"
# Start SSH connections
for host in "${hosts[@]}"; do
cat "$script_execution" | myssh "${DEFAULT_USER}"@$host 'bash -s' &
wait
done
#-----------------------------------------------------------------------------#
else
echo "Usage: $0"
echo
echo "Remote SSH with simplified and streamlined options."
echo
echo "Local script execution on a remote host:"
echo -e "${YELLOW}# RunOnClient local_script.sh <remote_hostname>${NC}"
echo
echo -e "Local script parallel execution on a multiple remote hosts: ${MAGENTA}>>>> High Speed >>>>${NC}"
echo -e "${GREEN}# RunOnClient local_script.sh <hosts_inventory.txt>${NC}"
echo
echo "Local script serial execution on a multiple remote hosts:"
echo -e "${CYAN}# RunOnClient local_script.sh <hosts_inventory.txt> -wait${NC}"
echo
echo -e "Execute commands parallel on multiple remote hosts: ${MAGENTA}>>>> High Speed >>>>${NC}"
echo -e "${GREEN}# RunOnClient <hosts_inventory.txt> <command>${NC}"
echo -e "${GREEN}# RunOnClient <hosts_inventory.txt> \"<commands>\"${NC}"
echo
echo "Execute commands serially on multiple remote hosts:"
echo -e "${CYAN}# RunOnClient <hosts_inventory.txt> -wait <command>${NC}"
echo -e "${CYAN}# RunOnClient <hosts_inventory.txt> -wait \"<commands>\"${NC}"
echo
echo "Execute command on a remote hosts:"
echo -e "${YELLOW}# myssh <remote_hostname> <command>${NC}"
echo
echo "Report bugs to www.virtualnetworkingconcept.com"
exit 0
fi
#-----------------------------------------------------------------------------#
# Optionally, wait for all connections to complete
wait
Script Features and Operations
The RunOnClient script supports various operations for efficient remote management:
To get the help message about RunOnClient & myssh on your Jump Host:
Command:
# RunOnClient -h
# RunOnClient --help
# RunOnClient
# myssh -h
# myssh --help
# myssh
Execute Local Script on Remote Host:
Command:
# RunOnClient local_script.sh <remote_hostname>
Parallel Execution on Multiple Hosts (High Speed):
For scripts:
# RunOnClient local_script.sh <hosts_inventory.txt>
For commands:
# RunOnClient <hosts_inventory.txt> "<command>"
Serial Execution on Multiple Hosts:
For scripts:
# RunOnClient local_script.sh <hosts_inventory.txt> -wait
For commands:
# RunOnClient <hosts_inventory.txt> -wait "<command>"
Execute Command on Single Remote Host:
Command:
# myssh <remote_hostname> <command>
Conclusion
As system administrators, our job is to make things run smoothly and efficiently. With this tool, you'll be able to handle remote tasks with ease, giving you more time to focus on other important aspects of your work.