Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The overall structure is as follow:
2. RServer&CommandlineScreen - A guide to using RServer and the Commandline
3. PureCommandLine - A guide to using pure commandline
4. Slurm - A guide to using our job scheduler.
5. Tools - Contains script for adding SSH aliases for Euclid servers.
5. Tools - Student-written tools for: adding SSH aliases for Euclid servers, checking live usage, checking a program is installed etc.
6. BasicCommands - A collection of simple commands for connecting to the servers.

## Command line use.
Expand Down
15 changes: 14 additions & 1 deletion tools/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Euclid Tools
This folder contains command line tools useful for working with the Euclids.
This folder contains student-written command line tools which you may find useful for working with the Euclids.

Use at your own risk, and always be careful not to cause any disruption to other users or access machines which you do not have permission to use. The lists of restricted-access and general-use Euclid machines on which these scripts rely were correct as of January 2026.

## Create SSH Aliases
To prevent you having to type out `<login_name>@euclid-<number>.maths.gla.ac.uk` every time, aliases for servers can be added to your SSH config file, usually located at `~/.ssh/config`.
Expand All @@ -14,3 +16,14 @@ Host euclid-01 # Alias of your choice
For Unix/WSL/MacOS, these aliases can be added to your SSH config file using the script located at `tools/euclid-ssh-aliases/create-euclid-aliases.sh`. Use `create-euclid-aliases.sh -h` for help menu. By default aliases will only be created for Euclids with unrestricted access.

For Windows, copy the config file you wish to use, use a find-and-replace tool to replace `<euclid-username>` with your username, and copy into `~/.ssh/config` (where `~/` specifies your home folder on your machine).

## Check Installed & Usage
These helper scripts check all public Euclids for the existence of a particular command (check_installed.sh) or the live CPU/Memory/GPU utilisation (usage.sh).

These can be modified to include other Euclids to which you have access by modifying the "SERVERS" variable in each script.

To add aliases for these scripts, you can add the following to your `~/.bashrc` file:
```bash
alias euclid-usage='./path/to/ServerInfo/tools/usage.sh'
alias euclid-installed='./path/to/ServerInfo/tools/check_installed.sh'
```
74 changes: 74 additions & 0 deletions tools/check_installed.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/bin/bash
# Student-written helper script which uses "command" to check whether a command exists on each of the Euclids.
# Use at own risk, and always be careful not to cause any disruption to other users or access machines which you do not have permission to use.
# Specify --pip to check Python libraries instead of installed applications.

UNRESTRICTED_SERVERS="01 02 04 05 10 18 19 21 23 25 26 27 28 29 30"
RESTRICTED_SERVERS="03 06 07 08 09 12 17 22 24 32 35 36 37 "
SLURM_SERVERS="13 14 15 16 20 31 33"
RETIRED_SERVERS="11 34"

SERVERS=$UNRESTRICTED_SERVERS

cmdToCheck=$1

function cleanup {
echo ""
}
trap cleanup EXIT

if [[ -z $cmdToCheck ]]; then
echo "No command to check installation status specified, exiting."
echo "Usage: ./check_installed.sh <command to check>"
exit
fi

while true; do
read -p "Check whether command '$cmdToCheck' exists on the euclid servers? Y/n " yn
case $yn in
[Yy]* ) break;;
[Nn]* ) exit;;
* ) echo "Please answer Y/n.";;
esac
done

# Run command & save output to temp directory
tmpdir=$(mktemp -d)
if [[ $* == *--pip* ]]; then
cmd="pip list | grep '$cmdToCheck '"
else
cmd="command -v $cmdToCheck" # Command to run on each euclid
fi
for euclid in $SERVERS; do
echo $(if out=$(ssh "euclid-$euclid" -q -o RemoteCommand="$cmd" 2>&1); then
echo "$out"
else
echo "Not installed"
fi
) > $tmpdir/euclid-$euclid &
done

# Display outputs:
n_servers=$(echo $SERVERS | wc --words)
while :; do
done_count=0
for euclid in $SERVERS; do
if [[ -f "$tmpdir/euclid-$euclid" ]]; then
printf "euclid-$euclid: %s\n" "$(tr '\n' ' ' < $tmpdir/euclid-$euclid)"
((done_count++))
else
printf "euclid-$euclid:\n"
fi
done

# Break if all servers have responded
((done_count == n_servers)) && break

# Move cursor back to top
printf "\033[${n_servers}A"

# Wait before re-checking
sleep 0.2
done

rm -r "$tmpdir"
59 changes: 59 additions & 0 deletions tools/usage.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/bin/bash
# Usage: usage.sh [euclid ids to check usage of]
# Student-written helper script to check the live CPU/Memory/GPU utilisation of the Euclid servers.
# Use at own risk, and always be careful not to cause any disruption to other users or access machines which you do not have permission to use.

UNRESTRICTED_SERVERS="01 02 04 05 10 18 19 21 23 25 26 27 28 29 30"
RESTRICTED_SERVERS="03 06 07 08 09 12 17 22 24 32 35 36 37 "
SLURM_SERVERS="13 14 15 16 20 31 33"
RETIRED_SERVERS="11 34"

SERVERS=$UNRESTRICTED_SERVERS

if [[ $# > 0 ]]; then
SERVERS="$@"
fi

# Run command & save output to temp directory
tmpdir=$(mktemp -d)
run_cmd(){
ssh "euclid-$euclid" -q -o RemoteCommand="$1"
}
for euclid in $SERVERS; do
run_cmd "top -bn 5 -d 0.1 -E M" | grep -e '^%Cpu' -e '^MiB Mem' | tail -n 2 > $tmpdir/euclid-$euclid-cpu-mem &
run_cmd "lscpu" > $tmpdir/euclid-$euclid-lscpu &
run_cmd "if [[ \$(command -v nvidia-smi) ]]; then nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader,nounits; else echo '-1'; fi" > $tmpdir/euclid-$euclid-gpu & # Saves each GPU percentage to a newline
done

# Display outputs:
n_servers=$(echo $SERVERS | wc --words)
echo "Total CPU Usage; Total Mem Usage; Physical(Logical) Cores; Total Mem; GPU Utilisation per GPU"
while :; do
done_count=0
for euclid in $SERVERS; do
if [[ -s "$tmpdir/euclid-$euclid-cpu-mem" && -s "$tmpdir/euclid-$euclid-lscpu" && -s "$tmpdir/euclid-$euclid-gpu" ]]; then
cpu_usage=$(cat $tmpdir/euclid-$euclid-cpu-mem | grep -e '^%Cpu' | awk -F'[, ]+' '{print $2+$4+$6}')
mem_usage=$(cat $tmpdir/euclid-$euclid-cpu-mem | grep -e '^MiB Mem' | awk -F'[, ]+' '{print $8*100/$4}')
mem_size=$(cat $tmpdir/euclid-$euclid-cpu-mem | grep -e '^MiB Mem' | awk -F'[, ]+' '{print $4/1024}')
cores=$(cat $tmpdir/euclid-$euclid-lscpu | grep -e '^Core(s) per socket' -e 'Socket(s)' | paste -s | awk '{print $4*$6}')
threads=$(cat $tmpdir/euclid-$euclid-lscpu | grep '^CPU(s)' | awk '{print $2}')
gpu_file=$(cat $tmpdir/euclid-$euclid-gpu)
gpu_string=$(if [[ $gpu_file == "-1" || $gpu_file == *failed* ]]; then echo ""; else printf " %s%% GPU" "$(echo $gpu_file | tr ' ' ', ')"; fi)
printf "euclid-$euclid: %5.1f%% CPU %5.1f%% Mem %-3d(%-3d) Cores %4.0f GiB%s\n" $cpu_usage $mem_usage $cores $threads $mem_size "$gpu_string"
((done_count++))
else
printf "euclid-$euclid:\n"
fi
done

# Break if all servers have responded
((done_count == n_servers)) && break

# Move cursor back to top
printf "\033[${n_servers}A"

# Wait before re-checking
sleep 0.5
done

rm -r "$tmpdir"