LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Slackware (https://www.linuxquestions.org/questions/slackware-14/)
-   -   bash question - syntax error near unexpected token (https://www.linuxquestions.org/questions/slackware-14/bash-question-syntax-error-near-unexpected-token-4175455516/)

trainee 03-25-2013 10:45 AM

bash question - syntax error near unexpected token
 
Hi,
I wrote a script like this
Code:

for i in 2 3 4 5 6 7 8 9 10 do
/usr/bin/pdfunite test.pdf chap[i].pdf test.pdf
done

and put it in a file testrun.sh

When I run
#./testrun.sh
I got the error

./testrun.sh: line 3: syntax error near unexpected token `/usr/bin/pdfunite'
./testrun.sh: line 3: ` /usr/bin/pdfunite test.pdf chap$i.pdf test.pdf'

Do you know how to fix the error?

Thanks in advance.

Ahau 03-25-2013 10:55 AM

try a semicolon after your last list item (before do, else bash thinks 'do' is one of the items to perform the for loop on), and another semicolon on the line before done. You also need to let bash know [i] is your variable, with $i.

Try this:
Code:

for i in 2 3 4 5 6 7 8 9 10; do
/usr/bin/pdfunite test.pdf chap[$i].pdf test.pdf;
done


colucix 03-25-2013 10:56 AM

You missed a semicolon before the do keyword (plus a $ sign to evaluate the i variable inside the loop)
Code:

for i in 2 3 4 5 6 7 8 9 10;  do
  /usr/bin/pdfunite test.pdf chap[$i].pdf test.pdf
done

or in alternative:
Code:

for i in 2 3 4 5 6 7 8 9 10
do
  /usr/bin/pdfunite test.pdf chap[$i].pdf test.pdf
done

Edit: too late! ;)

Mike_M 03-25-2013 10:56 AM

On line 1 you either need a semicolon before " do", or "do" needs to be on its own line.

Examples:

Code:

#!/bin/sh
for i in 2 3 4 5 6 7 8 9 10; do
  /usr/bin/pdfunite test.pdf chap[$i].pdf test.pdf
done


Code:

#!/bin/sh
for i in 2 3 4 5 6 7 8 9 10
do
  /usr/bin/pdfunite test.pdf chap[$i].pdf test.pdf
done


trainee 03-25-2013 11:13 AM

Thanks for the tips. I fixed the error. Now something else comes up.

I run the script and got this message:
Code:

Syntax Error: Catalog object is wrong type (null)
Syntax Error: Catalog object is wrong type (null)
Syntax Error: Catalog object is wrong type (null)
Syntax Error: Catalog object is wrong type (null)
Syntax Error: Catalog object is wrong type (null)
Syntax Error: Catalog object is wrong type (null)
Syntax Error: Catalog object is wrong type (null)
Syntax Error: Catalog object is wrong type (null)
Syntax Error: Catalog object is wrong type (null)

and this is the output of ls-al
Code:

drwxr-xr-x  2 dat root  4096 Mar 25 12:11 .
drwx--x--x 27 dat root  4096 Mar 25 12:09 ..
-rw-r--r--  1 dat root 394200 Mar 25 10:40 back.pdf
-rw-r--r--  1 dat root 456464 Mar 25 10:40 chap1.pdf
-rw-r--r--  1 dat root 792229 Mar 25 10:40 chap10.pdf
-rw-r--r--  1 dat root 645207 Mar 25 10:40 chap2.pdf
-rw-r--r--  1 dat root 566813 Mar 25 10:40 chap3.pdf
-rw-r--r--  1 dat root 887743 Mar 25 10:40 chap4.pdf
-rw-r--r--  1 dat root 463453 Mar 25 10:40 chap5.pdf
-rw-r--r--  1 dat root 422404 Mar 25 10:40 chap6.pdf
-rw-r--r--  1 dat root 833556 Mar 25 10:40 chap7.pdf
-rw-r--r--  1 dat root 752984 Mar 25 10:40 chap8.pdf
-rw-r--r--  1 dat root 503119 Mar 25 10:40 chap9.pdf
-rw-r--r--  1 dat root 199399 Mar 25 10:40 front.pdf
-rw-r--r--  1 dat root 646077 Mar 25 12:11 test.pdf
-rwxr-xr-x  1 dat root    100 Mar 25 12:09 testrun.sh

and this is the code of the shell
Code:

#!/bin/bash
for i in 2  3 4 5 6 7 8 9 10
do
        /usr/bin/pdfunite test.pdf chap[$i].pdf test.pdf
done

I tried for both chap$i.pdf and chap[$i].pdf, same error.

colucix 03-25-2013 11:26 AM

According to the pdfunite man page you can try to do it without a loop and by means of extended brace expansion:
Code:

/usr/bin/pdfunite chap{1..10}.pdf test.pdf
Anyway the "Catalog object is wrong type (null)" error is not from bash, but maybe from pdfunite itself. Therefore maybe something is wrong with the PDF files?

trainee 03-25-2013 11:28 AM

As mentioned in the earlier post, I tried that and got the same error.

Mike_M 03-25-2013 11:34 AM

There may be problems with your PDF files.

Also, pdfunite may not work when your destination PDF file is the same as one of your source PDF files.

trainee 03-25-2013 11:45 AM

Yes, Mike_M. You are right. Is there anyway I can type a command that listed chap1.pdf chap2.pdf til chap10.pdf without having to spell them out all. Thanks.

Mike_M 03-25-2013 12:13 PM

I'm sure there are many ways to do this, but the first that pops in to mind would be using concatenation to build your final command. Something along the lines of the following:


Code:

#!/bin/sh

PDFUNITE='/usr/bin/pdfunite'
OUTFILE='test.pdf'
PDFUNITE_ARGS=""

for i in {1..10}
do
  PDFUNITE_ARGS="$PDFUNITE_ARGS chap$i.pdf"
done

$PDFUNITE $PDFUNITE_ARGS $OUTFILE

[edit]
See colucix' answer in post #6 for the obviously better solution :)

trainee 03-25-2013 12:44 PM

Very nice. I should have thought of that. Thank you very much.

TobiSGD 03-25-2013 12:53 PM

The code previously shown by colucix does the same in a much more elegant way, provided that you use a modern shell, like Bash (most likely) or Zsh:
Code:

/usr/bin/pdfunite chap{1..10}.pdf test.pdf
The shell will automatically expand chap{1..10}.pdf to all filenames it can find that matches the expression. No need for loops at all.

David the H. 03-26-2013 04:04 PM

Quote:

Originally Posted by Mike_M (Post 4918525)
I'm sure there are many ways to do this, but the first that pops in to mind would be using concatenation to build your final command. Something along the lines of the following:


Code:

#!/bin/sh

PDFUNITE='/usr/bin/pdfunite'
OUTFILE='test.pdf'
PDFUNITE_ARGS=""

for i in {1..10}
do
  PDFUNITE_ARGS="$PDFUNITE_ARGS chap$i.pdf"
done

$PDFUNITE $PDFUNITE_ARGS $OUTFILE


The idea may be ok, but the execution is wrong. You should never use simple, scalar variables for lists of things. It's very difficult to safely re-split it back into the individual entries. You should always use arrays instead for this purpose.

(But note that arrays are not supported by posix-based /bin/sh scripts. Always use /bin/bash or another shell that has explicit array ability.)

Code:

#!/bin/bash

outfile='test.pdf'
pdfunite_args=""

for i in {1..10}; do
    pdfunite_args+=( "chap$i.pdf" )
done

/usr/bin/pdfunite "${pdfunite_args[@]}" "$outfile"


Since environment variables are generally all upper-case, it's recommended practice to keep your own user variables in lower-case or mixed-case to help differentiate them.

Scripting With Style



But finally, since the chapter files are already there, you can probably just use simple globbing instead.

Code:

/usr/bin/pdfunite chap[1-9].pdf chap10.pdf "$outfile"
This is basically the same as given by colucix, but generally better, since globbing only does pattern matching on existing files, while brace expansion attempts to generate a list of all possible filenames for the pattern. Any generated names that don't have corresponding files matching them would result in "file not found" errors.

Notice how I had to separate out chap10.pdf though, since globbing produces lists in shell sorting order. For this reason I highly recommend getting into the habit of fully zero-padding all numbers in your filenames, which will let the shell automatically sort them properly.


All times are GMT -5. The time now is 07:01 PM.