0

Usually if I want to compile a C program called number_input.c I would type

cc -o number_input number_input.c

I want to use my mac terminal to make a script so that I don't have to type that extra word. Originally I did this to save myself 1 sec of programming but ironically I've spent over 2 hrs trying to get this to work.

a= echo "$1" | rev | cut -c3- | rev
echo $a
cc -o $a $1
echo $1

This is my output:

number_input

clang: error: no input files number_input.c

I can tell that the names are being inputted correctly but for some reason the cc command isn't taking in the value of $1? I am assuming that somehow the $1 isn't directly converted into a string or something like that but I am not sure.

3
  • 1
    You should use a Makefile. Commented Apr 26, 2017 at 8:00
  • 1
    You could use a Makefile. You could also use CMake, or Ninja, or bfg9000, or gyp, or... Commented Apr 26, 2017 at 8:01
  • 1
    ...or nothing, since there is only one file being compiled! Commented Apr 26, 2017 at 8:04

2 Answers 2

5

Your error is on the first line, since you're not assigning anything to a:

a=$(echo "$1" | rev | cut -c3- | rev)

Would fix the problem (for well-behaved filenames, at least, since you're missing quotes further down in your script). A space after a means you're assigning an empty string to it and then running the commands in the pipeline.

Instead of going to all the effort of reversing the twice, just remove the last two characters with ${1%??}:

cc -o "${1%??}" "$1"
Sign up to request clarification or add additional context in comments.

Comments

1

The most common tool to do this is make. It reads the recipes from a file named Makefile in the directory it is run, and performs any tasks necessary. It is smart enough to check the file timestamps to detect if or which parts of your projects need to be re-compiled. Here is an example Makefile:

CC      := gcc
CFLAGS  := -Wall -O2
LDFLAGS := -lm

PROGS   := number_input

.PHONY: all clean

all: $(PROGS)

clean:
    rm -f $(PROGS)

$(PROGS): %: %.c
    $(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@

Note that indentation in a Makefile must use tabs, not spaces. If you copy the above, and paste to a file, you will need to run sed -e 's|^ *|\t|' -i Makefile to fix the indentation.

The first three lines name the compiler used, the compiler options, and the linking options. The -lm linking option is not needed for your particular use case; I just included it because you will sooner or later want to use <math.h>, and then you do need to include the -lm linking option.

The PROGS line names your programs. You can specify more than one, just separate them by spaces.

The .PHONY: line tells make that targets all and clean are "phony", that they do not generate files of that name.

The all recipe, as the first recipe in a Makefile, is the default recipe that is followed, when you run make. This one tells that all programs listed in PROGS should be built.

The clean recipe (run make clean) removes all temporary files and compiled files from the directory -- essentially cleaning it.

The last recipe is a tricky one. It says that all the files listed in PROGS are each built from a file having the same name plus a .c suffix. The $^ refers to the .c file name, and $@ to the file name without the suffix.

If this Makefile were used for returning exercises via email to a teacher, I'd also add a new .PHONY target, tarball:

CC      := gcc
CFLAGS  := -Wall -O2
LDFLAGS := -lm

PROGS   := number_input
TAR     := $(notdir $(CURDIR)).tar

.PHONY: all clean tarball

all: $(PROGS)

clean:
    rm -f $(PROGS)

tarball: clean
    rm -f ../$(TAR)
    tar -cf ../$(TAR) $(notdir $(CURDIR))/

$(PROGS): %: %.c
    $(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@

Running make will compile number_input, if number_input.c has been modified after the last time number_input was compiled, or if number_input does not exist yet.

Running make TAR=myname-ex01.tar tarball removes the compiled files from the current directory, then creates a tarball of the current directory (and its subdirectories, if any) in the parent directory as myname-ex01.tar. If you run just make tarball, the tar file name will be the same as the name of the current directory, but with a .tar suffix.

I hope you can see why writing a Makefile is so useful.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.