Funções Bash, algo estranho acontecendo!

5

Eu sou novo em funções bash, mas estava começando a escrever alguns pedaços para acelerar o fluxo de trabalho. Eu gosto de testar isso, então eu me vi editando e obtendo muito do meu ~ / .profile e achei ~/. um pouco difícil de digitar ...

Então, a primeira coisa que pensei em fazer foi o seguinte:

sourceProfile(){
    source ~/.profile
}

editProfile(){
    vim ~/.profile && sourceProfile
}

ao executar editProfile, estou recebendo um problema na chamada sourceProfile. Inicialmente eu estava recebendo o erro:

-bash: ~./profile: No such file or directory

Observe a falta de erros na minha função!

No entanto, funciona se eu usar um alias.

alias sourceProfile='source ~/.profile'

No entanto, depois de adicionar esse alias e, em seguida, comentá-lo e descomentar a função, comecei a receber um erro de sintaxe:

-bash: /home/jonathanramsden/.profile: line 45: syntax error near unexpected token '('
-bash: /home/jonathanramsden/.profile: line 45: 'sourceProfile(){'

a linha que segue é:

alias sservice='sudo service'

Tenho certeza que tudo que fiz foi comentar / descomentar! E com base no meu googling parece que é a sintaxe para definir funções.

    
por Jonny Leeds 05.10.2017 / 11:36

2 respostas

5

Os aliases são como alguma forma de expansão de macro, semelhante ao pré-pré-processamento feito em C com #define , exceto que em shells, não há delimitação clara e óbvia entre a etapa de pré-processamento e a de interpretação (também, aliases não são expandidos em todos os contextos e pode haver várias rodadas de expansão de apelidos como com aliases aninhados).

Quando você faz:

alias sourceProfile='source ~/.profile'
sourceProfile() {
  something
}

A expansão do alias a transforma em:

source ~/.profile() {
  something
}

que é um erro de sintaxe. E:

alias sourceProfile='source ~/.profile'
editProfile(){
  vim ~/.profile && sourceProfile
}

Transforma em:

editProfile(){
  vim ~/.profile && source ~/.profile
}

Portanto, se mais tarde você redefinir sourceProfile como uma função, editProfile não chamará, porque a definição de editProfile tem o valor expandido do alias original.

Além disso, para funções (ou qualquer comando composto), os aliases são expandidos apenas na hora da definição da função (enquanto são lidos e analisados), e não no tempo de execução. Então isso:

editProfile(){
  vim ~/.profile && sourceProfile
}
alias sourceProfile='source ~/.profile'
editProfile

não funcionará porque sourceProfile não foi definido no momento em que o corpo da função editProfile foi analisado e não haverá nenhuma expansão de alias no momento da execução da função editProfile .

Portanto, evite misturar aliases e funções. E tenha cuidado com as implicações de usar aliases, pois eles não são realmente comandos , mas alguma forma de expansão de macro.

    
por 06.10.2017 / 12:58
1

Ao testar funções de teste, certifique-se de recarregar ( source ) a definição de função entre cada edição, ou a definição de função mais antiga ainda estará ativa. Não há erro de digitação em sua função, e você não deve receber essa mensagem de erro (não posso reproduzi-la aqui), o que significa que você não está executando a função como está escrita.

Além disso, sugiro que você comece a usar $HOME em vez de ~ ao escrever scripts, principalmente porque ~ não se comporta como uma variável (veja Por que o til (~) não expande aspas duplas? ).

Sugestão:

edit_profile () {
    local EDITOR=${EDITOR:-vim}
    local file="$HOME/.profile"

    "$EDITOR" "$file" && source "$file"
}

A variável file é extra, mas a variável EDITOR pode já estar definida para um editor sensato. Caso contrário, o código define como vim .

    
por 05.10.2017 / 11:56

Tags