Por que não consigo chamar dois aliases com “;”?

5

Quando tento combinar dois comandos normais usando o caractere ; (por exemplo, ls; cd ), ele funciona bem. No entanto, tenho dois aliases que criei ( stopdev e startdev ) e se eu tentar combiná-los:

stopdev; startdev

ou mesmo se eu tentar adicionar um ponto e vírgula depois de um:

stopdev;

Eu recebo um erro de sintaxe:

bash: syntax error near unexpected token ';'

Eu também tenho o mesmo problema se eu usar && :

stopdev && startdev

bash: syntax error near unexpected token '&&'

Estou confuso com isso porque pensei que os aliases eram como qualquer outro comando ... mas claramente eles não são.

Então, duas perguntas:

  1. Por que usar ; ou && com uma chamada de alias é inválida?
  2. Existe alguma maneira (além de criar um stopstartdev alias) para executar facilmente esses dois comandos juntos?

Aqui está a definição de stopdev :

alias stopdev="cd $HOME/website; make website_stop; make backend_stop;"
    
por machineghost 26.02.2016 / 19:10

1 resposta

9

Um alias é expandido simplesmente substituindo o alias por sua definição (como uma lista de tokens, não uma string, que é basicamente equivalente a pegar a string e adicionar um espaço no final). Então stopdev; true é expandido para

cd $HOME/website; make website_stop; make backend_stop; ; true
                                                      ^^^

Como você não pode ter dois pontos-e-vírgulas consecutivos na sintaxe do shell, isso é um erro de sintaxe.

Você pode remover o ; , o que tornará stopdev; startev funcionando, mas não é bom, porque qualquer argumento que você passar para stopdev será passado para make backend_stop , o que provavelmente não é desejável.

Você deve fazer isso uma função. Além disso, não execute os comandos make se o comando cd falhar.

stopdev () {
  cd "$HOME/website" && {
    make website_stop
    make backend_stop
  }
}

Uma melhoria seria fazer a função retornar um código de falha mesmo se make website_stop falhar, mas make backend_stop tiver êxito.

stopdev () {
  cd "$HOME/website" && {
    make website_stop
    ret=$?
    make backend_stop && return $ret
  }
}

Observe que isso deixa você no diretório ~/website . Para evitar alterar o diretório do processo do shell, execute a função em um subshell.

stopdev () (
  cd "$HOME/website" && {
    make website_stop
    ret=$?
    make backend_stop && return $ret
  }
)

Como alternativa, com o GNU make, você pode usar sua opção -C .

stopdev () {
  make -C "$HOME/website" website_stop
  ret=$?
  make -C "$HOME/website" backend_stop && return $ret
}

Se os alvos nunca falharem, basta passar os dois.

stopdev () (
  cd "$HOME/website" && make website_stop backend_stop
)

ou

stopdev () {
  make -C "$HOME/website" website_stop backend_stop
}
    
por 27.02.2016 / 01:16