Eu costumava usar o CShell (csh), que permite criar um alias que aceita um parâmetro. A notação era algo como
alias junk="mv \\!* ~/.Trash"
No Bash, isso parece não funcionar. Dado que o Bash tem uma infinidade de recursos úteis, eu assumiria que este foi implementado, mas estou me perguntando como.
"$1"
ls
parals -la
, em seguida, digitandols foo bar
seria realmente executarls -la foo bar
. Na linha de comando"alias test_args="echo PREFIX --$1-- SUFFIX"
, que quando chamado comtest_args ABCD
rendimentos a seguinte saída do consolePREFIX ---- SUFFIX ABCD
Respostas:
O alias do bash não aceita parâmetros diretamente. Você terá que criar uma função.
alias
não aceita parâmetros, mas uma função pode ser chamada como um alias. Por exemplo:A propósito, as funções do Bash definidas no seu
.bashrc
e em outros arquivos estão disponíveis como comandos no seu shell. Por exemplo, você pode chamar a função anterior como estafonte
$1
aspas?source
seu .bashrc adicionará a função, mas não anulará o antigo alias. Como os aliases são precedentes mais altos que as funções, ele tentará usar o alias. Você precisa fechar e reabrir seu shell, ou então chamarunalias <name>
. Talvez eu salve alguém nos 5 minutos que desperdicei.exec bash
: Ele iniciará um novo shell, fornecendo uma leitura limpa de suas configurações, como se você fechasse e reabrisse, mas mantendo também as configurações variáveis de ambiente da sessão . Além disso, executarbash
sem o exec pode ser útil quando você deseja manipular os pensamentos como uma pilha.mv "$1" "$1.bak"
. sem aspas, se $ 1 fosse "olá mundo", você executaria emmv hello world hello world.bak
vez demv "hello world" "hello world.bak"
.Refinando a resposta acima, você pode obter uma sintaxe de 1 linha, como é possível para aliases, o que é mais conveniente para definições ad-hoc em arquivos shell ou .bashrc:
Não se esqueça do ponto e vírgula antes do colchete direito de fechamento. Da mesma forma, para a pergunta real:
Ou:
fonte
mv "$1" "$1.bak"; cp "$2" "$1"
paramv "$1" "$1.bak" && cp "$2" "$1"
para não perder seus dados quandomv
houver problemas (por exemplo, sistema de arquivos cheio).A pergunta é simplesmente feita errada. Você não
alias
cria um alias que aceita parâmetros porque apenas adiciona um segundo nome para algo que já existe. A funcionalidade que o OP deseja é ofunction
comando para criar uma nova função. Você não precisa aliasar a função, pois a função já tem um nome.Eu acho que você quer algo assim:
É isso aí! Você pode usar os parâmetros $ 1, $ 2, $ 3, etc, ou apenas encher todos eles com $ @
fonte
echo -e '#!/bin/bash\nshopt -s expand_aliases\nalias asrc='\''echo "${BASH_SOURCE[0]}"'\'' # note the '\''s\nfunction fsrc(){ echo "${BASH_SOURCE[0]}";}'>>file2&&echo -e '#!/bin/bash\n. file2\nalias rl='\''readlink -f'\''\nrl $(asrc)\nrl $(fsrc)'>>file1&&chmod +x file1&&./file1;rm -f file1 file2
$@
para suportar nomes de arquivos com espaços, etc.TL; DR: faça isso em vez disso
É muito mais fácil e mais legível usar uma função do que um alias para colocar argumentos no meio de um comando.
Se você continuar lendo, aprenderá coisas que não precisa saber sobre o processamento de argumentos de shell. O conhecimento é perigoso. Apenas obtenha o resultado que deseja, antes que o lado sombrio controle seu destino para sempre.
Esclarecimento
bash
aliases fazer aceitar argumentos, mas apenas no final :Colocar argumentos no meio do comando via
alias
é realmente possível, mas fica feio.Não tente fazer isso em casa, crianças!
Se você gosta de contornar as limitações e fazer o que os outros dizem ser impossível, aqui está a receita. Só não me culpe se seu cabelo estiver desgrenhado e seu rosto acabar coberto de fuligem ao estilo de cientista louco.
A solução alternativa é passar os argumentos que
alias
aceitam apenas no final para um wrapper que os insira no meio e execute seu comando.Solução 1
Se você é realmente contra usar uma função em si, você pode usar:
Você pode substituir
$@
por$1
se desejar apenas o primeiro argumento.Explicação 1
Isso cria uma função temporária
f
, à qual são passados os argumentos (observe quef
é chamado no final). Eleunset -f
remove a definição da função, pois o alias é executado para que não fique por aí depois.Solução 2
Você também pode usar um subshell:
Explicação 2
O alias cria um comando como:
Comentários:
O espaço reservado
_
é obrigatório, mas pode ser qualquer coisa. Ele é definido comosh
's'$0
e é necessário para que o primeiro dos argumentos fornecidos pelo usuário não seja consumido. Demonstração:As aspas simples dentro das aspas simples são necessárias. Aqui está um exemplo de que não funciona com aspas duplas:
Aqui, os valores dos shell interativos
$0
e$@
são substituídos pelo duplo entre aspas antes de serem passados parash
. Aqui está a prova:As aspas simples garantem que essas variáveis não sejam interpretadas pelo shell interativo e sejam transmitidas literalmente para
sh -c
.Você pode usar aspas duplas e
\$@
, mas a melhor prática é citar seus argumentos (pois eles podem conter espaços) e\"\$@\"
parecer ainda mais feio, mas pode ajudá-lo a vencer um concurso de ofuscação em que cabelos desgrenhados são um pré-requisito para entrada.fonte
alias gc='git checkout'
$@
? Eles são necessários se você tiver, por exemplo, arquivos com espaços neles.Uma solução alternativa é usar o marcador , uma ferramenta que eu criei recentemente que permite "marcar" modelos de comando e colocar facilmente o cursor nos espaços reservados para comandos:
Descobri que, na maioria das vezes, estou usando funções de shell para não precisar escrever comandos usados com freqüência na linha de comando. A questão do uso de funções para este caso de uso é adicionar novos termos ao meu vocabulário de comando e ter que lembrar quais parâmetros de funções se referem no comando real. O objetivo do marcador é eliminar esse fardo mental.
fonte
Tudo que você precisa fazer é criar uma função dentro de um alias:
Você deve colocar aspas duplas em torno de "$ 1", pois aspas simples não funcionarão.
fonte
bash: syntax error near unexpected token '{mkdir'
.;
dentro da função,_mkcd
provavelmente o erro é disso.{
e}
Aqui estão três exemplos de funções que tenho no meu
~/.bashrc
, que são essencialmente aliases que aceitam um parâmetro:.
.
.
Referências:
fonte
O alias do Bash absolutamente aceita parâmetros. Acabei de adicionar um alias para criar um novo aplicativo de reação que aceita o nome do aplicativo como parâmetro. Aqui está o meu processo:
Abra o bash_profile para editar no nano
Adicione seus aliases, um por linha:
Salvar e sair do nano editor
Diga ao terminal para usar os novos aliases em .bash_profile
É isso aí! Agora você pode usar seus novos aliases
fonte
NB: Caso a idéia não seja óbvia, é uma má idéia usar aliases para qualquer coisa, exceto alias, sendo o primeiro a 'função em um alias' e o segundo o 'difícil redirecionar / fonte'. Além disso, existem falhas (que eu pensei que seriam óbvias, mas apenas no caso de você estar confuso: não pretendo que elas sejam realmente usadas ... em qualquer lugar!)
.................................................. .................................................. ............................................
Eu já respondi isso antes, e sempre foi assim no passado:
o que é bom e bom, a menos que você esteja evitando o uso de funções todos juntos. Nesse caso, você pode aproveitar a vasta capacidade do bash para redirecionar texto:
Ambos têm aproximadamente o mesmo comprimento, fornecem ou recebem alguns caracteres.
O verdadeiro kicker é a diferença de tempo, sendo a parte superior o 'método da função' e a parte inferior o método da 'fonte de redirecionamento'. Para provar essa teoria, o momento fala por si:
Esta é a parte inferior de cerca de 200 resultados, feitos em intervalos aleatórios. Parece que a criação / destruição de funções leva mais tempo que o redirecionamento. Esperemos que isso ajude os futuros visitantes a esta pergunta (não queria mantê-la para mim).
fonte
Se você estiver procurando uma maneira genérica de aplicar todos os parâmetros a uma função, não apenas uma ou duas ou outra quantidade codificada, você pode fazer isso desta maneira:
Portanto, no exemplo acima, passo todos os parâmetros a partir de quando corro
runjar
para o alias.Por exemplo, se eu fizesse
runjar hi there
isso acabaria realmente em execuçãojava -jar myjar.jar hi there
. Se eu fizesserunjar one two three
isso iria correrjava -jar myjar.jar one two three
.Gosto desta
$@
solução porque funciona com qualquer número de parâmetros.fonte
runjar
vez de torná-la um alias para uma função? Parece desnecessariamente complicado!alias
(ou têm as propriedades das coisas passadasalias
) nos arquivos bash? se sim, então eu simplesmente não sei disso #alias runjar='java -jar myjar.jar'
. Os aliases aceitam argumentos, mas apenas no final.Respeitosamente para todos aqueles que dizem que você não pode inserir um parâmetro no meio de um alias, eu apenas testei e descobri que funcionava.
alias mycommand = "python3" $ 1 "script.py --folderoutput RESULTADOS /"
quando executei meu comando foobar, ele funcionou exatamente como se eu tivesse digitado o comando à mão.
fonte
alias myalias="echo 1 "$1" 3"; myalias 2
dá:1 3 2
Existem razões técnicas legítimas para querer uma solução generalizada para o problema de o alias do bash não ter um mecanismo para reposicionar argumentos arbitrários. Uma razão é se o comando que você deseja executar seria afetado negativamente pelas mudanças no ambiente resultantes da execução de uma função. Em todos os outros casos, as funções devem ser usadas.
O que recentemente me levou a tentar uma solução para isso é que eu queria criar alguns comandos abreviados para imprimir as definições de variáveis e funções. Então, eu escrevi algumas funções para esse fim. No entanto, existem certas variáveis que são (ou podem ser) alteradas por uma chamada de função. Entre eles estão:
FUNCNAME BASH_SOURCE BASH_LINENO BASH_ARGC BASH_ARGV
O comando básico que eu estava usando (em uma função) para imprimir defns de variáveis. na saída do formulário pelo comando set foi:
Por exemplo:
Problema: Isso não imprimirá as definições das variáveis mencionadas acima, como estão no contexto atual , por exemplo, se em um prompt de shell interativo (ou não em nenhuma chamada de função), FUNCNAME não estiver definido. Mas minha função me diz a informação errada:
Uma solução que eu encontrei foi mencionada por outras pessoas em outros posts sobre esse tópico. Para que este comando específico imprima a variável defns., E que requer apenas um argumento, eu fiz o seguinte:
O que fornece a saída correta (nenhuma) e o status do resultado (falso):
No entanto, ainda me sentia obrigado a encontrar uma solução que funcionasse para números arbitrários de argumentos.
Uma solução geral para passar argumentos arbitrários para um comando com alias do Bash:
Por exemplo:
Uma coisa boa dessa solução é que todos os truques especiais usados para manipular parâmetros posicionais (argumentos) para comandos funcionarão ao compor o comando interceptado. A única diferença é que a sintaxe da matriz deve ser usada.
Por exemplo,
Se você deseja "$ @", use "$ {CMD_ARGV [@]}".
Se você quiser "$ #", use "$ {# CMD_ARGV [@]}".
Etc.
fonte
Uma vez eu fiz um projeto divertido e ainda o uso. Está mostrando alguma animação enquanto eu copio arquivos via
cp
comando cozcp
, não mostramos nada e é meio frustrante. Então eu fiz esse aliasE este é o script spiner
É assim
Animação Ciclada)
fonte
Para obter parâmetros, você deve usar funções!
No entanto, $ @ é interpretado ao criar o alias em vez de durante a execução do alias e escapar do $ também não funciona. Como eu resolvo este problema?
Você precisa usar a função shell em vez de um alias para se livrar desse problema. Você pode definir foo da seguinte maneira:
OU
Por fim, chame seu foo () usando a seguinte sintaxe:
Certifique-se de adicionar seu foo ()
~/.bash_profile
ou~/.zshrc
arquivo.No seu caso, isso funcionará
fonte
As funções são de fato quase sempre a resposta, já amplamente contribuída e confirmada por esta citação da página de manual: "Para quase todos os propósitos, os aliases são substituídos pelas funções de shell".
Para garantir a integridade e como isso pode ser útil (sintaxe ligeiramente mais leve), pode-se observar que, quando os parâmetros seguem o alias, eles ainda podem ser usados (embora isso não atenda aos requisitos do OP). Provavelmente, isso é mais fácil de demonstrar com um exemplo:
permite digitar smth like
ssh_disc myhost
, que é expandido conforme o esperado:ssh -O stop myhost
Isso pode ser útil para comandos que usam argumentos complexos (minha memória não é mais o que costumava ser ...)
fonte
Ambas as funções e aliases podem usar parâmetros como outros mostraram aqui. Além disso, gostaria de destacar alguns outros aspectos:
1. função é executada em seu próprio escopo, alias compartilha escopo
Pode ser útil conhecer essa diferença nos casos em que você precisa ocultar ou expor algo. Também sugere que uma função é a melhor escolha para encapsulamento.
Resultado:
2. script wrapper é uma escolha melhor
Ocorreu-me várias vezes que um alias ou função não pode ser encontrado ao efetuar login via
ssh
ou envolvendo a alternância de nomes de usuário ou ambiente multiusuário. Existem dicas e truques com arquivos de ponto de origem, ou um interessante com alias:alias sd='sudo '
permite que esse alias subseqüentealias install='sd apt-get install'
funcione conforme o esperado (observe o espaço extrasd='sudo '
). No entanto, um script de wrapper funciona melhor que uma função ou alias em casos como este. A principal vantagem de um script de wrapper é que ele é visível / executável para o caminho pretendido (por exemplo, / usr / loca / bin /) onde, como função / alias, precisa ser originado antes de ser utilizado. Por exemplo, você coloca uma função em ~ / .bash_profile ou ~ / .bashrc forbash
, mas depois muda para outro shell (por exemplo,zsh
), a função não está mais visível. Portanto, quando você está em dúvida, um script de wrapper é sempre a solução mais confiável e portátil.fonte
source
em uma função funciona muito bem.f () { source /tmp/nst; }
faz exatamente o que eu espero. Talvez vocêPATH
esteja errado, então isso corre erradoactivate
ou algo assim; mas corrersource
de uma função funciona bem.function
palavra - chave em sua definição, consulte wiki.bash-hackers.org/scripting/obsolete -function funcname {
é uma sintaxe antiga do ksh que o bash suporta para compatibilidade retroativa com shells pré-POSIX, enquantofuncname() {
é a sintaxe oficial padronizada do POSIX.function funcname() {
é um erro fatal dos dois que não é compatível com o ksh antigo ou compatível com o POSIX sh e, portanto, é melhor evitar.Aqui está o exemplo:
Muito importante:
{
e antes}
.;
após cada comando em sequência. Se você esquecer isso após o último comando, verá um>
prompt!"$1"
fonte
Como já foi apontado por outros, o uso de uma função deve ser considerado uma prática recomendada.
No entanto, aqui está outra abordagem, aproveitando
xargs
:Observe que isso tem efeitos colaterais em relação ao redirecionamento de fluxos.
fonte
Você não precisa fazer nada, o alias faz isso automaticamente.
Por exemplo, se eu quiser tornar o mestre de origem do git pull parametrizado, posso simplesmente criar um alias da seguinte maneira:
e quando realmente chamá-lo, você pode passar 'master' (o nome do ramo) como um parâmetro, como este:
fonte