Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I'm writing a script to copy some files around, and trying to use shopt -s dotglob to enable cp to copy dotfiles like .jshint and whatnot.

I can run shopt -s dotglob directly at a bash prompt with no error. However, running the script throws the error:

script.sh: 81: script.sh: shopt: not found

I'm running this script in bash shell, with the shebang header #!/usr/bin/env bash. Error line:

shopt -s dotglob
cp -r $TEMP/img/* $TARGET/img/
cp -r $TEMP/js/* $TARGET/js/
cp -r $TEMP/less/* $TARGET/less/

Not finding anything helpful on google, any idea what the problem is here?

share|improve this question
    
Thanks for the reminder, selected answers for all that I could. Still one besides this question that doesn't have a good answer yet. –  Kurtosis Aug 27 '12 at 8:15
    
Thanks, much appreciated :) –  izx Aug 27 '12 at 8:15
3  
Try with the simpler #!/bin/bash header? –  izx Aug 27 '12 at 8:17
    
And which Ubuntu version? –  izx Aug 27 '12 at 8:19
1  
@izx, that is the right answer, shopt is a bash builtin, sh does not have shopt, and the error message looks like an error message from dash. So most likely the error here is running a bash script with sh (which in Ubuntu is dash by default). Even if sh is a symlink to bash, running a bash script with sh is not the same as running it with bash. –  geirha Aug 27 '12 at 10:25
add comment

2 Answers

up vote 7 down vote accepted

To form an answer from the comments:

Many people out of habit run their scripts with sh instead of bash. This is a good practice if portability is a concern, but many people do so because they're copying something they've seen without understanding it.

Unless your script needs to run on a non-desktop Linux system (e.g., running shell scripts on Android devices is quite different), I recommend using the Bash shebang line at the beginning:

#!/bin/bash

This line, when it's the first line in the script, determines which interpreter (shell such as bash or sh, Python, etc.) is called to execute it. If you use the above line, you'll get the same behavior (almost) as you do from the command line, assuming you use the default shell. If for reasons of portability or preference you use a different shebang line, be aware that you'll have to consult the documentation for the shell you've referenced, even if the shell you reference is a symlink to Bash.

share|improve this answer
    
That did the trick, thanks. –  Kurtosis Aug 28 '12 at 7:21
    
To be completely cross-system, I prefer: #!/usr/bin/env bash as it is env's job to know which bash to use (in case you've patched it, for example). –  shrikeh Jan 25 at 14:16
add comment

use the full (absolute) path to the binary your script is trying to run. So, instead of just entering shopt by itself, you would enter

/usr/bin/shopt

This ensures that you’re running the binary that you want to, but it’s a more “brittle” approach. If your script is run on a system where the binary you are calling is in a different location, your script will break when the command is not found. One approach to help cut down on this drawback is to use the whereis command to locate the command for you.

share|improve this answer
3  
Unfortunately shopt is not a binary, it's a builtin bash command, so it's not in the system path. You call it from a bash shell or, I thought anyway, a bash script. –  Kurtosis Aug 27 '12 at 8:16
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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