Shell script file for compiling and producing output of C file - c

I wrote this .sh file to compile any c source file, so that when I run it, it asks for a filename and gcc compiles it and then, runs the executable a.out.
But this doesn't work properly when error is present in .c files. It also shows that a.out is not present. I don't want this error message ( a.out is not present ) but just want to print only the error message generated for the .c files..
Here's the script..
echo `clear`
echo enter file name
read FILE
gcc $FILE
./a.out
echo -e '\n'

If you enable abort-on-error in shell scripts, life will be a lot easier:
#!/bin/sh
set -eu # makes your program exit on error or unbound variable
# ...your code here...

Utilizing builtin rules as an alternative to your script you might want to use make as an alternative to a handcrafted script. To compile file.c and run the generated executable all you need to do is:
make file && ./file
If you don't know it, I strongly suggest you take a look at the make utility as it will ease your work a lot. Managing anything more than a one file project can get really nasty without it.

You can chain compilation and execution commands:
echo `clear`
echo enter file name
read FILE
gcc $FILE && ./a.out
echo -e '\n'
Here, if gcc will fail, the shell will drop the ./a.out command.

You may also protect the file name with double quotes :
#! /bin/bash
clear
echo -n "Enter file name: "
read FILE
gcc -Wall -W "$FILE" && ./a.out
echo

I there hope this is what you were looking it only requires this command:
./compile executableName myCProgram.c -lm
you can place more C files ahead of each others and add more libraries at the end of the line and executableName does not require the .exe
#!/bin/bash
args="$#"
quant=$#
#Copies in case you need the -lm(math library) params
biblio=${args#*-}
#grabs all params except the first one which should be the name of the executable
firstCommand=${*:2:${#args}}
#Remove the "-lm -lc" from firstCommand
firstCommand=${firstCommand%%-*}
printf "\nEXECUTING: gcc -W -Wall -c $firstCommand\n"
#Creates the object file ".o"
gcc -W -Wall -c $firstCommand
#Convert the files names from example.c to example.o
args=${args//.c/.o}
printf "\nEXECUTING: gcc -o $args\n\n"
#Creates the executable
gcc -o $args
printf "\n**Now execute comand: ./$1 **\n\n"

Related

Why $(< file.txt) don't work on makefile?

Using the command line I get the desired output
$ ./program $(< file.txt)
./program 1 2 3 4 5
But with a makefile
all: program file.txt
./program $(< file.txt)
#rm -f program
program: program.c
gcc program.c -o program
I get the output
gcc program.c -o program
./program
Because in a makefile, the $(...) syntax is used for variable interpolation. So your makefile tries to expand the value of a makefile variable / environment variable named < file.txt. And if unset, it expands to an empty string.
Proof:
all:
echo $(< file.txt)
and file.txt containing
now it works
Then execute
% env '< file.txt=Hello world' make
echo Hello world
Hello world
i.e. by setting an environment variable named < file.txt to value Hello world , the greeting was printed. The fix is to escape the $ character by doubling it:
all:
echo $$(< file.txt)
and then
% make
echo $(< file.txt)
now it works
Q.E.D.
Finally, while the $() interpolation syntax in POSIX shells, the $(< file.txt) is not but you can replace it with $(cat file.txt) so it works with minimally POSIX-conforming shells. Of course in a makefile you again need to double the dollar, therefore getting the maximally compatible
$$(cat file.txt)
Alternatively you can use the similar makefile facility which is $(shell ), i.e.
$(shell cat file.txt)
would work too... (now with one $). Finally you can read files with $(file ) GNU makefile function too, i.e.
all:
echo $(file <file.txt)
would work alike but wouldn't call shell at all.
The substitution you are trying to use is a Bash feature, but make out of the box runs the regular Bourne shell sh, where this syntax is not available (even when sh is a symlink to Bash, as is still common on some Linux distributions).
Requiring the contents of the file to be specified on the command line looks like a design flaw, anyway; it's probably much better if your C program simply reads and processes standard input (or perhaps accepts a list of file names, and falls back to stdin if none are specified, like many Unix file processing utilities).
If this is just for a test case to run the program with parameters from a file, check out xargs.
xargs ./program <file.txt
If you insist on using Bash-only syntax, add
SHELL=/bin/bash
(or whatever full path is correct on your system); but understand that this limits the portability of your Makefile.
Still, you'll need to double any literal dollar sign which should be passed through and exposed to the shell.

C program with in bash script

I am trying to run C program inside bash, my C program is using the gps device and calculating the distance based on latitude and longitude values. The problem is when i run this C program through bash to get distance, i am not able to redirect its output to any file or variable. i tried this:
output=$(./run)
but it is not working.
to run C code inside bash i am using the following code:
#!/bin/bash
echo 'clear'
echo enter file name
read FILE
gcc -o a.out $FILE -lm
output=$(./a.out)
echo $output
when i do not redirect it shows value:
#!/bin/bash
echo `clear`
echo enter file name
read FILE
gcc -o a.out $FILE -lm
./a.out
[gps values][1]
Can any body help in this?
You don't include the requested debug log, but from your screenshot it looks like your program never exits. It just stays around and writes values forever. Therefore, the capture never reaches the end, so your echo statement never executes.
You should modify your program or invocation so that it will at some point exit.
If you can't modify the program, you can capture e.g. only the first ten lines using one of:
# More canonical way
output=$(./a.out | head -n 10)
# More resilient way, if the program is especially poorly written
output=$( head -n 10 <(./a.out) )
Thank you every one for the comments
It is working now
#!/bin/bash
echo `clear`
echo enter file name
read FILE
gcc -o a.out $FILE -lm
stdbuf -oL ./a.out |
while IFS= read -r line
do
echo "Data: $line"
done
by using the above code
Use -o flag in gcc to create the binary first.
I'll give you an example using "Hello World" code:
~]# cat hw.c
#include <stdio.h>
int main(){
printf("Hello World");
return 0;
}
The bash script:
~]# cat hw.sh
gcc -o hw hw.c
./hw
Then run:
~]# bash hw.sh
Hello World

running my code using terminal Ubuntu

I've watched tons of videos about how to use sublime text 3 I do what they say but it doesn't work. When i type "subl test.c" in terminal it opens up a a file called test.c in sublime text 3 when i use the command gcc -c test.c everything is fine too, but when I try to run the code using ./test it says bash: ./test: No such file or directory
Bash says that there is no such file or directory because you haven't created a file called 'test'. You should specify an output filename, i.e. you should type gcc test.c -o your_out_filename. Then you may run your program using ./your_out_filename. Without -o flag gcc will create a a.out by default, so your out_filename will be a.out.
You have to use the following command to create a file called test:
gcc test.c -o test
If you don't use the -o option (gcc test.c) your created file will be a.out.
The option -c of gcc only compiles your file and doesn't link it to a program which you can run. The result of the -c option is only an object file called test.o.
Therefore the easiest way is the one I have mentionend above (-o option).
You have to run:
gcc -o output test.c
output is the file you have to do ./output in terminal for it to execute

When compiling C code in the linux terminal, what is the difference between make <filename> and cc <filename>?

I'm new to C, and I understand that both of those commands accomplish the same thing, but does one of them do something different than the other along the way?
First of all, if you are using make then for hello.c you will call make as make hello and not make hello.c. Also, note that make is most of the times used with a Makefile. Nonetheless, you can build executable binary from single source file using make as you have shown.
If the executable (hello) does not exist, then both will have same effect - create the executable from source file.
However, if the executable already exists, then make will run the build commands only if it thinks that the source code has changed after last build, whereas cc will always do the build.
For example:
$ make hello
cc hello.c -o hello
$ make hello
make: 'hello' is up to date. # make does not think source file has changed
$ touch hello.c # Update the timestamp of hello.c
$ make hello
cc hello.c -o hello # make thinks source file changed. Builds again
$
However, cc will not check if the source has changed or not. It will always do the required build.
$ cc hello.c -o hello
$ ls -l hello | cut -d ' ' -f '8-'
12:18 hello
$ cc hello.c -o hello # Build again without changing source
$ ls -l hello | cut -d ' ' -f '8-'
12:21 hello # hello was built again
$
Above description was for GNU make and GNU cc. Not sure about other implementations.
P.S.: make is not a compiler. It only calls the compiler when it thinks it should, as seen in the example above. Whereas cc is a compiler.
P.S. If you run cc hello.c, the excutable is named a.out, and not hello.
make(1) is a program that will run commands. You create a file named "Makefile" in a directory. The Makefile has a recipe with a specific syntax that is beyond the scope of this answer. You then invoke the make command in the directory with the file named Makefile
cc $filename will invoke a C compiler upon the $filename
cc or gcc or clang will invoke the compiler.
make is used when you have many files to compile.
In make you will give name of .o file and include header file location.

compile a stream of data in C?

Is it possible to compile a stream of data rather than compiling a .c file using gcc? for example, is it possible that instead of having my code stored in any xyz.c file, I can directly compile the code?
Use gcc options -x and -
$ echo -e '#include <stdio.h>\nmain(){puts("Hello world");return 0;}' | gcc -xc -ogarbage - && ./garbage && rm garbage
Hello world
The single line command above is made up of the following parts:
echo -e '#include <stdio.h>\nmain(){puts("Hello world");return 0;}' # "source"
| # pipe
gcc -xc -ogarbage - # compile
&& # and
./garbage # run
&& # and
rm garbage # delete
This may answer you question, though it is rarely useful.
You can create a file, stream the code into it, then create another process(that is, the compiler) giving it the file as an argument. Then create another process(that is, the linker) and it will create an exe for you. And finally you can launch that exe as a new process. But why?!:)

Resources