Bash script - compile and run c++ code for coding competitions This is a simple bash script that I use to compile and run single C++ files for coding competitions.
Features:

Detects if there is a corresponding .in file next to it, and if so uses that as stdin

e.g. if the file problem1.cpp and problem1.in are in the same directory, the script will redirect stdin from problem1.in


Compile each file to a temp directory so it doesn't clutter the working directory
Configurable g++ warning flags as needed

Note: \033[32m and \033[0m are terminal color codes that make the text green
#!/bin/bash
# Compiles and runs .cpp code
# if there exists an .in file next to the .cpp file
# it will use that as input

if [ -z $1 ]; then
  echo -e &quot;Please choose an input file&quot;
  exit 1
fi

FILE=&quot;$1&quot;
FILE_IN=&quot;${FILE%.*}.in&quot;

clear
echo -e &quot;\033[32mCompiling...\033[0m&quot;
TMPFILE=$(mktemp /tmp/run-cpp.XXXXXXXXXX)
WARNING_FLAGS=&quot;-Wuninitialized -Wmaybe-uninitialized&quot;
g++ $FILE -std=c++17 $WARNING_FLAGS -O3 -o $TMPFILE

if [ $? -eq 0 ]; then
  echo -e &quot;\033[32mRunning...\033[0m&quot;
  if [ -f $FILE_IN ]; then
    $TMPFILE &lt; $FILE_IN
  else
    $TMPFILE
  fi
  ERROR=$?
fi
rm $TMPFILE 2&gt; /dev/null
exit $ERROR

Usage:
./runcpp.sh /path/to/my-cpp-file.cpp
#!/bin/bash


I don't see why you're using Bash for this - there should be no problem using standard POSIX shell.

if [ -z $1 ]; then


I would recommend &quot;$1&quot; there, even though extra arguments will cause [ to return false for other reasons.  Passing as a single argument won't emit any error messages.

  echo -e &quot;Please choose an input file&quot;


echo -e isn't portable, and isn't necessary here anyway.

FILE=&quot;$1&quot;
FILE_IN=&quot;${FILE%.*}.in&quot;


Avoid all-caps names for variables in your own program - these are generally reserved for environment variables which change programs' behaviour.

clear


I think that's a bit rude - some of us like to be able to compare results against the previous run.  If I want to clear before I run, I can type that easily.

echo -e &quot;\033[32mCompiling...\033[0m&quot;


Don't embed terminal-specific escape codes like that!  Even though most recent terminals support the ANSI escapes, there are others - and if you redirect to file, you don't want it littered with control characters.  Use tput to generate the correct escapes for your $TERM (and slightly more readable code).

TMPFILE=$(mktemp /tmp/run-cpp.XXXXXXXXXX)


That's not a very descriptive variable name.  It's more informative to say what it's for (the executable to create).  And why hard-code /tmp as the directory?  Prefer $TMPDIR if set (perhaps systems with per-user temp directories, or with a choice of fast or large temporary storage).

WARNING_FLAGS=&quot;-Wuninitialized -Wmaybe-uninitialized&quot;


That's quite a lax set of warnings.  If you care about the quality of your source, add a few more.  I suggest -Wall -Wextra -Wwrite-strings -Wno-parentheses -Wpedantic -Warray-bounds -Weffc++.  If you only care about performance, then perhaps -Wall -Wextra -Wno-parentheses -Warray-bounds might be sufficient.
Since we use this variable only once, perhaps we should inline its use, thereby not triggering a Shellcheck warning where we (correctly) expand it without quotes.

g++ $FILE -std=c++17 $WARNING_FLAGS -O3 -o $TMPFILE


&quot;$FILE&quot; here, too.  I'd write &quot;$TMPFILE&quot; even though we constructed it to be a safe name.

if [ $? -eq 0 ]; then


Anti-pattern - just use the preceding command directly after if.  Or, enable the -e flag of the shell, to just exit if the compilation fails.

  echo -e &quot;\033[32mRunning...\033[0m&quot;


tput again.

  if [ -f $FILE_IN ]; then


Quotes again.

    $TMPFILE &lt; $FILE_IN
  else
    $TMPFILE
  fi


As we don't use stdin, we could just redirect stdin using exec, and not need two different commands.

  ERROR=$?
fi
rm $TMPFILE 2&gt; /dev/null


Why didn't we remove the temporary file if we exited early?

exit $ERROR


We wouldn't need to store the error if we made removing the temp-file an exit trap.

Modified code
#!/bin/sh
# Compiles and runs C++ source code. A corresponding file
# ending with .in will be used as input, if present

set -eu

if [ $# -ne 1 ] || [ -z &quot;$1&quot; ]
then
  echo &quot;Usage: $0 SOURCE&quot;
  exit 1
fi

executable=$(mktemp -t run-cpp.XXXXXXXXXX)
trap 'rm $executable' EXIT

green=$(tput setaf 2)
normal=$(tput sgr0)

echo &quot;${green}Compiling...${normal}&quot;
g++ -o &quot;$executable&quot; -std=c++17 -O3                     \
    -Wall -Wextra -Wwrite-strings -Wno-parentheses      \
    -Wpedantic -Warray-bounds -Weffc++                  \
    &quot;$1&quot;

echo &quot;${green}Running...${normal}&quot;
input=${1%.*}.in
if [ -f &quot;$input&quot; ]
then exec &lt;&quot;$input&quot;
fi

&quot;$executable&quot;

You might also be interested in my approach to a similar situation, which uses Make rather than shell.