Solía usar CShell (csh), que le permite crear un alias que toma un parámetro. La notación era algo así como
alias junk="mv \\!* ~/.Trash"
En Bash, esto no parece funcionar. Dado que Bash tiene una multitud de características útiles, supongo que esta se ha implementado, pero me pregunto cómo.
"$1"
ls
als -la
, a continuación, escribiendols foo bar
sería realmente ejecutarls -la foo bar
en la línea de comandos."alias test_args="echo PREFIX --$1-- SUFFIX"
, que cuando se llama contest_args ABCD
produce la siguiente salida de la consolaPREFIX ---- SUFFIX ABCD
Respuestas:
El alias bash no acepta parámetros directamente. Tendrás que crear una función.
alias
no acepta parámetros, pero una función se puede llamar como un alias. Por ejemplo:Por cierto, las funciones de Bash definidas en usted
.bashrc
y otros archivos están disponibles como comandos dentro de su shell. Entonces, por ejemplo, puede llamar a la función anterior de esta manerafuente
$1
entre comillas?source
ing .bashrc agregará la función, pero no eliminará el alias anterior. Como los alias tienen un precedente más alto que las funciones, intentará usar el alias. Debe cerrar y volver a abrir su shell, o bien llamarunalias <name>
. Quizás ahorre a alguien los 5 minutos que acabo de perder.exec bash
: Comenzará un nuevo shell, que le dará una lectura limpia de sus configuraciones, como si cerrara y volviera a abrir, pero manteniendo la configuración variable de entorno de esa sesión también . Además, la ejecuciónbash
sin el exec puede ser útil cuando desea manejar piensa como una pila.mv "$1" "$1.bak"
. sin comillas, si $ 1 fuera "hola mundo", ejecutarías enmv hello world hello world.bak
lugar demv "hello world" "hello world.bak"
.Refinando la respuesta anterior, puede obtener una sintaxis de 1 línea como puede para los alias, que es más conveniente para las definiciones ad-hoc en un shell o archivos .bashrc:
No olvide el punto y coma antes del cierre del corchete derecho. Del mismo modo, para la pregunta real:
O:
fuente
mv "$1" "$1.bak"; cp "$2" "$1"
amv "$1" "$1.bak" && cp "$2" "$1"
para no perder sus datos cuando tengamv
problemas (por ejemplo, sistema de archivos lleno).La pregunta simplemente se hace mal. No crea un alias que tome parámetros porque
alias
solo agrega un segundo nombre para algo que ya existe. La funcionalidad que el OP quiere es elfunction
comando para crear una nueva función. No necesita alias de la función ya que la función ya tiene un nombre.Creo que quieres algo como esto:
¡Eso es! Puede usar los parámetros $ 1, $ 2, $ 3, etc., o simplemente rellenarlos todos con $ @
fuente
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 admitir nombres de archivos con espacios, etc.TL; DR: haga esto en su lugar
Es mucho más fácil y más legible usar una función que un alias para colocar argumentos en el medio de un comando.
Si sigue leyendo, aprenderá cosas que no necesita saber sobre el procesamiento de argumentos de shell. El conocimiento es peligroso. Solo obtén el resultado que deseas, antes de que el lado oscuro controle para siempre tu destino.
Aclaración
bash
alias hacen aceptar los argumentos, pero sólo al final :Poner argumentos en el medio del comando a través de sí
alias
es posible, pero se pone feo.¡No intenten esto en casa, niños!
Si te gusta eludir las limitaciones y hacer lo que otros dicen es imposible, aquí está la receta. Simplemente no me culpes si tu cabello se agota y tu cara termina cubierta de hollín al estilo científico loco.
La solución consiste en pasar los argumentos que
alias
aceptan solo al final a un contenedor que los insertará en el medio y luego ejecutará su comando.Solución 1
Si realmente está en contra de usar una función per se, puede usar:
Puede reemplazar
$@
con$1
si solo desea el primer argumento.Explicacion 1
Esto crea una función temporal
f
, a la que se le pasan los argumentos (tenga en cuenta quef
se llama al final). Launset -f
quita la definición de función como el alias se ejecuta de manera que no cuelgue alrededor después.Solución 2
También puedes usar una subshell:
Explicacion 2
El alias construye un comando como:
Comentarios:
Se
_
requiere el marcador de posición , pero podría ser cualquier cosa. Se establece ensh
's$0
, y es necesario para que el primero de los argumentos proporcionados por el usuario no se consuma. Demostración:Se requieren comillas simples dentro de comillas simples. Aquí hay un ejemplo de que no funciona con comillas dobles:
Aquí los valores de los shell interactivos
$0
y$@
se reemplazan en el doble entrecomillado antes de pasarlo ash
. Aquí hay prueba:Las comillas simples aseguran que estas variables no sean interpretadas por el shell interactivo y se pasen literalmente a
sh -c
.Puede usar comillas dobles y
\$@
, pero la mejor práctica es citar sus argumentos (ya que pueden contener espacios), y se\"\$@\"
ve aún más feo, pero puede ayudarlo a ganar un concurso de ofuscación donde el cabello agitado es un requisito previo para la entrada.fuente
alias gc='git checkout'
$@
? Son necesarios si tiene, por ejemplo, archivos con espacios en ellos.Una solución alternativa es usar el marcador , una herramienta que he creado recientemente que le permite "marcar" plantillas de comando y colocar fácilmente el cursor en los marcadores de posición de comando:
Descubrí que la mayoría de las veces, estoy usando funciones de shell, así que no tengo que escribir comandos usados con frecuencia una y otra vez en la línea de comandos. El problema del uso de funciones para este caso de uso es agregar nuevos términos a mi vocabulario de comandos y tener que recordar a qué parámetros de funciones se refieren en el comando real. El objetivo del marcador es eliminar esa carga mental.
fuente
Todo lo que tienes que hacer es hacer una función dentro de un alias:
Usted debe poner comillas dobles "$ 1" porque comillas simples no funcionarán.
fuente
bash: syntax error near unexpected token '{mkdir'
.;
dentro de la función,_mkcd
probablemente el error es de eso.{
y}
Aquí hay tres ejemplos de funciones que tengo en mi
~/.bashrc
, que son esencialmente alias que aceptan un parámetro:.
.
.
Referencias
fuente
Bash alias absolutamente acepta parámetros. Acabo de agregar un alias para crear una nueva aplicación de reacción que acepta el nombre de la aplicación como parámetro. Aquí está mi proceso:
Abra el bash_profile para editar en nano
Agregue sus alias, uno por línea:
Guardar y salir del editor nano
Dígale a la terminal que use los nuevos alias en .bash_profile
¡Eso es! Ahora puedes usar tus nuevos alias
fuente
NB: en caso de que la idea no sea obvia, es una mala idea usar alias para cualquier cosa que no sea alias, siendo la primera la 'función en un alias' y la segunda la 'redirección / fuente difícil de leer'. Además, hay fallas (que pensé que serían obvias, pero en caso de que estés confundido: no quiero decir que realmente se usen ... ¡en cualquier lugar!)
.................................................. .................................................. ............................................
He respondido esto antes, y siempre ha sido así en el pasado:
lo cual está bien y es bueno, a menos que esté evitando el uso de funciones todas juntas. en cuyo caso puede aprovechar la gran capacidad de bash para redirigir texto:
Ambos tienen aproximadamente la misma longitud, dan o toman algunos caracteres.
La verdadera patada es la diferencia horaria, la parte superior es el 'método de función' y la inferior es el método 'fuente de redireccionamiento'. Para probar esta teoría, el momento habla por sí mismo:
Esta es la parte inferior de unos 200 resultados, realizada a intervalos aleatorios. Parece que la creación / destrucción de funciones lleva más tiempo que la redirección. Espero que esto ayude a los futuros visitantes a esta pregunta (no quería que me la guardara).
fuente
time for i in {1..1000}; do foo FOOVALUE; done
→ 0m0.028s. Perotime for i in {1..1000}; do bar FOOVALUE; done
→ 0m2.739s. Bar es dos órdenes de magnitud más lento que foo. El simple uso de una función simple en lugar de un alias reduce el tiempo de ejecución en otro 30%:function boo() { echo "arg1 for boo=$1" ; }
⇒time for i in {1..1000}; do boo FOOVALUE; done
→ 0m0.019s.Si está buscando una forma genérica de aplicar todos los parámetros a una función, no solo una o dos u otra cantidad codificada, puede hacerlo de esta manera:
Entonces, en el ejemplo anterior, paso todos los parámetros desde cuando ejecuto
runjar
el alias.Por ejemplo, si lo hiciera
runjar hi there
, terminaría realmente ejecutándosejava -jar myjar.jar hi there
. Si lo hicierarunjar one two three
, correríajava -jar myjar.jar one two three
.Me gusta esta
$@
solución basada porque funciona con cualquier número de parámetros.fuente
runjar
lugar de convertirla en un alias de una función? Parece innecesariamente complicado!alias
(o se pasan las propiedades de las cosasalias
) en los archivos bash? en caso afirmativo, es solo que no lo he sabidoalias runjar='java -jar myjar.jar'
. Los alias aceptan argumentos, pero solo al final.Respetuosamente a todos aquellos que dicen que no se puede insertar un parámetro en el medio de un alias. Lo probé y descubrí que funcionaba.
alias mycommand = "python3" $ 1 "script.py --folderoutput RESULTADOS /"
cuando ejecuté mi comando foobar, funcionó exactamente como si hubiera escrito el comando a mano.
fuente
alias myalias="echo 1 "$1" 3"; myalias 2
da:1 3 2
Existen razones técnicas legítimas para querer una solución generalizada al problema de bash alias que no tiene un mecanismo para tomar una posición de argumentos arbitrarios. Una razón es si el comando que desea ejecutar se vería afectado negativamente por los cambios en el entorno que resultan de ejecutar una función. En todos los demás casos, se deben utilizar funciones.
Lo que recientemente me obligó a intentar una solución a esto es que quería crear algunos comandos abreviados para imprimir las definiciones de variables y funciones. Entonces escribí algunas funciones para ese propósito. Sin embargo, hay ciertas variables que son (o pueden ser) cambiadas por una función llamada en sí. Entre ellos están:
FUNCNAME BASH_SOURCE BASH_LINENO BASH_ARGC BASH_ARGV
El comando básico que había estado usando (en una función) para imprimir definiciones variables. en el formulario de salida por el comando set fue:
P.ej:
Problema: Esto no imprimirá las definiciones de las variables mencionadas anteriormente, ya que están en el contexto actual , por ejemplo, si en un intérprete de comandos interactivo (o no en ninguna llamada de función), FUNCNAME no está definido. Pero mi función me dice la información incorrecta:
Una solución que se me ocurrió ha sido mencionada por otros en otras publicaciones sobre este tema. Para este comando específico para imprimir defns variables, y que requiere solo un argumento, hice esto:
Lo que da el resultado correcto (ninguno) y el estado del resultado (falso):
Sin embargo, todavía me sentí obligado a encontrar una solución que funcione para números arbitrarios de argumentos.
Una solución general para pasar argumentos arbitrarios a un comando con alias bash:
P.ej:
Lo bueno de esta solución es que todos los trucos especiales utilizados para manejar los parámetros posicionales (argumentos) de los comandos funcionarán al componer el comando atrapado. La única diferencia es que se debe usar la sintaxis de matriz.
P.ej,
Si desea "$ @", use "$ {CMD_ARGV [@]}".
Si desea "$ #", use "$ {# CMD_ARGV [@]}".
Etc.
fuente
Una vez hice un proyecto divertido y todavía lo uso. Muestra algo de animación mientras copio archivos a través del
cp
comandocp
porque no muestra nada y es un poco frustrante. Entonces hice este aliasY esta es la secuencia de comandos spiner
Se parece a esto
Animación cíclica)
fuente
¡Para tomar parámetros, debe usar funciones!
Sin embargo, $ @ se interpreta al crear el alias en lugar de durante la ejecución del alias y escapar de $ tampoco funciona. ¿Cómo resuelvo este problema?
Debe utilizar la función de shell en lugar de un alias para deshacerse de este problema. Puede definir foo de la siguiente manera:
O
Finalmente, llame a su foo () usando la siguiente sintaxis:
Asegúrate de agregar tu foo () a
~/.bash_profile
o~/.zshrc
archivo.En tu caso, esto funcionará
fuente
De hecho, las funciones son casi siempre la respuesta, ya que esta cita de la página del manual ya ha contribuido y confirmado ampliamente: "Para casi todos los propósitos, los alias son reemplazados por las funciones de shell".
Para completar y porque esto puede ser útil (sintaxis marginalmente más liviana), podría notarse que cuando los parámetros siguen el alias, todavía se pueden usar (aunque esto no abordaría el requisito del OP). Esto es probablemente más fácil de demostrar con un ejemplo:
me permite escribir algo como
ssh_disc myhost
, que se expande como se esperaba como:ssh -O stop myhost
Esto puede ser útil para comandos que toman argumentos complejos (mi memoria ya no es lo que solía ser ...)
fuente
Tanto las funciones como los alias pueden usar parámetros como otros han mostrado aquí. Además, me gustaría señalar un par de otros aspectos:
1. la función se ejecuta en su propio alcance, el alias comparte el alcance
Puede ser útil saber esta diferencia en los casos en que necesite ocultar o exponer algo. También sugiere que una función es la mejor opción para la encapsulación.
Salida:
2. script de envoltura es una mejor opción
Me ha sucedido varias veces que no se puede encontrar un alias o una función al iniciar sesión a través de
ssh
o al cambiar nombres de usuario o entornos multiusuario. Hay consejos y trucos con el abastecimiento de archivos de puntos, o este interesante con alias:alias sd='sudo '
permite que este alias posterioralias install='sd apt-get install'
funcione como se espera (observe el espacio adicional ensd='sudo '
). Sin embargo, un script de contenedor funciona mejor que una función o alias en casos como este. La principal ventaja de un script de envoltura es que es visible / ejecutable para la ruta prevista (es decir, / usr / loca / bin /) donde, como función / alias, debe obtenerse antes de que sea utilizable. Por ejemplo, coloca una función en un ~ / .bash_profile o ~ / .bashrc parabash
, pero luego cambia a otro shell (es decirzsh
) entonces la función ya no es visible. Por lo tanto, cuando tenga dudas, un script de contenedor siempre es la solución más confiable y portátil.fuente
source
en una función funciona bien.f () { source /tmp/nst; }
hace exactamente lo que espero. Tal vez tuPATH
está mal, así que funciona malactivate
o algo así; pero corrersource
desde una función funciona bien.function
palabra clave en su definición, consulte wiki.bash-hackers.org/scripting/obsolete -function funcname {
es una antigua sintaxis ksh que bash admite para la compatibilidad con versiones anteriores de shells POSIX, mientras quefuncname() {
es una sintaxis estandarizada oficial POSIX.function funcname() {
es una mismah de las dos que no es compatible con ksh antiguo o compatible con POSIX sh, y que por lo tanto es mejor evitarlo.Aquí está el ejemplo:
Muy importante:
{
y antes}
.;
después de cada comando en secuencia. Si olvida esto después del último comando, verá un>
mensaje en su lugar."$1"
fuente
Como ya han señalado otros, el uso de una función debe considerarse la mejor práctica.
Sin embargo, aquí hay otro enfoque, aprovechando
xargs
:Tenga en cuenta que esto tiene efectos secundarios con respecto a la redirección de secuencias.
fuente
No tiene que hacer nada, alias lo hace automáticamente.
Por ejemplo, si quiero hacer que el origen de git pull sea parametrizado, simplemente puedo crear un alias de la siguiente manera:
y cuando realmente lo llama, puede pasar 'maestro' (el nombre de la sucursal) como un parámetro, como este:
fuente