Bash Script to Compile and Run C++ Program

linux script running c program

Get rid of the backticks, the chmod, and the echo. All you need to do is run gcc, then run your program.

#!/bin/bash
gcc odd.c -o odd222
./odd222

It'd also be good to only try to run the program if it compiles successfully. You can make it conditional by using &&.

#!/bin/bash
gcc odd.c -o odd222 && ./odd222

It'd also be good to modify your C code to ensure the printouts are printed immediately. Output is usually line buffered, meaning it's only displayed once you write a full line with a newline \n at the end. You'll want to either print a newline:

printf("enter the no.\n");

Or flush the output explicitly:

printf("enter the no.");
fflush(stdout);

Bash script to compile and run C++ program

If g++ fails it will return with a non-zero return-value which can be checked for with a Bash if command:

output=$(g++ $PROG_NAME 2>&1)
if [[ $? != 0 ]]; then
# There was an error, display the error in $output
echo -e "Error:\n$output"
else
# Compilation successfull
./a.out
fi

A possibly better solution (IMO) is to learn how to use makefiles, as it will allow more complex projects as well.

How to run C programs in Git bash?

I got this problem fixed by appending fflush(stdout) after those printf() statements:

printf("Enter first value: ");
fflush(stdout); // this
scanf("%d", &a);

printf("Enter second value: ");
fflush(stdout); // this
scanf("%d", &b);

Just flushing the buffer will let the program wait for your input after printing.

The working example screenshot:

Git Bash Working Program Example

Compiling and executing c program in bash script not working because the compiled program is not found

The shell cannot find a.out because it isn't looking in the current directory. That is best practice. (ie, do not add . to PATH). Just do:

gcc stadist.c -lm &&
./a.out < XXXXX | sort -n -k3 > YYYYY
rm a.out
rm stadist.c
rm XXXXX

Note that I added && after the invocation of gcc so that the script does not attempt to run a.out if the compilation fails. You'll probably want to add more robust error checking.

Is there a way to execute compiled C code from inside a bash script?

This worked:

"Try to invoke /Users/User/screensaver/a.out without putting a dot at the beginning of the path. There is a paticular security reason why you need to specify ./a.out rather than a.out when you are in the directory which holds the executable."
-tshiono

How to write a bash file to compile and execute a c++ program

You have struggled for a few hours and put something together, but what happens if the compilation fails? What happens if there are no arguments? What happens if there are 4 arguments for the program?

When writing a script, or a program, the most important thing you can do is validate every necessary step! If you are expecting input, validate you received it. Once you have the input, validate it is what your expected. Is it a value within the usable range? Is it a filename that meets my requirements? Does it exist? Did my compile succeed or fail? Do I try and execute the program?

All of these need to be addressed. Otherwise, your script (or program) will stray off on some undefined path.

Bash provides a wealth of conditional expressions that can be used with test (or [...]) or using the bash [[...]] operator. See Bash Manual - 6.4 Bash Conditional Expressions. Make use of the language features to make your code robust.

Bash provides a wealth of string handling features through parameter expansions Bash Manual - 3.5.3 Shell Parameter Expansion, use them to check the extension to make sure it is c, cpp or c++

Putting those features together with a few if...then...fi statements will make your script much more reliable -- and actually do what it is you are trying to do.

The following short script takes arguments (bash Positional Parameters) requiring that at least the filename to compile be provided, and passing any additional arguments to the compiled program as command line arguments with ${@:2} (all bash positional parameters beginning with the 2nd one)

#!/bin/bash

if [ -z "$1" ] ## validate at least one argument given
then
printf "error: insufficient arguments\n" >&2
printf "usage: %s file.cpp [args]\n" "${0##*/}" >&2
exit 1
fi

if [ ! -r "$1" ] ## validate file is readable
then
printf "error: file not found '%s'\n" "$1" >&2
exit 1
fi

src="$1" ## give source file a handy name

## check the source file ends in '.c', '.cpp' or '.c++'
if [ "${src##*.}" != 'c' -a "${src##*.}" != 'cpp' -a "${src##*.}" != 'c++' ]
then
printf "error: first argument not a c/c++ file\n" >&2
exit 1
fi

ext="${src##*.}" ## save the extension

if [ "${#ext}" = 'c' ] ## check if ext is 'c' use gcc else use g++
then
## always enable compiler warnings, -Wall -Wextra -pedantic, minimum
# -Wshadow to catch shadowed variables, -Werror treat warnings as error
gcc -Wall -Wextra -pedantic -Wshadow -Werror \
-std=c11 -O3 -o "${src%.*}" "$src"
else
g++ -Wall -Wextra -pedantic -Wshadow -Werror \
-std=c++11 -O3 -o "${src%.*}" "$src"
fi

if [ $? -eq '0' ] ## check the compiler return, run only on success
then
./"${src%.*}" ${@:2}
else
printf "\nAn error occurred, executable not called\n\n" >&2
fi

Now a couple of short examples to make sure it works:

#include <stdio.h>

int main (int argc, char **argv) {

const char *s = "hello c file.";

printf ("%s\n", s);

for (int i = 1; i < argc; i++)
printf ("arg[%d]: %s\n", i, argv[i]);
}

Example Use/Output

$ bash compilewargs.sh cfile.c foo bar baz
hello c file.
arg[1]: foo
arg[2]: bar
arg[3]: baz

For C++

#include <iostream>
#include <string>

int main (int argc, char **argv) {

std::string s = "hello cpp file.";

std::cout << s << '\n';

for (int i = 1; i < argc; i++)
std::cout << "arg[" << i << "]: " << argv[i] << '\n';
}

Example Use/Output

$ bash compilewargs.sh cppfile.cpp foo bar baz
hello cpp file.
arg[1]: foo
arg[2]: bar
arg[3]: baz

Does the error-handling work?

#include <stdio.h>

int main (void) {

const char *s = "hello c file.";

printf ("%s\n", unknown);
}

Example Use/Output

$ bash compilewargs.sh cerrfile.c foo bar baz
cerrfile.c: In function ‘int main()’:
cerrfile.c:7:21: error: ‘unknown’ was not declared in this scope
printf ("%s\n", unknown);
^
cerrfile.c:5:17: error: unused variable ‘s’ [-Werror=unused-variable]
const char *s = "hello c file.";
^
cc1plus: all warnings being treated as errors

An error occurred, executable not called

What about a file that doesn't exist?

$ bash compilewargs.sh myfile.c foo bar baz
error: file not found 'myfile.c'

What about a text (or any other non-c, cpp or c++) file?

$ bash compilewargs.sh compilewargs.sh foo bar baz
error: first argument not a c/c++ file

By taking the time to think though what the dumbest user you know could ever try and do with your script -- and protecting against it, you can write reasonably robust scripts that will save you grief. Look things over and let me know if you have further questions.

Compile C/C++ program via simple script

  1. Just copy paste your commands in a file, say x.sh.

  2. Type chmod +x x.sh in the directory where x.sh resides.

  3. Run x.sh by typing ./x.sh

apollo:~/test$ cat > x.sh   
gcc -c -Wall tbl0.c tbl1.c tbl2.c

gcc -shared -Wall -o libtbl.so -I.
-Wl,-z,defs -L. -lpthread -lm -ldl

apollo:~/test$ chmod +x x.sh

apollo:~/test$ ./x.sh #run

I will suggest that you stick with a Makefile. They may look complex initially, but are useful in the long run.



Related Topics



Leave a reply



Submit