Como passar argumentos de linha de comando para um alias do shell?

288

Como passo os argumentos da linha de comando para um alias? Aqui está uma amostra:

alias mkcd = 'mkdir $ 1; cd $ 1; '

Mas, neste caso, o $ xx está sendo traduzido no alias, criando tempo e não em tempo de execução. No entanto, criei uma solução alternativa usando uma função shell (depois de pesquisar um pouco) como abaixo:

função mkcd () {
  mkdir $ 1
  cd $ 1
}

Só queria saber se existe uma maneira de criar aliases que aceitem parâmetros de CL.
BTW - Eu uso 'bash' como meu shell padrão.

Vini
fonte
2
Possível duplicata do alias Make a Bash que aceita um parâmetro?
Tripleee
2
O / T, mas sobre como uma alternativa para fazer uma função mkcd, você pode escrevermkdir mydirectoryname && cd $_
Moala

Respostas:

174

Você encontrou o caminho: crie uma função em vez de um alias. O shell C possui um mecanismo para gerar argumentos para aliases, mas o bash e o shell Korn não, porque o mecanismo de função é mais flexível e oferece o mesmo recurso.

Charlie Martin
fonte
No entanto, você não precisa de funções ao criar aliases no .bashrcarquivo. Por exemplo, # crie um alias que leva o número da porta pelo alias do usuário serve = "python -m SimpleHTTPServer $ 1" Depois de fazer a alteração no arquivo .bashrc, certifique-se de inserir o seguinte comando. ~ $ Source .bashrc Você deve ser capaz de usar este como assim ~ $ servir 8998
kaizer1v
8
@ kaizer1v, Minha observação na versão 4.2.46 do CentOS7.3 bash é que sua sugestão não funciona como você pensa. Como você está usando aspas duplas, o $ 1 está sendo avaliado como uma sequência vazia e o alias é o mesmo que o alias serve = "python -m SimpleHTTPServer" e, portanto, o que você passa depois desse alias também é passado na linha de comando. Se você tentar este conjunto -x; alias serve = "python -m SimpleHTTPServer $ 1 &" você verá o erro / problema. Seu argumento e o comando alias são executados como comandos separados.
PatS
279

Apenas para reiterar o que foi publicado para outros shells, no Bash os seguintes trabalhos:

alias blah='function _blah(){ echo "First: $1"; echo "Second: $2"; };_blah'

Executando o seguinte:

blah one two

Fornece a saída abaixo:

First: one
Second: two
Thomas Bratt
fonte
4
Ótima solução. Algumas perguntas de um iniciante no bash: a função precisa ser nomeada com um sublinhado (ou diferente) ou isso é apenas para facilitar a leitura? Qual é o propósito do final "; _blah" na definição da função? Por que não funciona ao usar aspas duplas no lugar de aspas simples (o $ 1 não é interpretado corretamente) mesmo quando se faz algo que não requer aspas ao redor do $ 1? Agradecemos antecipadamente pelo conselho. Eu tenho uma solução funcional, mas sempre gosto de entender mais sobre por que funciona.
Mynameispaulie 11/11
4
@mynameispaulie A função pode ter qualquer nome. Eu usei um prefixo de um sublinhado, pois é um truque comum para ajudar a evitar colisões de nomes (ou seja, outra função com o mesmo nome)
Thomas Bratt
6
@mynameispaulie As aspas duplas permitem Bashsubstituir $1e $2pelos parâmetros passados ​​para a função. Aspas simples dizem ao Bash para não fazer isso.
Thomas Bratt
5
Vejo esse alias / função combo copiar / colar muito, mas parece não servir a nenhum propósito útil. A abordagem padrão seria definir a função uma vez, com um nome sensato, e não ter um alias.
tripleee
16
Não vejo como isso é preferível afunction blah(){ echo "First: $1"; echo "Second: $2"; }
René Nyffenegger
57

Você não pode no ksh, mas no csh.

alias mkcd 'mkdir \!^; cd \!^1'

No ksh, a função é o caminho a percorrer. Mas se você realmente queria usar o alias:

alias mkcd='_(){ mkdir $1; cd $1; }; _'
Sanjaya R
fonte
Como uma observação interessante, acho que a vulnerabilidade de execução remota de código de que todo mundo fala recentemente envolve fazer quase exatamente a mesma coisa, mas em uma variável de ambiente sendo definida pela entrada bruta do usuário. openwall.com/lists/oss-security/2014/09/24/11
Floegipoky
@ Flloegipoky - porque está em um alias e não em um env var, é substancialmente diferente. O problema do ShellShock é que ele é executado quando o env var é definido. Definir um env var deve ser uma operação segura. Nenhum script é executado quando o alias acima é definido, somente quando o alias é executado.
Sanjaya R
Talvez deva ser salientado que cshgeralmente não é o que uma pessoa moderna deve querer usar. O alias-que-cria-uma-função-depois-executa-aquela-função é relativamente popular, mas não oferece nenhum benefício sobre uma função adequada, tanto quanto posso dizer. (A função deve citar corretamente seu argumento, de qualquer maneira.) Voto a favor.
tripleee
17

Para citar a página do manual bash:

Não há mecanismo para usar argumentos no texto de substituição. Se argumentos forem necessários, uma função shell deve ser usada (consulte FUNÇÕES abaixo).

Parece que você respondeu sua própria pergunta - use uma função em vez de um alias

Chris Dodd
fonte
12

Você também pode achar este comando útil:

mkdir dirname && cd $_

onde dirname é o nome do diretório que você deseja criar

tdecs
fonte
1
@StarDust $_é a saída do último comando unix.stackexchange.com/a/271693/169772
Taylor Edmiston
5

Eu descobri que funções não podem ser escritas em ~/.cshrc arquivo. Aqui no alias que leva argumentos

por exemplo, argumentos passados ​​para o comando 'find'

alias fl "find . -name '\!:1'"     
Ex: >fl abc

onde abc é o argumento passado como!: 1

kumar palaniappan
fonte
4
Isso não é útil para o OP, cujo shell padrão é bash. E a resposta de Sanjaya R mencionou aliases de csh há 4 anos.
Keith Thompson
1
A resposta de Sanjaya R não explicou o que !:1significava. Eu tive que rolar para baixo para ver aqui que era o argumento. Uma boa resposta não deixa mais perguntas, mesmo que não fosse do tipo de shell do OP.
searchengine27
4

A maneira mais fácil é usar a função e não o alias. você ainda pode chamar uma função a qualquer momento a partir do CLI. No bash, você pode simplesmente adicionar o nome da função () {command}, que carrega o mesmo que um alias.

function mkcd() { mkdir $1; cd $1 ;}

Não tenho certeza sobre outras conchas

Luke Attard
fonte
1

Isso funciona no ksh:

$ alias -x mkcd="mkdir \$dirname; cd \$dirname;"
$ alias mkcd
mkcd='mkdir $dirname; cd $dirname;'
$ dirname=aaa 
$ pwd
/tmp   
$ mkcd
$ pwd
/tmp/aaa

A opção "-x" torna o alias "exportado" - o alias é visível nos subshells.

E esteja ciente do fato de que os aliases definidos em um script não são visíveis nesse script (porque os aliases são expandidos quando um script é carregado, não quando uma linha é interpretada). Isso pode ser resolvido com a execução de outro arquivo de script no mesmo shell (usando ponto).


fonte
-2

Aqui está um exemplo simples de função usando python. Você pode colocar ~ / .bashrc
Você precisa de um espaço após o primeiro colchete esquerdo
O comando python precisa estar entre aspas duplas para obter a substituição da variável
Não se esqueça do ponto e vírgula no final

função count () {python -c "para num in xrange ($ 1): print num";}

$ count 6
0
1
2
3
4
5
$
AAAfarmclub
fonte
-5

Um alias vazio executará seus argumentos:

alias DEBUG=
Peter Sharp
fonte
12
Vejo pelo seu representante que você é novo no SO (Stack Overflow). Por favor, não fique consternado com a votação da sua resposta. Foi rejeitada porque realmente não responde à pergunta que o OP (Pôster original) pediu para responder. Pendure-os e continue tentando. Além disso, ao responder, tente incluir um exemplo simples de como sua resposta funciona e mostre a saída. Isso ajudará outras pessoas a ver como sua resposta funciona.
PatS