0

I am getting the following error

/tmp/filechecking.sh: line 11: warning: here-document at line 6 delimited by end-of-file (wanted `EOF')
/tmp/filechecking.sh: command substitution: line 8: unexpected EOF while looking for matching `"'
/tmp/filechecking.sh: command substitution: line 11: syntax error: unexpected end of file
/tmp/filechecking.sh: line 6: bad substitution: no closing "`" in `
echo "${filetype[@]}"
done

My script is

losystem=`ls /appl/vortex/archive/cons/*`
echo "${losystem[@]"
for indsystm in "${losystem[@]}"
do
filetype=`isql -UDAS -PCDRD -SYTRT_DCS_FRET << EOF
select  file_type  from expected_file where  starters_package_version = '4.0' and system_id = 'DAL'
go
EOF`
echo "${filetype[@]}"
done

Can somebody help what is the syntax error here'

4
losystem=`ls /appl/vortex/archive/cons/*`
echo "${losystem[@]"
for indsystm in "${losystem[@]}"
do
filetype=`isql -UDAS -PCDRD -SYTRT_DCS_FRET << EOF
select  file_type  from expected_file where  starters_package_version = '4.0' and system_id = 'DAL'
go
EOF`
echo "${filetype[@]}"
done

The syntax error itself is caused by the backtick appearing on the same line as EOF, as indicated in Kusalananda's answer. However, this script has other problems, so in the interest of better shell scripting abilities everywhere, let's take a closer look.


First misconception: As you reference "${losystem[@]}", you seem to be under the impression that you have created an array. You haven't. To do that, you need to use parentheses in your variable assignment.

Similarly, if you do use an array, you don't need to use ls. The globs will expand directly to become the elements of the array.

This is fortunate, because you should never parse the output of ls, anyway; see:

So the right way to set the variable losystem as an array whose elements are the files and directories inside /appl/vortex/archive/cons/ is:

losystem=(/appl/vortex/archive/cons/*)

Your echo command (on the second line) is missing a closing }.

Also, you may want to use printf here instead:

printf '%s\n' "${losystem[@]}"

Also see:


The for loop is correct for iterating over the elements of the Bash array losystem, so given that you've made the above corrections, you can use it unchanged.

However, you don't need to set an array, and it's much more idiomatic (cleaner, more intuitive) to directly state the file glob in the for loop:

for indsystem in /appl/vortex/archive/cons/*; do

This also has the advantage of being POSIX-compliant, since it doesn't rely on Bash arrays, so it can work in a wider variety of shells (i.e. it's more portable).


The next part of your script is even trickier to review, because it appears that you are setting filetype to the output of the isql command, but then you don't do anything with this output except print it—badly formatted—with echo. (Again, see Why is printf better than echo?)

The obvious approach is not to set the variable at all, but just run the command directly; it will print its own output, which is all you really wanted anyway:

isql -UDAS -PCDRD -SYTRT_DCS_FRET << EOF
select  file_type  from expected_file where  starters_package_version = '4.0' and system_id = 'DAL'
go
EOF

Note that I am not familiar with isql, so I do not attest the correctness of this command. It is the command you yourself wrote, unchanged. It may or may not be correct.


The strangest thing about this script, though, is the fact that you are setting indsystem to each element of the losystem array (or trying to), but then you never reference the value of "$indsystem".

This is the "elephant in the room." I can't fix this logic, because I can't read your mind. It's not at all clear what you are trying to do.

I can think of several different possibilities:

  1. Perhaps you are trying to run the isql command on each file in the cons directory. (In which case the isql command should reference the indsystem variable somewhere, and you should check that you don't run it on directories.)
  2. Perhaps you want to run the isql command exactly once, but only if the cons directory is not empty.
  3. Perhaps you want to run the isql command without referencing indsystem, but run it the same way multiple times, exactly as many times as there are files/directories in the cons directory. (This is what my fixed version of the code will do, but it doesn't make a whole lot of sense.)

None of these possibilities are obviously correct, so I can't conclude what the script is actually trying to do.

Still, I hope this was helpful in learning more about shell scripting. To learn Bash scripting properly, I recommend the Wooledge Bash Guide.


I will also comment that in my professional experience, I have found that a shell script with as many problems as this one usually has architectural/design problems at a higher level, and that usually it is necessary to completely review the supposed reason why the script is needed in the first place to get a truly workable solution.

1

The end delimiter of the here-document should be alone on the line:

filetype=`isql -UDAS -PCDRD -SYTRT_DCS_FRET << EOF
select  file_type  from expected_file where  starters_package_version = '4.0' and system_id = 'DAL'
go
EOF
`

It is often recommended to use $(...) rather than backticks for new code, as $(...) have better nesting capabilities and in general just looks better:

filetype=$( isql -UDAS -PCDRD -SYTRT_DCS_FRET <<EOF
select  file_type 
  from  expected_file
  where starters_package_version = '4.0' 
    and system_id = 'DAL'
go
EOF
)

For information about why using $(...) may be preferrable, see "Have backticks (i.e. `cmd`) in *sh shells been deprecated?"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.