How do the environments of a standard Terminal command-line and a bash script differ?

Solution 1:

Assuming that you're using the same shell in your script and in your terminal, the main difference is that ~/.bashrc is read by interactive shells but not by script-interpreting shells. The reason is that scripts are usually meant to be somewhat portable, and for that you don't want to depend on the user's shell customizations.

Many things in typical .bashrc files only apply to the command line anyway (prompt settings, key bindings). Some, like function definitions, make sense in scripts as well; typically you'd put them into a separate file and source it both from ~/.bashrc and scripts. Sometimes you want some shell options for interactive use but not in scripts, because they lead to shorter (good on the command line) but more cryptic or less portable (bad in scripts) code. There are a few things that bash does differently, e.g. history expansion (!!, etc.) is on by default only in interactive shells.

Here you're using the +(…) construct, which is a ksh extended globbing pattern. Bash doesn't enable them by default (for backward compatibility) but you can turn them on with shopt -s extglob. Apparently you have this in your ~/.bashrc.

You can put shopt -s extglob in your script, or use a portable way of truncating leading 0s from a variable such as

var=${var#${var%%[!0]*}}

Solution 2:

Your question cannot be answered quite generally. Some comments though. On my version of bash (3.1.17(1)-release), your command doesn't have the desired output even when run from the command line; the same with zsh. So presumably something is fishy about your command. I don't know what "##+(0)" is suppoed to accomplish, but "#0" succeeds in removing one leading zero. This show a way to remove arbitrary numbers of zeros.

If there really is a difference between the behavior on the command line and from a script, then most likely the script uses a different interpreter (different bash version, bash instead of zsh) or different shell options (try running shopt). The latter difference might be the result of your interactive shell sourcing $HOME/.bashrc and $HOME/.profile whereas scripts generally don't. That shouldn't affect environment variables, as they're inherited if exported, but it should affect shell options, which need to be set in every shell.