Como os ambientes de uma linha de comando padrão do Terminal e um script bash diferem?

6

Eu sei que há algo diferente no ambiente da linha de comando do Terminal e no ambiente em um script bash, mas não sei qual é a diferença ...

Aqui está o exemplo que finalmente me levou a perguntar esta pergunta; pode liberar algumas das diferenças.

Estou tentando remover 0 de um número, com este comando.

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

Quando executo este comando a partir da linha de comando do Terminal, obtenho: 123

No entanto, quando eu corro de dentro de um script, não funciona; Eu recebo: 000123

Estou usando o Ubuntu 10.04 e tentei todos os seguintes resultados com sam:

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

Minha versão bash 4 1 5 1 libera i486-pc-linux-gnu (em terminais e scripts)

Diferenças 'shopt' entre o CLI e o Script:

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

O que está causando essa diferença?

Mesmo que alguma atualização funcione em scripts ...
Eu estou tentando descobrir o que e por que , Então, no futuro, vou saber o que procurar.

Aqui estão 3 maneiras bash para remover os '0's' principais. (Eu sabia apenas um quando eu perguntei pela primeira vez esta 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  
    
por Peter.O 10.01.2011 / 09:41

2 respostas

2

Sua pergunta não pode ser respondida de maneira geral. Alguns comentários embora. Na minha versão do bash (3.1.17 (1) -release), seu comando não tem a saída desejada, mesmo quando executado a partir da linha de comando; o mesmo com zsh. Então, presumivelmente, algo é suspeito sobre o seu comando. Eu não sei o que "## + (0)" é suposto para realizar, mas "# 0" consegue remover um zero à esquerda. Este mostra uma maneira de remover números arbitrários de zeros.

Se realmente houver uma diferença entre o comportamento na linha de comando e de um script, provavelmente o script usa um interpretador diferente (diferente versão bash, bash em vez de zsh) ou opções de shell diferentes (tente executar shopt ). A última diferença pode ser o resultado da origem do shell interativo $HOME/.bashrc e $HOME/.profile , enquanto os scripts geralmente não o fazem. Isso não deve afetar as variáveis de ambiente, já que elas são herdadas se exportadas, mas devem afetar as opções do shell, que precisam ser definidas em cada shell.

    
por loevborg 10.01.2011 / 10:13
6

Supondo que você esteja usando o mesmo shell em seu script e em seu terminal, a principal diferença é que ~/.bashrc é lido por shells interativos, mas não por shells de interpretação de script. A razão é que os scripts geralmente são um pouco portáteis e, para isso, você não quer depender das personalizações do shell do usuário.

Muitas coisas em arquivos .bashrc típicos só se aplicam à linha de comando (configurações de prompt, atalhos de teclado). Alguns, como as definições de funções, também fazem sentido em scripts; Normalmente, você os colocaria em um arquivo separado e o originaria de ~/.bashrc e scripts. Às vezes, você quer algumas opções de shell para uso interativo, mas não em scripts, porque elas levam a códigos mais curtos (bons na linha de comando), mas mais crípticos ou menos portáveis (ruins em scripts). Existem algumas coisas que o bash faz de forma diferente, por ex. A expansão do histórico ( !! , etc.) está ativada por padrão apenas em shells interativos.

Aqui você está usando a construção +(…) , que é um padrão de globbing estendido ksh. O Bash não os habilita por padrão (para compatibilidade com versões anteriores), mas você pode ativá-los com shopt -s extglob . Aparentemente você tem isso no seu ~/.bashrc .

Você pode colocar shopt -s extglob em seu script ou usar uma maneira portátil de truncar o líder 0 s de uma variável como

var=${var#${var%%[!0]*}}
    
por Gilles 10.01.2011 / 22:41