¿Cómo pasar argumentos de línea de comando a un alias de shell?

288

¿Cómo paso los argumentos de la línea de comando a un alias? Aquí hay una muestra:

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

Pero en este caso, $ xx se está traduciendo en el tiempo de creación de alias y no en tiempo de ejecución. Sin embargo, he creado una solución alternativa usando una función de shell (después de buscar en Google un poco) como a continuación:

función mkcd () {
  mkdir $ 1
  cd $ 1
}

Solo quería saber si hay una manera de crear alias que acepten parámetros CL.
Por cierto, uso 'bash' como mi shell predeterminado.

Vini
fuente
2
¿Posible duplicado de Make a Bash alias que toma un parámetro?
tripleee
2
O / T, pero como una alternativa a hacer una función mkcd, puede escribirmkdir mydirectoryname && cd $_
moala el

Respuestas:

174

Encontraste el camino: crea una función en lugar de un alias. El shell C tiene un mecanismo para hacer argumentos a los alias, pero bash y el shell Korn no, porque el mecanismo de función es más flexible y ofrece la misma capacidad.

Charlie Martin
fuente
Sin embargo, no necesita funciones al crear alias en el .bashrcarchivo. Por ejemplo, # cree un alias que tome el número de puerto por el usuario alias serve = "python -m SimpleHTTPServer $ 1" Después de realizar el cambio en el archivo .bashrc, asegúrese de ingresar el siguiente comando. ~ $ source .bashrc Deberías poder usar esto así ~ $ serve 8998
kaizer1v
8
@ kaizer1v, mi observación sobre CentOS7.3 bash versión 4.2.46 es que su sugerencia no funciona como cree que funciona. Debido a que está usando comillas dobles, el $ 1 en realidad se está evaluando en una cadena vacía y el alias es en realidad el mismo que alias serve = "python -m SimpleHTTPServer", por lo que lo que pase después de ese alias TAMBIÉN se pasa en la línea de comando. Si prueba este conjunto -x; alias serve = "python -m SimpleHTTPServer $ 1 &" verá el error / problema. Tanto su argumento como el comando alias se ejecutan como comandos separados.
PatS
279

Solo para reiterar lo que se ha publicado para otros shells, en Bash los siguientes trabajos:

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

Ejecutando lo siguiente:

blah one two

Da el resultado a continuación:

First: one
Second: two
Thomas Bratt
fuente
44
Gran solución Algunas preguntas de un bash novato: ¿La función debe nombrarse con un guión bajo (o diferente) o es solo para facilitar la lectura? ¿Cuál es el propósito del "; _blah" al definir la función? ¿Por qué no funciona cuando se usan comillas dobles en lugar de comillas simples (el $ 1 no se interpreta correctamente) incluso cuando se hace algo que no requiere comillas alrededor del $ 1? Gracias de antemano por el consejo. Tengo una solución que funciona, pero siempre me gusta entender más sobre por qué funciona.
mynameispaulie
44
@mynameispaulie La función se puede nombrar de cualquier forma. He usado un prefijo de subrayado, ya que es un truco común para ayudar a prevenir las colisiones de nombres (es decir, otra función con el mismo nombre)
Thomas Bratt
66
@mynameispaulie Las comillas dobles permiten Bashreemplazar $1y $2con los parámetros pasados ​​a la función. Las comillas simples le dicen a Bash que no haga esto.
Thomas Bratt
55
Veo que este alias / función combo copió / pegó mucho, pero no parece tener ningún propósito útil. El enfoque estándar sería definir la función una vez, con un nombre sensato, y no tener un alias.
tripleee
16
No veo cómo se prefiere estofunction blah(){ echo "First: $1"; echo "Second: $2"; }
René Nyffenegger
57

No puedes en ksh, pero puedes en csh.

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

En ksh, la función es el camino a seguir. Pero si realmente realmente quisieras usar un alias:

alias mkcd='_(){ mkdir $1; cd $1; }; _'
Sanjaya R
fuente
Como nota al margen interesante, creo que la vulnerabilidad de ejecución remota de código de la que todos han estado hablando recientemente implica hacer casi exactamente lo mismo, pero en una variable de entorno establecida por la entrada sin procesar del usuario. openwall.com/lists/oss-security/2014/09/24/11
Floegipoky
@Floegipoky: debido a que está en un alias y no en una variable ambiental, es sustancialmente diferente. El problema de ShellShock es que se ejecuta cuando se establece la variable env. Se supone que configurar un entorno var es una operación segura. Ningún script se ejecuta cuando se establece el alias anterior, solo cuando se ejecuta el alias.
Sanjaya R
Quizás debería señalarse que cshgeneralmente no es lo que una persona moderna debería querer usar. La indirección alias-que-crea-una-función-luego-ejecuta-esa-función es relativamente popular, pero por lo que puedo decir, no ofrece ningún beneficio sobre una función adecuada. (La función debería citar correctamente su argumento, de todos modos). Votación a favor.
tripleee
17

Para citar la página de manual de bash:

No hay ningún mecanismo para usar argumentos en el texto de reemplazo. Si se necesitan argumentos, se debe utilizar una función de shell (ver FUNCIONES a continuación).

Parece que has respondido tu propia pregunta: usa una función en lugar de un alias

Chris Dodd
fuente
12

También puede encontrar útil este comando:

mkdir dirname && cd $_

donde dirname es el nombre del directorio que desea crear

tdecs
fuente
1
@StarDust $_es la salida del último comando unix.stackexchange.com/a/271693/169772
Taylor Edmiston
5

Descubrí que las funciones no se pueden escribir en ~/.cshrc archivo. Aquí en alias que toma argumentos

por ejemplo, argumentos pasados ​​al comando 'buscar'

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

donde abc es el argumento pasado como!: 1

kumar palaniappan
fuente
44
Eso no es útil para el OP, cuyo shell predeterminado es bash. Y la respuesta de Sanjaya R mencionó alias csh hace 4 años.
Keith Thompson
1
La respuesta de Sanjaya R no explicó lo que !:1significaba. Tuve que desplazarme hacia abajo para ver aquí que era el argumento. Una buena respuesta no deja más preguntas, incluso si no fuera por el tipo de shell OP.
searchengine27
4

La forma más fácil es usar la función, no el alias. aún puede llamar a una función en cualquier momento desde el cli. En bash, solo puede agregar el nombre de la función () {comando} se carga igual que un alias.

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

No estoy seguro acerca de otras conchas

Luke Attard
fuente
1

Esto funciona en ksh:

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

La opción "-x" hace que el alias sea "exportado": el alias es visible en subcapas.

Y tenga en cuenta que los alias definidos en un script no son visibles en ese script (porque los alias se expanden cuando se carga un script, no cuando se interpreta una línea). Esto se puede resolver ejecutando otro archivo de secuencia de comandos en el mismo shell (usando punto).


fuente
-2

Aquí hay una función de ejemplo simple usando python. Puede pegarse en ~ / .bashrc
Debe tener un espacio después del primer corchete izquierdo
El comando python debe estar entre comillas dobles para obtener la sustitución de variables
No olvide ese punto y coma al final

función count () {python -c "para num en xrange ($ 1): print num";}

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

Un alias vacío ejecutará sus argumentos:

alias DEBUG=
Peter Sharp
fuente
12
Veo por su representante que usted es nuevo en SO (desbordamiento de pila). No se desanime al rechazar su respuesta. Se ha rechazado porque realmente no responde a la pregunta que el OP (Cartel original) pidió que respondiera. Cuelgue en su y siga intentándolo. También al responder, intente incluir un ejemplo simple de cómo funciona su respuesta y muestre el resultado. Esto ayudará a otros a ver cómo funciona su respuesta.
PatS