Makefile:
a b:
if [ -f s ];then
echo aaa
fi
command:make b
if [ -f s ];then
/bin/sh: -c: line 1: syntax error: unexpected end of file
make: *** [b] Error 2
Could anyone tell me why?
You should not be mixing shell scripting and make scripting. Try the below
a b:
#if test -f s; then \
echo "aaa";\
fi
Related
my simple makefile
#export PATH=/xxx/bin:$$PATH
$(info $(PATH))
export ABC=123
t:
echo $${PATH}
echo $${ABC}
runs fine. until I uncommented the first line.
following is output before and after
before:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
echo ${PATH}
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
echo ${ABC}
123
echo 123
123
after:
/xxx/bin:$PATH
echo ${PATH}
/xxx/bin:$PATH
echo ${ABC}
123
echo 123
make: echo: Command not found
make: *** [t.mk:13: t] Error 127
You want export PATH := /xxx/bin:$(PATH).
I am looking to create a shell script that reads command line arguments, then concatenates the contents of those files and print it to stdout. I need to verify the files passed to the command line exist.
I have written some code so far, but the script only works if only one command line argument is passed. If passing more than one argument, the error checking I have tried does not work.
#!/bin/bash
if [ $# -eq 0 ]; then
echo -e "Usage: concat FILE ... \nDescription: Concatenates FILE(s)
to standard output separating them with divider -----."
exit 1
fi
for var in "$#"
do
if [[ ! -e $# ]]; then
echo "One or more files does not exist"
exit 1
fi
done
for var in "$#"
do
if [ -f $var ]; then
cat $var
echo "-----"
exit 0
fi
done
I need to fix the error checking on this so that every command line argument is checked to be an existing file. If a file does not exist, the error must be printed to stderr and nothing should be printed to stdout.
You have a bug in line 11:
if [[ ! -e $# ]]; then
You do need to check for a given file here using $var like that:
if [[ ! -e "$var" ]]; then
And you exit prematurely in line 23 - you will always print only a
single file. And remember to always quote your variable because
otherwise your script would not run correctly on files that have a whitespaces in the name, for example:
$ echo a line > 'a b'
$ cat 'a b'
a line
$ ./concat.sh 'a b'
cat: a: No such file or directory
cat: b: No such file or directory
-----.
You said:
if a file does not exist, the error must be printed to stderr and
nothing should be printed to stdout.
You aren't printing anything to stderr at the moment, if you want to
you should do:
echo ... >&2
And you should use printf instead of echo as it's more portable
even though you're using Bash.
All in all, your script could look like this:
#!/bin/bash
if [ $# -eq 0 ]; then
printf "Usage: concat FILE ... \nDescription: Concatenates FILE(s) to standard output separating them with divider -----.\n" >&2
exit 1
fi
for var in "$#"
do
if [[ ! -e "$var" ]]; then
printf "One or more files does not exist\n" >&2
exit 1
fi
done
for var in "$#"
do
if [ -f "$var" ]; then
cat "$var"
printf -- "-----\n"
fi
done
exit 0
I want to include some conditional statement into a makefile:
SHELL=/bin/bash
all:
$(g++ -Wall main.cpp othersrc.cpp -o hello)
#if [[ $? -ne -1 ]]; then \
echo "Compile failed!"; \
exit 1; \
fi
But get an error:
/bin/bash: -c: line 0: conditional binary operator expected /bin/bash:
-c: line 0: syntax error near -1' /bin/bash: -c: line 0:if [[ -ne -1 ]]; then \' makefile:3: recipe for target 'all' failed make: *** [all] Error 1
How to fix it?
Note that each line of a makefile recipe runs in a different shell, so that $? of the previous line is unavailable, unless you use .ONESHELL option.
A fix without .ONESHELL:
all: hello
.PHONY: all
hello: main.cpp othersrc.cpp
g++ -o $# -Wall main.cpp othersrc.cpp && echo "Compile succeeded." || (echo "Compile failed!"; false)
With .ONESHELL:
all: hello
.PHONY: all
SHELL:=/bin/bash
.ONESHELL:
hello:
#echo "g++ -o $# -Wall main.cpp othersrc.cpp"
g++ -o $# -Wall main.cpp othersrc.cpp
if [[ $$? -eq 0 ]]; then
echo "Compile succeded!"
else
echo "Compile failed!"
exit 1
fi
When $ needs to be passed into a shell command it must be quoted as $$ in the makefile (make charges you a dollar for passing one dollar, basically). Hence $$?.
I am very new to Linux/Asterisk. I am trying to write a script but, when I execute it, I see the error shown below.
The script is as follows:
#!/bin/bash
asteriskbin=`which asterisk`
interval=10
trunk=”<test>”
run=true
while [[ "$run" == "true" ]]; do
checktrunk=`$asteriskbin -rx “sip show peer $trunk” | grep Status | grep -wc OK`
if [[ $checktrunk == 0 ]]; then
echo “<TEST Trunk Down>”
else
echo “SIP trunk registration OK.”
fi
sleep $interval
exit 1
Debug error is as following:
bash -x trunks.sh
++ which asterisk
+ asteriskbin=/usr/sbin/asterisk
+ interval=10
+ trunk=$'\342\200\235test\342\200\235'
+ run=true
trunks.sh: line 15: syntax error: unexpected end of file
This might be a duplicate post but, from my search, the given answers such as chmod 755 script.sh, exit 0, exit 1, or dos2unix script.sh did not work.
Aren't you missing a done to terminate the while block? I assume a line before exit 1.
I have a makefile rule in while I am executing a linux tool. I need to check the exit status of the tool command, and if that command fails the make has to be aborted.
I tried checking with $?, $$? \$? etc in the makefile. But they gives me syntax error when makefile runs.
What is the right way to do this ?
Here is the relevant rule in Makefile
mycommand \
if [ $$? -ne 0 ]; \
then \
echo "mycommand failed"; \
false; \
fi
In the makefile-:
mycommand || (echo "mycommand failed $$?"; exit 1)
Each line in the makefile action invokes a new shell - the error must be checked in the action line where the command failed.
If mycommand fails the logic branches to the echo statement then exits.
Here are a couple of other approaches:
shell & .SHELLSTATUS
some_recipe:
#echo $(shell echo 'doing stuff'; exit 123)
#echo 'command exited with $(.SHELLSTATUS)'
#exit $(.SHELLSTATUS)
Output:
$ make some_recipe
doing stuff
command exited with 123
make: *** [Makefile:4: some_recipe] Error 123
It does have the caveat that the shell command output isn't streamed, so you just end up with a dump to stdout when it finishes.
$?
some_recipe:
#echo 'doing stuff'; sh -c 'exit 123';\
EXIT_CODE=$$?;\
echo "command exited with $$EXIT_CODE";\
exit $$EXIT_CODE
Or, a bit easier to read:
.ONESHELL:
some_recipe:
#echo 'doing stuff'; sh -c 'exit 123'
#EXIT_CODE=$$?
#echo "command exited with $$EXIT_CODE"
#exit $$EXIT_CODE
Output:
$ make some_recipe
doing stuff
command exited with 123
make: *** [Makefile:2: some_recipe] Error 123
It's essentially one string of commands, executed in the same shell.
If all you want is for the make to be aborted iff the tool exits with a nonzero status, make will already do that by default.
Example Makefile:
a: b
#echo making $#
b:
#echo making $#
#false
#echo already failed
.
This is what happens with my make:
$ make
making b
make: *** [Makefile:6: b] Error 1
Make sure partially or wholly created targets are removed in case you fail.
For instance, this
a: b
#gena $+ > $#
b:
#genb > $#
is incorrect: if on the first try, genb fails, it will probably leave an incorrect b, which, on the second try, make will assume is correct. So you need to do something like
a: b
#gena $+ > $# || { rm $#; exit 1; }
b:
#genb > $#
To those who can't still fix it, the original snippet in the question missed a semicolon after mycommand. So, the working example is:
mycommand; \ # <<== here's the missing semicolon
if [ $$? -ne 0 ]; \
then \
echo "mycommand failed"; \
false; \
fi