HiveBrain v1.2.0
Get Started
← Back to all entries
patternbashMinor

Compile and run C++ code

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
andcoderuncompile

Problem

I have created this bash script for Compile And Run c++ code, car++.sh.
As I'm new to bash scripting, I'm not sure about good bash programming practices.

Please review it to see if you could find any anomaly.

#!/bin/bash

found=false;
output=;
o_is_set=false;

#retrieve output_filename from arguments as provided by user
for arg in "$@"
do
    if [ "$o_is_set" = true ]
    then
        output="$arg";
        found=true;
        break;
    fi

    if [[ $arg == -o ]]
    then
        o_is_set=true;
    fi
done

#else retrieve from file name of first .cpp or .c++ file specified
if [ "$found" = false ]
then
    for file in "$@"
    do
        ext=$(echo $file | tr '[:upper:]' '[:lower:]');

        if [[ $ext == *.cpp ]]
        then
            output=$(basename "$file" ".cpp");
            found=true;
            break;
        fi

        if [[ $ext == *.c++ ]]
        then
            output=$(basename "$file" ".c++");
            found=true;
            break;
        fi
    done
fi

#else retrieve from first .c file specified
if [ "$found" = false ]
then
    for file in "$@"
    do
        ext=$(echo $file | tr '[:upper:]' '[:lower:]');

        if [[ $ext == *.c ]]
        then
            output=$(basename "$file" ".c");
            found=true;
            break;
        fi
    done
fi

#output file name is not specified by user and there is no C++ or C file,
#lets see what g++ says about it
if [ "$found" = false ]
then
echo;
    g++ -Wall -std=c++11 "$@";
    exit "$?";
fi

run="./$output";

g++ -Wall -o "$output" -std=c++11 "$@" && $run;

Solution

It's a good start, but I see a number of things that may help you improve your code.

Try to reduce the scope of variables

The variables o_is_set and found are essentially global variables, but don't need to be. Instead, the code might be structured as a series of functions, reducing the linkage within the code.

Use standard option parsing

One could use getopts for parsing command line options, or plain old bash for that. For example, consider this code for parsing a -o option with its corresponding argument:

while [[ $# > 1 ]]
    do
        opt="$1"
        case $opt in 
            -o)
            OUTPUT="$2"
            shift
            ;;
            *)
                # ignore unknown option
            ;;
        esac
        shift
    done


Use make instead

The basic operation of this file is to create an executable from either a .cpp or .c file using the gcc compiler and then running the resulting executable. One can do essentially the same thing with a single line:

#!/bin/bash 
make $1 && ./$1


For example, if we have nuts.c in the current working directory and the file above is called car we can execute ./car nuts and make will run, find the nuts.c file, create an executable nuts and then run it.

Code Snippets

while [[ $# > 1 ]]
    do
        opt="$1"
        case $opt in 
            -o)
            OUTPUT="$2"
            shift
            ;;
            *)
                # ignore unknown option
            ;;
        esac
        shift
    done
#!/bin/bash 
make $1 && ./$1

Context

StackExchange Code Review Q#85941, answer score: 3

Revisions (0)

No revisions yet.