bash alias - running two commands - linux

How do I make an alias in my .bashrc such that I can run two commands with arguments?
For example, compile source and run.
gcc-run -lm example.c
would run
gcc -lm example.c
./a.out
The closest I found was this question but it doens't have any arguments.

If you want to pass an argument, you can't use an alias. You need to use a shell function. It sounds like you want something similar to
gcc-run () {
gcc "$#"
./a.out
}

Related

Is there anyway to compile many files by a single instruction in Linux bash?

For example, in Linux, gonna compile 3 files "test1.c", "test2.c" and "test3.c" separately to "test1", "test2" and "test3", is there a way using wildcard or pipe to do it by one line bash instruction?
There's not really such a thing as a "bash instruction", and even if you say "bash command", then gcc isn't really such a thing either because it is not intrinsically related to, or a part of bash. It is a separate binary/program that can be run under any shell, such as sh, ksh, ash, dash or even tcsh.
Assuming you mean one line, you can do:
gcc prog1.c -o prog1 & gcc prog2.c -o prog2 & gcc -o prog3 prog3.c
You can equally do that in a loop as William was suggesting:
for f in test?.c; do gcc "$f" -o "${f%.c}" & done
IMHO though, the easiest is with GNU Parallel:
parallel gcc {} -o {.} ::: test?.c
There are those who will rightly say that GNU Parallel is not part of POSIX, but, to be fair, you didn't mention POSIX in your question. So, if POSIX-compliance is an issue, you may choose to avoid this suggestion.
As suggested in the comments, a Makefile would be even better, So if you create a file called Makefile with the following contents:
all: test1 test2 test3
You can simply run:
make
and all three programs will be compiled, only if necessary, i.e. if you have changed the source file since last compiling. Or, if you want to use all those cores that you paid Intel so handsomely for, you can do them in parallel with:
make -j

How can I run an executable file without the "./" using a MakeFile?

I want to run my program with an executable without the "./"
For example lets say I have the makefile:
all: RUN
RUN: main.o
gcc -0 RUN main.o
main.o: main.c
gcc -c main.c
So in order to run the program normally I would say in the terminal "make" then put "./RUN" to invoke the program.
But I would just like to say in the terminal "make" then "RUN" to invoke the program.
So to conclude I would just like to say >RUN instead of >./RUN inside the terminal. Is there any command I can use to do this inside the Makefile?
When I just put "RUN" in the terminal it just says command not found.
It is a matter of $PATH, which is imported by make from your environment.
You might set it in your Makefile, perhaps with
export PATH=$(PATH):.
or
export PATH:=$(shell echo $$PATH:.)
but I don't recommend doing that (it could be a security hole).
I recommend on the contrary using explicitly ./RUN in your Makefile, which is much more readable and less error-prone (what would happen if you got a RUN program somewhere else in your PATH ?).
BTW, you'll better read more about make, run once make -p to understand the builtin rules known to make, and have
CC= gcc
CFLAGS+= -Wall -g
(because you really want all warnings & debug info)
and simply
main.o: main.c
(without recipes in that rule) in your Makefile
change your makefile to
all: RUN
RUN: main.o
gcc -o RUN main.o && ./RUN
main.o: main.c
gcc -c main.c
just put ./filename in your makefile

How to configure GCC to show all warnings by default?

I think it will be good and not much bad if -Wall flag is switched on by default. How do I configure GCC like this?
Is there any drawbacks to this other than the fact that a lot of warnings will flood your terminal when you are compiling some large program from source?
Add these lines to your ~/.bashrc if you use bash as your shell.
alias gcc='gcc -Wall'
Update:
you can refer to this question on https://superuser.com/questions/519692/alias-gcc-gcc-fpermissive-or-modifying-configure-script
If you use make, you need to overwrite make's variables CC and CXX from within the .bashrc:
export CC="gcc -wall"
export CXX="g++ -wall"
juzzlin suggested that a good method would be to write a wrapper for gcc. Marc Glisse also suggested that writing one is the best way to achieve what I want. So that's just what I did.
I made a bash script that calls gcc for me:
#!/bin/sh
echo -n "Compiling $1..."
gcc -Wall -Werror -o $(basename $1 .c).out $1
a=$?
if [[ "$a" -eq 1 ]]; then
echo "Failed!"
else
echo "Done."
echo "Executing:"
./$(basename $1 .c).out
fi
Then I copied the script to /usr/bin and made it executable:
sudo cp car /usr/bin
chmod +x /usr/bin/car
(The name of the script is car which stands for "Compile And Run")
So whenever I want to compile a source file and run it, I will type:
car mysourcefile.c
As discussed in the comments (although it's not a direct answer to your question), using a Makefile has many benefits. It provides a place where to put your build commands, that will alway stay up to date if you only build with make. It also ease running tests at each build.
Writing tests is a good habit, even when you're just working on a small and unsignificant piece of code for homeworks. It allows you to spot some dumb mistakes that you would otherwise miss, and to be sure you don't break your existing code by modifying it (especially the last minute modification).
An example of such a Makefile (here I have nothing to build apart from the test because it's a header only component):
all:
g++ -O2 -Wall -Werror -std=c++11 test_polynomial.cc -o test_polynomial -lgmp
g++ -O2 -Wall -Werror -std=c++11 test_g2polynomial.cc -o test_g2polynomial
./test_polynomial --log_level=test_suite
./test_g2polynomial --log_level=test_suite
clean:
rm -f test_polynomial test_g2polynomial
Note: The example is not a very good one as I don't even factorize the build options in CFLAGS. If I want to add a flag, I have to add it in both commands !
Another benefit is that you always run make to build, whatever the language, the dependencies or even the build system (when working on a project using scons or another build system, I still write a Makefile doing all the commands I do when building and testing !).
This allows my personal addition on it (but here we're completely off-topic): I have a build script named autobuild looping on make each time I write a file in vim. I code in screen and run autobuild in a small window at the bottom of my screen. This way, each change is built and tested as soon as I write the file.

Linux - can you compile AND run a program in one terminal line?

For example, a program named program.c
g++ program.c -o programName
./programName
Is there any way to consolidate these two lines?
Yes, you could write...
g++ program.c -o programName && ./programName
Which will only attempt to run your program if compilation succeeded.
For a more general approach, you could write a bash script..
#!/bin/sh
g++ $1 -o $2 && ./$2
Then you could do (provided it's on your PATH, it's executable and it's called mycompile)...
mycompile program.c programName
To make this program available on your PATH, you can pop it in your bin directory or any directory under echo $PATH. If you don't wish to do that, open your ~/.bashrc file and add its parent directory to your PATH with PATH="$PATH:your/new/dir" (keep in mind all scripts in that folder will be now reachable).
Ensure it's executable (check with ls -l mycompile), if not, you can add that permission with chmod +x mycompile.
Like this:
g++ program.c -o programName && ./programName
Notice that the commands will run sequentially, that is: one after the other.

How redirect time gcc output to a file?

I am using the command :
time gcc -lm test.c > time.txt
to determine the compilation time etc. and then write them to a file.BUt when i use the above command nothing gets printed into the file?
Where am i going wrong?
It depends on what shell you use. In bash, time is a builtin and cannot be redirected. You have to use a subshell to redirect its standard error:
(time gcc -lm test.c ) 2> time.txt
The problem here is that there are two command time. One is a bash built-in command and the other one is a usual Unix command.
$> type time
time is a shell keyword
$> type `which time`
/usr/bin/time is /usr/bin/time
If you want to use the bash built-in, you should write as choroba wrote:
(time gcc -lm test.c ) 2> time.txt
But, if you want to be sure that your script works even if the built-in is not present, you better try to enforce the usage of the real time command:
`which time` -o time.txt gcc -lm test.c
For more information about time do not hesitate to do man time.

Resources