Skip to content

Instantly share code, notes, and snippets.

@abhisekp
Last active January 9, 2024 05:42
Show Gist options
  • Save abhisekp/c4625eb8f324991957520c8a7c1e15cb to your computer and use it in GitHub Desktop.
Save abhisekp/c4625eb8f324991957520c8a7c1e15cb to your computer and use it in GitHub Desktop.
Compile and Run rust file provided either from file path or piped

Rust Compile, Run, and Clean Script

This Bash script provides a convenient way to compile, run, and optionally delete a Rust executable. It supports various options, including running in a temporary directory, watching for file changes, sending desktop notifications, and installing the script to the user's local ~/bin directory.

Features

Compile and Run

The script compiles and runs a given Rust file. If the compilation and execution are successful, it deletes the generated executable.

Example:

./compile_and_run_rust.sh intro2.rs

Temporary Directory

The -t or --temp option allows the script to compile and run the Rust file in a temporary directory. This is useful to avoid cluttering your working directory with executables.

Example:

./compile_and_run_rust.sh -t intro2.rs

Watch Mode

The -w or --watch option enables a watch mode. In this mode, the script monitors the specified Rust file for changes. If the file is modified, the script will re-compile, run, and optionally delete the executable. The script uses inotifywait for efficient file monitoring, and falls back to sleep and checksum if inotifywait is not available.

Example:

./compile_and_run_rust.sh -w intro2.rs

Notifications

The -n or --notify option enables desktop notifications. A notification with low urgency is sent upon successful compilation, and a notification with critical urgency is sent upon compilation failure.

Example:

./compile_and_run_rust.sh -n intro2.rs

Install Script

The --install option installs the script to the ~/bin directory. If ~/bin is not in your PATH, the script provides instructions to add it.

Example:

./compile_and_run_rust.sh --install

Help Text

The -h or --help option displays a help text that explains how to use the script and its options. The help text is colorized for better readability.

Example:

./compile_and_run_rust.sh -h

Piping Support

You can pipe a Rust file into the script. This is useful when you want to quickly run a Rust file without specifying its name.

Example:

cat intro2.rs | ./compile_and_run_rust.sh

Code

Here's the full script:

See compile_and_run_rust.sh file.

Download and Run the file

curl -O https://gist.githubusercontent.com/abhisekp/c4625eb8f324991957520c8a7c1e15cb/raw/497cca2d7bc310821bccc55e86880369f7013648/compile_and_run_rust.sh && chmod +x compile_and_run_rust.sh && ./compile_and_run_rust.sh

Requirements

  • Bash
  • inotifywait for watch mode (optional)
  • notify-send for notifications (optional)

Installation

  1. Save the script into a file, for example, compile_and_run_rust.sh.
  2. Make the script executable: chmod +x compile_and_run_rust.sh.

Usage

Run the script with the desired options and the Rust file as an argument. For example, to compile, run, and clean intro2.rs in a temporary directory while watching for changes and sending notifications:

./compile_and_run_rust.sh -t -w -n intro2.rs
#!/bin/bash
# Function to display help text
display_help() {
echo -e "\e[36mUsage: $0 [OPTION]... [FILE]\e[0m"
echo -e "Compile, run, and optionally delete a Rust executable."
echo
echo -e "\e[32m -t, --temp \e[37mcompile and run in a temporary directory\e[0m"
echo -e "\e[32m -w, --watch \e[37mwatch for file changes and recompile\e[0m"
echo -e "\e[32m -n, --notify \e[37msend desktop notifications\e[0m"
echo -e "\e[32m --install \e[37minstall this script to ~/bin\e[0m"
echo -e "\e[32m -h, --help \e[37mdisplay this help and exit\e[0m"
echo
echo -e "\e[33mTo add ~/bin to your PATH, add the following line to your .bashrc or .zshrc:\e[0m"
echo -e "\e[35mexport PATH=\$PATH:~/bin\e[0m"
echo
echo -e "\e[33mYou can also pipe a Rust file into this script:\e[0m"
echo -e "\e[35mcat intro2.rs | $0\e[0m"
}
# Function to compile, run, and optionally delete a Rust executable
compile_and_run_rust() {
clear # Clear the screen before each run
local use_temp_dir=$1
local rust_file=$2
local notify=$3
local abs_path=$(realpath "$rust_file")
# Extract the filename without extension
filename=$(basename -- "$rust_file")
filename_no_ext="${filename%.*}"
# Determine the directory to use
if [ "$use_temp_dir" -eq 1 ]; then
dir=$(mktemp -d)
else
dir="./"
fi
# Compile the Rust file
rustc "$rust_file" -o "$dir$filename_no_ext"
compile_status=$?
# Run the executable if compilation is successful
if [ $compile_status -eq 0 ]; then
"$dir$filename_no_ext"
run_status=$?
# Delete the executable if it was newly generated
if [ $run_status -eq 0 ]; then
rm -f "$dir$filename_no_ext"
[ "$notify" -eq 1 ] && notify-send -u low "Rust Script: $filename" "Execution successful.\nFile: $abs_path"
fi
else
echo "Compilation failed."
[ "$notify" -eq 1 ] && notify-send -u critical "Rust Script: $filename" "Compilation failed.\nFile: $abs_path"
fi
# Remove the temporary directory if used
if [ "$use_temp_dir" -eq 1 ]; then
rm -r "$dir"
fi
}
# Flags
use_temp_dir=0
watch_mode=0
notify=0
# Parse options
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
-t|--temp)
use_temp_dir=1
shift
;;
-w|--watch)
watch_mode=1
shift
;;
-n|--notify)
notify=1
shift
;;
--install)
mkdir -p ~/bin
cp "$0" ~/bin/
exit 0
;;
-h|--help)
display_help
exit 0
;;
*)
rust_file="$1"
shift
;;
esac
done
# Check if the script is being piped a file
if [ -p /dev/stdin ]; then
temp_file=$(mktemp)
cat > "$temp_file"
compile_and_run_rust $use_temp_dir "$temp_file" $notify
rm -f "$temp_file"
exit 0
fi
# Display help if no arguments are specified
if [ -z "$rust_file" ] && [ "$use_temp_dir" -eq 0 ] && [ "$watch_mode" -eq 0 ]; then
display_help
exit 0
fi
# If not being piped, expect the first parameter to be the Rust file
if [ -n "$rust_file" ]; then
if [ "$watch_mode" -eq 1 ]; then
compile_and_run_rust $use_temp_dir "$rust_file" $notify # Run initially
if command -v inotifywait &> /dev/null; then
while inotifywait -e close_write "$rust_file" > /dev/null 2>&1; do
compile_and_run_rust $use_temp_dir "$rust_file" $notify
done
else
prev_checksum=$(md5sum "$rust_file")
while true; do
sleep 1
new_checksum=$(md5sum "$rust_file")
if [ "$new_checksum" != "$prev_checksum" ]; then
compile_and_run_rust $use_temp_dir "$rust_file" $notify
prev_checksum=$new_checksum
fi
done
fi
else
compile_and_run_rust $use_temp_dir "$rust_file" $notify
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment