Posso escrever um apelido que leve um argumento? [duplicado]

4

Eu tenho algumas máquinas remotas, onde eu preciso compilar alguns códigos-fonte. O que eu normalmente faço é escrever um apelido, que diz algo como:

alias g++='g++ 'pkg-config --cflags opencv --libs opencv''

Então, quando eu vou compilar remotamente, eu faço g++ -o test test.cpp .

Por alguma razão, o Ubuntu não me deixa fazer isso. Em vez disso, o Ubuntu funciona, quando eu faço:

g++ file.cpp -o file 'pkg-config --cflags opencv --libs opencv'

Mas isso significa que não posso escrever um alias para g ++. Existe uma maneira de escrever um apelido que leve uma discussão? o que devo fazer?

    
por j0h 27.01.2017 / 16:35

2 respostas

4

TL; DR: Use command g++ em uma função shell em vez de g++ em um alias.

Como 6.6 Aliases no Bash manual de referência diz:

  

Não há mecanismo para usar argumentos no texto de substituição, como   em código%. Se argumentos forem necessários, uma função de shell deve ser usada   (consulte Funções da Shell ).

Embora um alias seja expandido mesmo quando aparece na frente de um texto adicional, os aliases não suportam parâmetros posicionais (isto é, argumentos da linha de comando ), portanto você não pode usar um alias para realizar sua tarefa atual. Ou seja, você não pode usar um alias para executar um comando com argumentos especificados pelo usuário seguido por argumentos adicionais.

Como você encontrou, você pode usar um alias para tornar csh run:

g++ 'pkg-config --cflags opencv --libs opencv' file.cpp -o file

Mas não para tornar g++ file.cpp -o file executar este comando:

g++ file.cpp -o file 'pkg-config --cflags opencv --libs opencv'

Então, se você quiser, provavelmente desejará usar um função shell :

g++ () {
    command g++ 'pkg-config --cflags opencv --libs opencv' "$@"
}

Você pode:

  • Execute isso na linha de comando e ele será definido enquanto o shell atual estiver em execução, somente dentro dessa instância do shell, ou
  • adicione-o ao seu arquivo g++ file.cpp -o file e inicie um novo shell ou execute ~/.bashrc .

Isso define a função chamada . ~/.bashrc . Como, diferentemente dos aliases, as funções podem se chamar, usei o g++ embutido para evitar recursão indesejada. command chama o comando command g++ externo. g++ expande para todos os argumentos de linha de comando passados para a função.

No caso muito raro de que "$@" realmente precisava ser um alias, você poderia "trapacear" e defini-lo como um alias para uma função (assim como você pode definir um alias para qualquer outro comando). Você pode fazer isso definindo a função primeiro ou definindo-a sempre no alias (como George sugere ). No entanto, não há necessidade de você fazer isso; uma função funcionará bem.

Claro, você pode não sempre querer que g++ tenha a saída de g++ passada para ele. Portanto, você pode querer colocar a definição de alias em um arquivo e fornecê-la apenas quando quiser. Se sua definição estiver em pkg-config --cflags opencv --libs opencv em seu diretório inicial, para ativar a função, você poderá executar:

. ~/g++-fn.sh

E para desativar a função (não importa como ela foi definida), você pode executar:

unset -f g++

Devo acrescentar que, para qualquer coisa além de programas pequenos ou triviais, você deve pelo menos considerar o uso de g++-fn.sh (ao invés de invocar make com a saída de g++ de cada vez), como steeldriver sugeriu .

    
por Eliah Kagan 27.01.2017 / 18:47
2
  

Então, quando eu vou compilar remotamente

Esse é o seu principal problema. Os aliases definidos no arquivo de configuração local ou no shell interativo local não funcionarão no sistema remoto. Defina o alias no ~/.bashrc do seu computador remoto e ele funcionará.

Uma abordagem melhor seria definir uma função, como Eliah sugeriu. Mas você ainda teria que defini-lo na máquina remota, como em um alias.

    
por Sergiy Kolodyazhnyy 28.01.2017 / 03:21