JP Vossen on 23 Apr 2010 22:16:02 -0700


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: [PLUG] Bash script problems - no "function" support?


> Date: Fri, 23 Apr 2010 14:35:30 -0400
> From: Mike Leone <turgon@mike-leone.com>
> 
> So I'm trying to run the bash script JP posted the other day, and it's 
> failing, for reasons I can't quite figure out.
> 
> $ bash -n snag-files.sh
> 'nag-files.sh: line 15: syntax error near unexpected token `{
> 'nag-files.sh: line 15: `function _file_size {
[...]


Short answer: somehow you are getting dash, not bash.  Unless /bin/bash 
is somehow mangled into /bin/dash, I'm not sure how that could happen. 
(You are using #!/bin/bash, as I had hard-coded and as is shown in the 
test script, right?)

They AREN'T the same, see: 
http://princessleia.com/plug/2008-JP_bash_vs_dash.pdf


### My Ubuntu 8.04 host looks like this:
[jp@host:T2:L1:C1127:J0:2010-04-24_00:54:06_EDT]
/tmp$ \ls -l /bin/*sh
-rwxr-xr-x 1 root root 813912 2008-05-12 14:36 /bin/bash
-rwxr-xr-x 1 root root 100856 2009-03-09 09:18 /bin/dash
lrwxrwxrwx 1 root root      4 2009-04-30 17:51 /bin/rbash -> bash
lrwxrwxrwx 1 root root      4 2009-04-30 17:51 /bin/sh -> dash

[jp@host:T2:L1:C1129:J0:2010-04-24_00:55:46_EDT]
/tmp$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 8.04.4 LTS
Release:	8.04
Codename:	hardy

[jp@host:T2:L1:C1130:J0:2010-04-24_00:55:49_EDT]
/tmp$ md5sum /bin/*sh
e90d860c96c540807c251c8a49ae39bc  /bin/bash
4bc9bc6278af1af2bd5590dd96aa25da  /bin/dash
e90d860c96c540807c251c8a49ae39bc  /bin/rbash
4bc9bc6278af1af2bd5590dd96aa25da  /bin/sh

Note the file sizes.  That's a major reason why Ubuntu is using dash; 
it's a lot smaller and therefor a lot faster to start and that adds up 
when you are running a gazillion shell scripts, like when you are booting...



LONG answer:
AKA, the long and winding road I took to get to the above....

I hope I didn't cause more trouble than I'm worth with that script.  But 
'bash -n' runs clean for me, so I suspect one of three things.

Very likely, someone's mail agent broke a line, and thus broke the 
script.  I hate sending attachments to mailing lists, so I've forwarded 
it as an attachment directly to Mike.

If that isn't it, maybe your /bin/bash is somehow goofed up with 
/bin/dash.  dash supports functions but does not use the 'function' 
keyword.  OTOH, I like to use function (even though it's not portable to 
dash), because it's nice and greppable when I want a function list.

Finally, if somehow it got DOS CRLF in the file (via mail agent, 
Notepad, etc.) you can get *really* goofy error like that.


> =================
> 
> Seems to think that the function declaration is invalid. Looks right to 
> me, from what I can tell. However, even the sample script using 
> functions fails: (<http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-8.html>)
> 
> =================
> $ more test.sh
> #!/bin/bash
> function quit {
>                exit
>                }
> function hello {
>                  echo Hello!
>                 }
> hello
> quit
> echo foo
> 
> $ sh test.sh
> test.sh: 2: function: not found
> 
> ==============
> 
> So why are functions not being recognized on my system? Ubuntu 8.04. The 
> shell for this user is explicitly set to "/bin/bash" in /etc/passwd.

The /etc/passwd field is only the interactive setting, whatever the 
script has in the shebang line (#!/bin/......) will take precedence to 
run the script, else Perl and friends wouldn't work.


I was going to accuse you of creating that with Notepad and saving or 
copying to Linux, but I get a slightly different error when I do that:

### Works for me:
[jp@ringo:T2:L1:C1078:J0:2010-04-24_00:45:12_EDT]
/tmp$ cat test.sh
#!/bin/bash
function quit {
                exit
                }
function hello {
                  echo Hello!
                 }
hello
quit
echo foo


[jp@ringo:T2:L1:C1078:J0:2010-04-24_00:46:03_EDT]
/tmp$ ./test.sh
Hello!

### Break it with CRLFs
[jp@ringo:T2:L1:C1079:J0:2010-04-24_00:46:06_EDT]
/tmp$ unix2dos test.sh

[jp@ringo:T2:L1:C1080:J0:2010-04-24_00:47:26_EDT]
/tmp$ ./test.sh
bash: ./test.sh: /bin/bash^M: bad interpreter: No such file or directory


Hummmm...  Not quite the same error.  So maybe only some CRLFs?  Does a 
'dos2unix test.sh' help?  (you probably have to do 'aptitude install 
tofrodos' to get dos2unix)  Else, as Brent already suggested:

1) run with bash -x
2) Find out what /bin/bash really is:
	\ls -l /bin/*sh

The more I think about it, the more I think you've got dash somehow 
mixed up in this...

# Ubuntu 9.10
[jp@ringo:T2:L1:C1084:J0:2010-04-24_00:53:55_EDT]
/tmp$ dos2unix test.sh

# Hummmmmmmm!  Bingo.
[jp@ringo:T2:L1:C1085:J0:2010-04-24_00:59:10_EDT]
/tmp$ dash test.sh
test.sh: 2: function: not found


Also, may I suggest that you not name scripts and functions with 
reserved words like test, you will get nothing but trouble.  (Yes, that 
is a recipe in the book. :)  Technically, test.sh is OK, since it isn't 
quite 'test', but...  Likewise, spell it out and *don't* assume that 
/bin/sh is bash; it increasingly isn't.

Good luck,
JP

PS--I did see the other question about groups and perms.  Been swamped, 
and am still thinking about that...
----------------------------|:::======|-------------------------------
JP Vossen, CISSP            |:::======|      http://bashcookbook.com/
My Account, My Opinions     |=========|      http://www.jpsdomain.org/
----------------------------|=========|-------------------------------
"Microsoft Tax" = the additional hardware & yearly fees for the add-on
software required to protect Windows from its own poorly designed and
implemented self, while the overhead incidentally flattens Moore's Law.
___________________________________________________________________________
Philadelphia Linux Users Group         --        http://www.phillylinux.org
Announcements - http://lists.phillylinux.org/mailman/listinfo/plug-announce
General Discussion  --   http://lists.phillylinux.org/mailman/listinfo/plug