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 know there is something different about the environment of the Terminal command-line and the environment in a bash script, but I don't know what that difference is...

Here is the example which finally led me to ask this quesiton; it may flush out some of the differences.

I am trying to strip leading '0's from a number, with this command.

  • var="000123"; var="${var##+(0)}" ; echo $var

When I run this command from the Terminal's command-line, I get: 123

However, when I run it from within a script, it doesn't work; I get: 000123

I'm using Ubuntu 10.04, and tried all the following with the sam results:

  • GNOME Terminal 2.30.2
  • Konsole 2.4.5
  • #!/bin/bash
  • #!/bin/sh

My bash version 4 1 5 1 release i486-pc-linux-gnu (in terminals and scripts)

'shopt' differences between CLI and Script:

    CLI   Script  
    on     off    checkwinsize    
    on     off    expand_aliases  
    on     off    extglob         
    on     off    histappend      
    off    on     hostcomplete    

What is causing this difference?

Even if some upgrade will make it work in scripts...
I am trying to find out the what and why, so in future, I'll know what to look out for.


Here are 3 bash ways to strip leading '0's. (I knew only one when I first asked this queston)

var=0001230; var="$[10#$var]";           echo $var   # fastest= 1.00  integers only
var=0001230; var="${var##+(0)}";         echo $var   # slower x 1.25  works with strings, but requires shopt -s extglob
var=0001230; var="${var#${var%%[!0]*}}"; echo $var   # slower x 1.61  works with strings  
share|improve this question
    
Can you clarify the purpose of var="${var##+(0)} ? I assume it's some shell formatting mechanism but could find any details about it. –  João Pinto Jan 10 '11 at 9:10
    
It strips leading, (only leading) strings.. like "^\(abc\)\+" in sed/grep... I went a-hunting the other day... and after much rummaging and scrummaging, I found this... and it suited my needs perfectly... (As I recall, there was some mention of it being new, and you would neeed "such-and-such".. I tried it (in the terminal, and it worked, so I didn't pay any special attention to it until now, when I used it in a script... –  Peter.O Jan 10 '11 at 9:28

2 Answers 2

up vote 2 down vote accepted

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.

share|improve this answer
    
loevborg. I have added comment below my question about the use of ##+(0)... and about my current bash version. –  Peter.O Jan 10 '11 at 10:21
    
I've added more system specs to the body of the question –  Peter.O Jan 10 '11 at 11:19
    
loevborg, You were right on target with your reference to shopt ... Everything else seems to be the same, and there are differences in my shopt settings, so I tried to re-find the web page where I first encountered this command... Actually it was much easier to find this time :)... He mentions that extglob must be on... mine is on for the CLI, but off for scripts! .... When I precede the command with shopt -s extglob, the commands works fine!... so Thanks for that! .... (I don't know how to make this permanent setting, but I should be able to work it out (I hope :) –  Peter.O Jan 10 '11 at 12:58
    
PS. I just now found a neat and simple method to remove leading '0's which doesn't require extglob... its: var="000123000"; echo "$[10#$var]" It uses numeric-base conversion, so it only works for '0's.. the other method is string-based –  Peter.O Jan 10 '11 at 13:39
    
Don't use $[...]. It's a deprecated syntax for math in bash, and it will disappear at some point. Use $((...)) instead. –  geirha Jan 22 '11 at 17:49

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]*}}
share|improve this answer
    
Thanks Gilles, it's a great amswer and I like this "new" way to strip lead '0's... but I'm a bit OD'd on it at the moment (it, and another couple of questions) .. I'll come back to it when I've recharged my batteries..... I've added 3 "strip-lead-0s" methods as a footnote to my question.. They may be handy for someone...it took me long enough to find them! :) –  Peter.O Jan 11 '11 at 9:24

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.