porque o código de erro 1 retornou carregando o .bash_profile no Mac

7

Sempre que eu abro um terminal bash, o código de erro 1 é retornado:

Last login: Tue Jan 15 16:19:53 on ttys000
spam@moss:~ $ echo $?
1

Descobri que isso é causado pela última linha de código no meu .bash_profile :

test -f $HOME/.debug && export profile_bash_profile='.bash_profile' || return 0

Se eu remover essa linha, o código de erro 0 será retornado. Eu não entendo como esta linha pode causar algum problema, porque eu posso fornecer .bash_profile com o código de erro 0:

spam@moss:~ $ source .bash_profile
spam@moss:~ $ echo $?
0

Atualização:

Alguém sabe como o Mac carrega ~ / .bash_profile? Eu duvido que o Mac o utilize quando um shell de login for iniciado. Parece que o comando return não é executado como esperado - quando coloco return 5 como a última linha de ~/.bash_profile e inicio um shell de login, ele não retorna o código de erro 5 (e estou certo de que ~/.bash_profile é o último script carregado).

    
por RNA 16.01.2013 / 00:37

2 respostas

5

Observe que o que acontece quando usar return fora de uma função sem ter source d o script (por exemplo, return ing de .bash_profile ) não está documentado em man bash .

A diferença está em como o código de retorno de um script ou função é registrado internamente em bash . Se você return um valor, esse valor é atribuído ao código de retorno do código chamado , por exemplo a chamada de função da qual você retorna ou o comando source . Como não há tal chamador ao retornar de .bash_profile durante a inicialização do shell, esse valor é simplesmente descartado. O que você está acessando como $? é o código de retorno da declaração anterior .

Usando o bash-86.1 da Apple como referência:

Se você source um script, seu conteúdo será analisado e executado até que uma instrução return seja encontrada. Seu valor de retorno é registrado separadamente e é de responsabilidade do responsável pela chamada ( execute_command_internal in bash-3.2/execute_cmd.c ) atribuir seu valor à variável que contém o último código de saída: last_command_exit_value .

Se for chamado como um script de inicialização, ele será carregado por meio de uma chamada para maybe_execute_file na função run_startup_files em bash/shell.c . Não é a execução regular do comando: Embora o conteúdo do arquivo seja executado corretamente, incluindo o return final, ninguém se importa com o valor real que você está retornando. É simplesmente descartado.

Então, qual comportamento você está vendo aqui ? Essencialmente o mesmo que se você tivesse chamado return sem argumento: Como return simplesmente retornou o código de retorno do comando anterior, que, no seu caso, é o teste com falha.

Como obter o comportamento desejado? Como você não pode exit de .bash_profile sem sair do shell, é necessário verificar se o comando imediatamente anterior produz o código de retorno desejado, neste caso:

test -f $HOME/.debug && export profile_bash_profile='.bash_profile' || { true; return; }
    
por 15.02.2013 / 22:06
2

Eu percebi o seguinte por tentativa e erro. Talvez um guru da BASH possa explicar um pouco mais.

  1. .bashrc contents:

    test -f $HOME/existent_file || return 4
    

    Depois de abrir um novo terminal:

    $ echo $?
    0
    
  2. .bashrc contents:

    test -f $HOME/non_existent_file || return 4
    

    Depois de abrir um novo terminal:

    $ echo $?
    1
    
  3. .bashrc contents:

    function foo () { 
        return 4 
    }
    foo;
    

    Depois de abrir um novo terminal:

    $ echo $?
    4
    
  4. .bashrc contents:

    return 4
    

    Depois de abrir um novo terminal:

    $ echo $?
    0
    
  5. Com o mesmo .bashrc acima:

    $ source ~/.bashrc
    $ echo $?
    4
    
  6. Esses comandos são executados diretamente de um terminal:

    $ test -f $HOME/existent_file  || return 4
    $ echo $?
    0
    $ test -f $HOME/non_existent_file  || return 4
    bash: return: can only 'return' from a function or sourced script
    $ echo $?
    1
    

Portanto, return só funciona de funções e arquivos originados. Eu não sei como o usuário ~/.bashrc é lido, mas aparentemente ele não é originado.

    
por 17.01.2013 / 18:24