Levei quase 10 anos de uso do Linux para fazer esta pergunta. Foi tudo tentativa e erro e navegação aleatória na Internet tarde da noite.
Mas as pessoas não devem precisar de 10 anos para isso. Se eu estivesse iniciando no Linux, gostaria de saber: Quando usar o pseudônimo, quando escrever e quando escrever uma função?
No caso de aliases, eu uso aliases para operações muito simples que não recebem argumentos.
alias houston='cd /home/username/.scripts/'
Isso parece óbvio. Mas algumas pessoas fazem isso:
alias command="bash bashscriptname"
(e adicione-o ao .bashrc
arquivo)
Existe uma boa razão para fazer isso? Estou me esforçando muito, mas realmente não consigo pensar em nenhuma circunstância em que eu queira fazer isso. Portanto, se houver um caso extremo em que isso faça diferença, responda abaixo.
Porque é aí que eu colocaria algo no meu PATH e chmod +x
isso, que é outra coisa que veio depois de anos de tentativa e erro do Linux.
O que me leva ao próximo tópico. Por exemplo, adicionei uma pasta oculta ( .scripts/
) no diretório inicial ao meu PATH, apenas adicionando uma linha ao meu .bashrc
( PATH=$PATH:/home/username/.scripts/
), para que qualquer coisa executável lá seja preenchida automaticamente automaticamente.
Se eu precisasse.
Eu realmente não preciso disso, preciso? Eu usaria isso apenas para linguagens que não são o shell, como Python.
Se for o shell, posso escrever uma função dentro da mesma .bashrc
:
funcname () {
somecommand -someARGS "$@"
}
Como afirmei, descobri muito disso por tentativa e erro. E só vi verdadeiramente a beleza das funções quando meu computador morreu e fui forçado a usar os computadores das pessoas ao meu redor quando não as estavam usando.
Em vez de mover um diretório inteiro de scripts de um computador para outro, acabei substituindo o .bashrc de todo mundo pelo meu, pois eles nunca fizeram uma única modificação.
Mas eu perdi alguma coisa?
Então, o que você diria a um usuário iniciante do Linux sobre quando criar um alias, quando criar um script e quando escrever uma função?
Se não for óbvio, estou assumindo que as pessoas que responderem a isso farão uso das três opções. Se você usar apenas aliases, ou apenas scripts, ou apenas funções - ou se você usar apenas aliases e scripts ou aliases e funções ou scripts e funções - , essa pergunta não será realmente direcionada a você.
fonte
Respostas:
Um alias efetivamente não deve (em geral) fazer mais do que alterar as opções padrão de um comando. Não passa de simples substituição de texto no nome do comando. Ele não pode fazer nada com argumentos, mas passá-los para o comando que ele realmente executa. Portanto, se você simplesmente precisar adicionar um argumento na frente de um único comando, um alias funcionará. Exemplos comuns são
Uma função deve ser usada quando você precisar fazer algo mais complexo que um alias, mas que não seja útil por si só. Por exemplo, considere esta resposta em uma pergunta que eu fiz sobre
grep
o comportamento padrão da alteração , dependendo se ele está em um pipeline:É um exemplo perfeito de uma função porque é muito complexo para um alias (exigindo diferentes padrões com base em uma condição), mas não é algo que você precisará em um script não interativo.
Se você obtiver muitas funções ou funções muito grandes, coloque-as em arquivos separados em um diretório oculto e origine-as em
~/.bashrc
:Um script deve ser independente. Deve ter valor como algo que pode ser reutilizado ou usado para mais de uma finalidade.
fonte
.
ou,source
um script é executado por um processo bash separado e possui seu próprio ambiente. Por esse motivo, qualquer coisa que modifique o ambiente do shell (por exemplo, funções, variáveis etc.) não persistirá no ambiente do shell a partir do qual você executa o script.As outras respostas fornecem algumas diretrizes gerais suaves baseadas no gosto pessoal, mas ignoram muitos fatos pertinentes que devem ser considerados ao decidir entre scripts, funções ou aliases.
Aliases e funções ¹
Scripts
$PATH
pesquisa, muitos shells armazenam um hash do nome do caminho na memória para economizar tempo em$PATH
pesquisas futuras , mas essa é a extensão da pegada de memória de um script quando não estiver em uso.Os scripts podem ser chamados de mais maneiras do que as funções e aliases. Eles podem ser passados como argumento para um intérprete, como
sh script
ou invocados diretamente como um executável; nesse caso, o intérprete na linha shebang (por exemplo#!/bin/sh
) é invocado para executá-lo. Nos dois casos, o script é executado por um processo de intérprete separado, com seu próprio ambiente separado daquele do seu shell, cujo ambiente o script não pode afetar de forma alguma. De fato, o shell do intérprete nem precisa corresponder ao shell de chamada. Como os scripts chamados dessa maneira parecem se comportar como qualquer executável comum, eles podem ser usados por qualquer programa.Finalmente, um script pode ser lido e executado pelo shell atual com
.
, ou em alguns shellssource
. Nesse caso, o script se comporta como uma função que é lida por demanda, em vez de ser constantemente mantida na memória.Inscrição
Diante do exposto, podemos apresentar algumas diretrizes gerais para tornar algo um script ou função / alias.
Outros programas além do seu shell precisam ser capazes de usá-lo? Se assim for, tem que ser um script.
Deseja que ele esteja disponível apenas a partir de um shell interativo? É comum querer alterar o comportamento padrão de muitos comandos quando executados de maneira interativa sem afetar comandos / scripts externos. Nesse caso, use um alias / function definido no arquivo rc "somente no modo interativo" do shell (pois
bash
é isso.bashrc
).Precisa mudar o ambiente do shell? Uma função / alias ou um script de origem são escolhas possíveis.
É algo que você usa com frequência? Provavelmente é mais eficiente mantê-lo na memória; portanto, torne-o uma função / alias, se possível.
Por outro lado, é algo que você usa apenas raramente? Nesse caso, não faz sentido armazená-la quando você não precisar, então faça disso um script.
Functions Embora funções e aliases tenham algumas diferenças importantes, eles são agrupados porque as funções podem fazer tudo o que é alias. Os aliases não podem ter variáveis locais, nem podem processar argumentos e são inconvenientes por qualquer coisa além de uma linha.
² Todo processo em execução em um sistema Unix possui um ambiente que consiste em vários
variable=value
pares que geralmente contêm definições de configuração global, comoLANG
a localidade padrão ePATH
a especificação do caminho de pesquisa executável.fonte
alias g='gradle'
eu recebo autocompletion Gradle quando usando o meug
apelido, mas não vai conseguir out-of-the-box ao usar um script comgradle $*
ou uma função comgradle $@
Eu acho que depende do gosto de cada pessoa. Para mim, a lógica é assim:
Não há realmente nada para impedi-lo de fazer algo que funcione .
fonte
Pelo menos parcialmente, é uma questão de gosto pessoal. Por outro lado, existem algumas distinções funcionais claras:
Olhando para scripts de shell que fiz nos últimos anos, parei mais ou menos de escrever aliases (porque todos tendem a crescer em funções ao longo do tempo) e só crio scripts se precisar estar disponível também em ambientes que não sejam do bash.
PS: Quanto a
alias command="bash bashscriptname"
, na verdade, não vejo motivo para fazer isso. Mesmo quebashscriptname
não esteja em $ PATH, um simplesalias c=/path/to/script
seria suficiente.fonte
alias command="bash bashscriptname"
script não precisa necessariamente ser executável; noalias c=/path/to/script
que tem que.exec()
descascar funções" :-)Aqui estão alguns pontos adicionais sobre aliases e funções:
Por exemplo:
Como podemos ver, existem espaços de nomes separados para aliases e funções; mais detalhes podem ser encontrados usando
declare -A -p BASH_ALIASES
edeclare -f f
, que imprime suas definições (ambas são armazenadas na memória).Exemplo mostrando limitações de aliases:
Como podemos ver, os aliases não são aninhados, ao contrário das funções. Além disso, seu uso é limitado às sessões interativas.
Por fim, observe que você pode ter computação arbitrária em um alias declarando uma função chamando-a imediatamente, assim:
que já é amplamente utilizado no caso de aliases do Git. O benefício de fazer isso ao declarar uma função é que seu alias não pode ser simplesmente substituído pela origem (ou uso
.
) de um script que declara uma função com o mesmo nome.fonte
Quando escrever um script ...
export
variáveis e / ou funções ed são passadas por valor ao script. As alterações nessas variáveis não se propagam de volta para o script pai.Quando escrever uma função ...
Quando escrever um pseudônimo ...
~/.profile
ou~/.bashrc
.Em scripts como scripts de biblioteca, algumas vezes é necessário um alias para uma função, como quando uma função é renomeada, mas é necessária compatibilidade com versões anteriores. Isso pode ser conseguido criando uma função simples com o nome antigo que passa todos os seus argumentos para a nova função ...
fonte
Outra coisa que não acredito ter sido levantada: uma função é executada no contexto do processo de chamada, enquanto um script bifurca um novo shell.
Isso pode ser importante para o desempenho - uma função é mais rápida, pois não
fork()
eexec()
. Em circunstâncias normais, a diferença é trivial, mas se você estiver depurando um sistema que está com memória insuficiente e com thrashing de página, isso pode fazer uma grande diferença.Além disso, se você quiser modificar seu ambiente de shell atual, use uma função Por exemplo, uma função pode alterar a pesquisa de comando
$PATH
do shell atual, mas um script não pode, porque opera em uma cópia fork / exec de$PATH
.fonte
export -f
uma função, embora o funcionamento interno preciso disso seja um pouco obscuro. Isso não é portátil para o shell Bourne tradicional, acredito.Script e alias e script e função não são mutuamente exclusivos. Você pode armazenar aliases e funções em scripts.
Scripts são apenas códigos que se tornam persistentes . Funções úteis e aliases que você deseja usar no futuro são armazenados em scripts. No entanto, um script geralmente é uma coleção de mais de uma função.
Como os aliases não são parametrizados , eles são muito limitados; geralmente para definir alguns parâmetros padrão.
Uma função é uma unidade de código separada , um conceito bem definido de algumas linhas de código que não podem ser separadas em partes menores e úteis; um que pode ser reutilizado diretamente ou outro por outras funções.
fonte
Se for muito rápido, torne-o um alias ou uma função.
Se for utilizável fora do seu shell preferido, torne-o um script. 1 1
Se receber argumentos, torne-o uma função ou um script.
Se precisar conter caracteres especiais, torne-o um alias ou um script. 2
Se precisar trabalhar com o sudo, torne-o um alias ou um script. 3
Se você deseja alterá-lo facilmente sem fazer logoff e logon, um script é mais fácil. 4
Notas de rodapé
1 Ou crie um alias, coloque-o
~/.env
e defina-oexport ENV="$HOME/.env"
, mas é complicado fazê-lo funcionar de maneira portável.2 Os nomes das funções devem ser identificadores; portanto, devem começar com uma letra e podem conter apenas letras, dígitos e sublinhados. Por exemplo, eu tenho um alias
alias +='pushd +1'
. Não pode ser uma função.3 E adicione o alias
alias sudo='sudo '
. O mesmo deve ser atribuído a qualquer outro comando, comostrace
,gdb
etc., que aceita um comando como seu primeiro argumento.4 Veja também: fpath. Claro que você também pode fazer
source ~/.bashrc
ou algo parecido, mas isso geralmente tem outros efeitos colaterais.fonte
+
no bash. Curiosamente, após o teste, descobri que no bash você pode criar+
um alias, mas não uma função, como você diz, mas o zsh é o inverso -+
pode ser uma função, mas não um alias.zsh
você tem que escreveralias -- +='some command here'
.+
é portátil. Veja a especificação POSIX sobre nomes de aliassudo
uso. Em relação à nota de rodapé 4, eu armazeno meus apelidos~/.bash_aliases
e definições de funções~/.bash_functions
para que eu possa substituí-source
los facilmente (sem qualquer perigo de efeitos colaterais).Apenas para adicionar algumas notas:
Fora isso, você pode usar a forma mais simples possível, ou seja, primeiro considere o alias, depois a função e o script.
fonte
sudo
. Mas primeiro você precisaalias sudo='sudo '
.Minha regra de ouro é:
fonte
Em um ambiente multiusuário (ou multi sysamin), eu uso scripts para tudo, mesmo que acabe sendo um invólucro curto de 'exec something ....'.
Claro, é tecnicamente mais lento / menos eficiente do que um alias ou função, mas isso quase nunca importa - e desde que esteja no caminho, um script sempre funciona.
Seu recurso pode ser chamado do cron, de algo com um ambiente reduzido ou modificado, como sudo ou env, ou o usuário pode estar apenas usando um shell diferente para você - todos ou que provavelmente quebrarão um alias ou função.
Se você tiver algo sensível ao desempenho, lide com isso como um caso especial ou, melhor ainda, considere isso um gatilho para reescrever em uma linguagem de script mais funcional.
Se estivermos falando sobre recursos que serão usados apenas em outros scripts, considere também definir um shell padrão e escrever um script da biblioteca de funções que possa ser apenas. originado I para todos os outros scripts.
T
fonte
Um exemplo para uma situação em que você provavelmente gostaria de usar um alias.
Sei que este é um post antigo, mas gostaria de apontar uma situação em que quase precisei usar uma combinação de alias com um script e optei por não usar uma função.
Eu tenho um script
~/.bin/
chamadosetup
que faz o seguinte: 1O ponto é que, se eu apenas executasse
setup <project-name>
, não teria essas variáveis definidas e nem teria chegado ao diretório. A solução que eu encontrei para ser o melhor foi adicionar este script paraPATH
e adicionaralias setup=". ~/.bin/setup"
a~/.bashrc
ou qualquer outra coisa.Notas:
fonte
Quando escrever um script
Quando você desejar executar o comando a partir de uma ferramenta que não seja o shell.
Isso inclui o vim (para mim): tendo escrito filtros e outros programas como scripts, posso fazer algo como
:%!my-filter
filtrar um arquivo através do programa do meu editor.Se
my-filter
fosse uma função ou um alias, isso não seria possível.fonte