2009-02-04 11 views
51

estoy tratando de ejecutar el siguiente comando:xargs no reconoce los alias de bash

find . -iname '.#*' -print0 | xargs -0 -L 1 foobar 

donde "foobar" es un alias o función definida en mi archivo .bashrc (en mi caso, es una función eso toma un parámetro). Aparentemente, xargs no los reconoce como cosas que puede ejecutar. ¿Hay alguna forma inteligente de remediar esto?

+1

Esta es una de las razones por las que crear secuencias de comandos en mi carpeta ~/bin en lugar de creando alias de bash. De esta forma, puedo usar mis alias desde cualquier shell: BASH, ZSH, IPYTHON o FISH. – Yoo

+2

Aquí hay una pregunta similar (aunque no idéntica): http: // stackoverflow.com/questions/979453/how-can-i-use-aliased-commands-with-xargs –

Respuesta

34

Desde solo su caparazón interactivo sabe sobre alias, ¿por qué no ejecuta el alias sin sobrescribirlo a través del xargs?

find . -iname '.#*' -print0 | while read -r -d '' i; do foobar "$i"; done 

Si está seguro de que sus nombres de archivo no tienen nuevas líneas en ellas (ick, ¿por qué no?), Puede simplificar esto a

find . -iname '.#*' -print | while read -r i; do foobar "$i"; done 

o incluso sólo find -iname '.#*' | ..., ya que la el directorio predeterminado es . y la acción predeterminada es -print.

una alternativa más:

IFS=$'\n'; for i in `find -iname '.#*'`; do foobar "$i"; done 

Bash diciendo que las palabras son solamente dividida en saltos de línea (por defecto: IFS=$' \t\n'). Sin embargo, debes tener cuidado con esto; algunos scripts no soportan bien un $IFS modificado.

+1

Esta respuesta está respondiendo POR QUÉ no podemos usar xargs y CÓMO podríamos usar xargs con el alias. –

+0

Esta respuesta nos da * alternativas * para usar xargs. Para obtener una respuesta que funcione * utilizando xargs *, consulte la respuesta de @ camh en la pregunta relacionada: http://stackoverflow.com/questions/979453/how-can-i-use-aliased-commands-with-xargs (que Nathan Fellman vinculado a arriba arriba) –

1

que suelen utilizar encontrar de esta manera:

find . -iname '' -exec cmd '{}' \; 

'{}' que se reemplazarán con el nombre de archivo y \; es necesario para terminar la cadena de ejecución. Sin embargo, si eso no funciona con su función, puede que tenga que ejecutar a través de bash:

find .. |sed -e "s/.*/cmd '&'/"|bash 

encontrar las impresiones cada archivo en una línea, simplemente sed prefijos esto con su comando y tubería que para golpear para la ejecución. Omita el | bash primero para ver qué pasará.

+0

Si está utilizando un find GNU nuevo, use '-exec cmd '{}' +' en su lugar: esto actúa más como xargs ya que agrupará argumentos en una sola ejecución en lugar de ejecutar un nuevo cmd por cada archivo encontrado. – ephemient

+0

Prefiero pensar que si su función fuera capaz de tomar múltiples parámetros, no estaría suministrando las opciones -L 1 para xargs ... – Alnitak

+0

Oh, eso es lo que -L? No lo busqué, y uso -n para ese propósito. – ephemient

4

Esto no funciona porque xargs espera ser capaz de exec el programa dada como parámetro.

Dado que foobar en su caso es solo un alias o función bash, no hay programa para ejecutar.

Aunque se trata de iniciar bash para cada archivo devuelto por find, se podría escribir un pequeño script de shell así:

#!/bin/bash 
. $(HOME)/.bashrc 
func $* 

y luego pasar el nombre de esa secuencia de comandos como el parámetro a xargs

+0

¿Dónde debería colocar esa secuencia de comandos para que * it * sea reconocido por 'xargs'? –

+0

@NickVolynkin donde quieras, siempre y cuando esté en '$ PATH' o dale su ubicación directamente a' xargs'. – Alnitak

+0

bien, gracias por la explicación. –

8

Usando Bash también puede especificar el número de argumentos que se pasa a su alias (o función) de esta manera:

alias myFuncOrAlias='echo' # alias defined in your ~/.bashrc, ~/.profile, ... 
echo arg1 arg2 | xargs -n 1 bash -cil 'myFuncOrAlias "$1"' arg0 
echo arg1 arg2 | xargs bash -cil 'myFuncOrAlias "[email protected]"' arg0