Pregunta ¿Por qué funciona "source <(cmd)" pero no "$ (cmd)"?


Quiero tener un script para llamar con params que agrega algunos alias a mi shell actual. Los alias deben construirse con respecto a los parámetros de llamada y el directorio actual desde donde lo inicio. Si es posible, me gustaría NO tener que buscar el script, simplemente ejecutarlo como cualquier otro script.

Esto es lo que he hecho hasta ahora:

Escribí un pequeño script de shell para generar algunos alias, como

echo 'alias foo="$1"'

y guárdalo como archivo "myscript" con + x derechos. Luego lo ejecuto a través de la consola para configurar el alias

$(myscipt hello)

eso funciona bien

Cuando cambio mi script de shell como

echo 'alias foo="bar $1 -param"'

y ejecutar de nuevo como arriba, el resultado es

bash: alias hello" not found
bash: alias -param" not found

??? Ya he escapado los espacios en blanco entre barra y -param pero no puedo hacer que funcione.

cuando ejecuto

source <(myscript hello)

todo está bien, como se esperaba (esa es mi solución por ahora, pero no estoy seguro de si es la mejor).

Algunas ideas de cómo obtener una mejor solución?


1


origen


La respuesta a su pregunta aquí es que source requiere un archivo, que es lo que obtienes con la sustitución del proceso <(), pero no con la sustitución de comando $(). Sin embargo, su pregunta es un buen ejemplo de un problema XY; por lo general, es mejor preguntar qué es lo que está tratando de lograr en lugar de intentar su solución. - slhck
@slhck - Actualicé mi pregunta - Quizás tengas una mejor idea para mi problema XY. Por cierto. cuando se usa la sustitución de comando $()NO fuente el resultado. $() inyectará el alias si NO hay espacio en el comando de aliasing. La pregunta a continuación es: ¿Qué debo hacer si quiero usar $() y espacios para separar argumentos? Lo que sea, quizás tengas una buena pista para mí. Gracias. - Tom Freudenberg
Afortunadamente mi respuesta acerta, pero en caso de que no lo haga: ¿Por qué source <(myscript hello) opción no es de tu agrado? - lindes-hw


Respuestas:


Estás usando el source comando incorrecto Supongo que tiene un archivo llamado myscript que contiene estos comandos. En lugar de tener cosas para generar los comandos correctos en el archivo, como este

echo 'alias foo="bar -param"'

solo deberías tener los comandos, como este

alias foo="bar -param"

Luego pasas tu script directamente a source comando, que lo ejecuta en el shell actual para que los cambios realizados en el script se reflejen en su sesión de shell actual:

source myscript

También el . comando es equivalente:

. myscript

(Tenga en cuenta que hay un espacio entre . y myscript.)


Actualizar

En respuesta a su comentario: aún debe usar un archivo. Como el nombre de un alias se puede establecer utilizando un valor de variable, puede agregar la lógica en el archivo para hacer todos los alias dinámicos. Aquí hay un ejemplo super simple:

$ foo=hello
$ alias $foo='echo hi'
$ hello
hi

Puede usar condiciones, bucles, etc. para crear una lógica mucho más compleja para sus alias dinámicos.


5



Gracias, sé tu respuesta, pero esto no es lo que estoy buscando. Eche un vistazo a mi comentario anterior, en resumen: no hay un alias estático y no quiero crear un archivo. - Tom Freudenberg
@TomFreudenberg - Sigo pensando que la manera correcta de hacerlo es usando un archivo estático con el source mando. Ver mi edición arriba para más detalles. - DaoWen
Gracias de nuevo. Pero usando un archivo necesito ingresar siempre 2 comandos en el shell. Primero: script para generar el archivo temporal de alias, Segundo: archivo temporal de origen. En caso de que esté escribiendo herramientas para un framework, no es una buena solución para mí. - Tom Freudenberg
Actualicé la pregunta para ser más preciso de lo que estoy buscando. Gracias por sus sugerencias y ayuda. - Tom Freudenberg
@TomFreudenberg - Todavía pareces confundido acerca de lo que estoy sugiriendo. No deberías necesitar dos scripts. Cualquier "parámetro" que tenga probablemente pueda pasar a través de variables de entorno. Toda la lógica pwd debe manejarse dentro de estático guión. - DaoWen


set -x resulta ser informativo:

: $; set -x
: $; $(./alias-builder)
++ ./alias-builder
+ alias 'foo="bar' '$1' '-param"'
bash: alias: $1: not found
bash: alias: -param": not found
: $; 

Entonces, lo que está sucediendo aquí es que cuando bash trata la producción de alias-builder (que es el nombre que le di a un script que contiene tu comando echo) como algo para sustituir en línea como argumentos, está separando el resultado de las palabras, como podría suceder normalmente, pero tratando las citas como parte de las palabras, en lugar de lo que haces Re expecting, que es analizar el resultado como lo haría si se escribiera.

Creo que finalmente tu respuesta es usar el source opción.

Ahora, si no es conveniente escribir, podría hacer algo como esto:

metamyscript() {
    source <(myscript "$@")
}

Y entonces deberías poder hacer, simplemente:

: $; metamyscript hello

y correrá myscript helloy obtener el resultado de eso.

(Por supuesto, podría cambiar los nombres a su gusto.)


0