LinuxQuestions.org
Latest LQ Deal: Complete CCNA, CCNP & Red Hat Certification Training Bundle
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 02-06-2012, 04:50 AM   #1
make
Member
 
Registered: Apr 2004
Distribution: Mandriva, Ubuntu, openSuSE, FreeBSD, OpenSolaris, PC-BSD
Posts: 195

Rep: Reputation: 30
bash script: Syntax error: redirection unexpected


This is probably an easy thing for you shell gurus but I'm banging my head to the wall with it. I updated Debian Lenny (5) to Squeeze (6). Now my script suddenly stopped working. Something has changed with bash.

Code:
#!/bin/bash

url=''

while grep -qv 'STOP$' <<<"$url"
do
  read -n1 next
  url="$url$next"
done
This part of the script is the problem. It is supposed to read characters into the variable $url until it gets a string "STOP" at the end of the URL address. It is used in our internal enterprise scripts.

It causes an error:
Code:
Syntax error: redirection unexpected
It refers to the line:
Code:
while grep -qv 'STOP$' <<<"$url
...so this line needs to be changed somehow.
 
Old 02-06-2012, 06:23 AM   #2
everToulouse
LQ Newbie
 
Registered: Apr 2010
Posts: 18

Rep: Reputation: 5
hi,

sh is no longer a link to bash, but to dash which doesn't know about `<<<' that is not POSIX.
 
Old 02-08-2012, 12:30 AM   #3
make
Member
 
Registered: Apr 2004
Distribution: Mandriva, Ubuntu, openSuSE, FreeBSD, OpenSolaris, PC-BSD
Posts: 195

Original Poster
Rep: Reputation: 30
Quote:
Originally Posted by everToulouse View Post
sh is no longer a link to bash, but to dash which doesn't know about `<<<' that is not POSIX.
So how do I get my scripts working again? Do I need to copy the old bash from the old Debian Lenny installation? Is there any other way?
 
Old 02-08-2012, 01:01 AM   #4
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 373Reputation: 373Reputation: 373Reputation: 373
Well, the easiest solution would be to remove the change, right?

So, if /bin/sh was a symlink to /bin/bash in Lenny, but is now a symlink to /bin/dash, then you can point it back to /bin/bash. For instance, as root:
Code:
# cd /bin
# ln -sf bash sh
If you're not an administrator, then this is not a viable solution of course.

If your script is being invoked somewhere with "sh /path/to/script.bash" then it would probably be better to change that to "bash /path/to/script.bash" or better yet, because your script identifies the interpreter in the shebang line, make the script executable and invoke it directly: "/path/to/script.bash"

If there is some system utility invoking the script (e.g. cron) and it defaults to "sh /path/to/script.bash" you will need to change the symlink (as described above) or figure out how to configure that utility to launch your script with bash or launch the script directly (as described in the above paragraph)

Or, lastly, modify all your scripts to use POSIX-only syntax.

There may be other possible fixes, but those are what immediately come to mind.

Keep in mind, if you change the symlink, there could be a problem if any of the Debian maintainers included scripts that depend on dash features (just as you have scripts that depend on bash features). I think the chances of that would be minimal because, as far as I know, bash supports most (if not all) the POSIX syntax and/or feature set.
 
Old 02-08-2012, 01:44 AM   #5
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,576
Blog Entries: 31

Rep: Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195
When run from the command line by ./test.sh (and so the shebang line is effective and it is run by bash), make's script does not give a syntax error but does hang. This when using bash version 4.1.7 (as determined by bash --version).

@make: what is the output of bash --version ?
 
Old 02-08-2012, 02:06 AM   #6
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 373Reputation: 373Reputation: 373Reputation: 373
Interesting. I'm running Debian 6.0.3. It has bash 4.1.5 installed.

I pasted the script into a file, gave execute permissions, and ran it.

The script waited for input on stdin as expected until I typed "STOP" at which point it immediately ended.

So if it hangs on your end catkin, then there was a feature change in either 4.1.6 or 4.1.7.
 
Old 02-08-2012, 02:39 AM   #7
make
Member
 
Registered: Apr 2004
Distribution: Mandriva, Ubuntu, openSuSE, FreeBSD, OpenSolaris, PC-BSD
Posts: 195

Original Poster
Rep: Reputation: 30
Thank you for all the replies. Here's my bash version:
Code:
GNU bash, versio 4.1.5(1)-release (x86_64-pc-linux-gnu)
I just realized that I can run the scripts by typing "bash script-name.sh". This works without problems. How stupid of me... I assumed that it automatically took the "/bin/bash" specified in the beginning of the file, but it did not.

What would be the POSIX syntax of my script? Would it be better to change the scripts anyway?
 
Old 02-08-2012, 03:24 AM   #8
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 373Reputation: 373Reputation: 373Reputation: 373
Quote:
Originally Posted by make
I just realized that I can run the scripts by typing "bash script-name.sh". This works without problems. How stupid of me... I assumed that it automatically took the "/bin/bash" specified in the beginning of the file, but it did not.
I agree with you. It should look at the interpreter specified in the shebang line. That is, after all, why it's there. But, somewhere there is some code that examines the file suffix and overrides (or ignores) the shebang line. In this case, your script has a ".sh" extension, and that code (wherever it is) decides to launch your script using /bin/sh.

On a minor rant here: it takes more effort to type "#!/bin/bash" than it does to give a filename a ".sh" extension. So, logically speaking, the greater effort should trump the lesser effort because, obviously, greater care/time went into the greater effort. It is dumb to ignore the shebang line when it's present. When I started using Linux, one of the "great differences" between Windows and Linux touted by the users was that Linux did not care about file extensions--Linux "figured it out." Ironic that the shell now seems to care more about file extensions than the shebang line by default.

Quote:
Originally Posted by make
What would be the POSIX syntax of my script? Would it be better to change the scripts anyway?
I'm on my way to bed. So, I'll give you some untested/unverified code that I think is POSIX and accomplishes the same task.
Code:
#!/bin/bash

url=''
while read inputLine ; do
  stopTest=`echo "${inputLine}" | grep 'STOP$'`
  if [ "${stopTest}x" = "x" ] ; then
    url="${url}${inputLine}"
  else
    exit 0
  fi
done

Last edited by Dark_Helmet; 02-08-2012 at 03:28 AM.
 
Old 02-08-2012, 03:52 AM   #9
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,576
Blog Entries: 31

Rep: Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195
Quote:
Originally Posted by Dark_Helmet View Post
The script waited for input on stdin as expected until I typed "STOP" at which point it immediately ended.

So if it hangs on your end catkin, then there was a feature change in either 4.1.6 or 4.1.7.
Sorry -- when I wrote "hangs" I meant it waited for user input. It behaves the same way that you describe.
 
Old 02-08-2012, 03:54 AM   #10
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,576
Blog Entries: 31

Rep: Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195
Quote:
Originally Posted by make View Post
I just realized that I can run the scripts by typing "bash script-name.sh". This works without problems.
How were you running it before?
 
Old 02-08-2012, 04:08 AM   #11
make
Member
 
Registered: Apr 2004
Distribution: Mandriva, Ubuntu, openSuSE, FreeBSD, OpenSolaris, PC-BSD
Posts: 195

Original Poster
Rep: Reputation: 30
Quote:
Originally Posted by catkin View Post
How were you running it before?
./script-name.sh


Dark_Helmet: Your script works otherwise, but requires an enter press to stop. I couldn't immediately figure how to make it work like mine (so that it stops immediately upon finishing the word "STOP").

Of course, the most important thing is that I have my scripts now working. Just need to run them with a different command.
 
Old 02-08-2012, 07:49 AM   #12
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,576
Blog Entries: 31

Rep: Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195
Quote:
Originally Posted by make View Post
./script-name.sh
That should work, given the shebang line.

What is the output of /bin/bash --version ?
 
Old 02-08-2012, 01:54 PM   #13
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 373Reputation: 373Reputation: 373Reputation: 373
Quote:
Originally Posted by make
Dark_Helmet: Your script works otherwise, but requires an enter press to stop. I couldn't immediately figure how to make it work like mine (so that it stops immediately upon finishing the word "STOP").
Yeah, I should have mentioned that the new version would require a newline for the script to process the input. I'm not sure there is a POSIX construct that would allow you access to the input character-by-character as they are entered.

As for the shebang-file extension conflict... I have not located the source, although I've been motivated to investigate some. I did encounter man update-binfmts which describes a kernel-based file extension-interpreter registry. I ran "/usr/sbin/update-binfmts --display" expecting to see an association between a "sh" extension and "/bin/sh" but there was none. The only listings on my system were for python, wine, java, and cli/mono.

Other people have encountered the file extension problem as well. I had helped another user with an expect script. Even with the correct shebang line pointing to the local installation of expect, his script failed because the filename has a "sh" extension and was being invoked with /bin/sh. Only when he renamed it with a "exp" extension (or something similar) did the correct interpreter get launched.

Anyway, if you don't want to bother with it, use a file extension of "bash" or remove the extension entirely.

Or... wait till someone tracks down the source and posts here
 
1 members found this post helpful.
Old 02-08-2012, 02:26 PM   #14
make
Member
 
Registered: Apr 2004
Distribution: Mandriva, Ubuntu, openSuSE, FreeBSD, OpenSolaris, PC-BSD
Posts: 195

Original Poster
Rep: Reputation: 30
Quote:
Originally Posted by catkin View Post
What is the output of /bin/bash --version ?
Code:
GNU bash, versio 4.1.5(1)-release (x86_64-pc-linux-gnu)
As long as bash doesn't get any updates that would make my scripts obsolete (strictly POSIX-only), the problem can be considered as solved. So in the end this thread was helpful. The solution was just simpler than I expected. Running the scripts with "bash script-name" is fine with me, regardless of the extensions.

Funny how I never paid attention how these shells were symlinked. Been using Debian for 10 years. I always assumed they were separate binaries and never took a closer look inside /bin. Learning new things every day.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Bash script problem: syntax error near unexpected token `do rmaier9 Programming 3 08-21-2014 05:20 AM
bash script syntax error: unexpected end of file? smecnb Linux - Newbie 11 02-25-2013 12:44 AM
Bash script -----------syntax error: unexpected end of file ArthurHuang Programming 2 05-01-2009 10:29 AM
Bash script - syntax error: unexpected end of file Mr Pink Programming 7 12-19-2008 06:31 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

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

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration