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
"$1" 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 "Please choose an input file"
echo -e isn't portable, and isn't necessary here anyway.
Avoid all-caps names for variables in your own program - these are generally reserved for environment variables which change programs' behaviour.
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 "\033[32mCompiling...\033[0m"
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).
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).
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
"$FILE" here, too. I'd write
"$TMPFILE" 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 "\033[32mRunning...\033[0m"
if [ -f $FILE_IN ]; then
$TMPFILE < $FILE_IN
As we don't use stdin, we could just redirect
exec, and not need two different commands.
rm $TMPFILE 2> /dev/null
Why didn't we remove the temporary file if we exited early?
We wouldn't need to store the error if we made removing the temp-file an exit trap.
# Compiles and runs C++ source code. A corresponding file
# ending with .in will be used as input, if present
if [ $# -ne 1 ] || [ -z "$1" ]
echo "Usage: $0 SOURCE"
executable=$(mktemp -t run-cpp.XXXXXXXXXX)
trap 'rm $executable' EXIT
green=$(tput setaf 2)
g++ -o "$executable" -std=c++17 -O3 \
-Wall -Wextra -Wwrite-strings -Wno-parentheses \
-Wpedantic -Warray-bounds -Weffc++ \
if [ -f "$input" ]
then exec <"$input"
You might also be interested in my approach to a similar situation, which uses Make rather than shell.