xargs non riconosce alias bash
-
21-08-2019 - |
Domanda
Sto cercando di eseguire il seguente comando:
find . -iname '.#*' -print0 | xargs -0 -L 1 foobar
dove "foobar" è un alias o una funzione definita nel mio file .bashrc (nel mio caso, si tratta di una funzione che prende un parametro). xargs A quanto pare non riconosce questi come le cose si può correre. C'è un modo intelligente per rimediare a questo?
Soluzione
Dal momento che solo la vostra shell interattiva conosce alias, perché non basta eseguire l'alias, senza sborsare attraverso xargs
?
find . -iname '.#*' -print0 | while read -r -d '' i; do foobar "$i"; done
Se sei sicuro che i nomi dei file non hanno a capo in loro (ahia, perché avrebbero dovuto?), È possibile semplificare questo per
find . -iname '.#*' -print | while read -r i; do foobar "$i"; done
o anche solo find -iname '.#*' | ...
, dal momento che la directory predefinita è .
e l'azione di default è -print
.
Ancora un'alternativa:
IFS=$'\n'; for i in `find -iname '.#*'`; do foobar "$i"; done
dicendo Bash che le parole sono solo per parti separate su nuove righe (default: IFS=$' \t\n'
). Si dovrebbe fare attenzione a questo, però; alcuni script non affrontare bene con una cambiata $IFS
.
Altri suggerimenti
Utilizzando Bash si può anche specificare il numero di argomenti di essere passato al tuo alias (o funzione) in questo modo:
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 "$@"' arg0
Questo non funziona perché xargs
si aspetta di essere in grado di exec
il dato come parametro.
Dal foobar
nel tuo caso è solo un alias bash
o una funzione non c'è nessun programma da eseguire.
Anche se si tratta di iniziare find
per ogni file restituito da <=>, si potrebbe scrivere un piccolo script di shell in tal modo:
#!/bin/bash
. $(HOME)/.bashrc
func $*
e quindi passare il nome di questo script come parametro a <=>
Io di solito uso trovare in questo modo:
find . -iname '' -exec cmd '{}' \;
'{}' andranno sostituiti con il nome del file, e \; è necessario per terminare la catena di esecuzione. Tuttavia, se questo non funziona con la vostra funzione, potrebbe essere necessario eseguire attraverso bash:
find .. |sed -e "s/.*/cmd '&'/"|bash
Trova stampe ogni file su una linea, sed solo prefissi questo con il vostro comando e quindi il tubo è di bash per l'esecuzione. Saltare la |. Bash primi a vedere cosa accadrà
try
find . -iname '.#*' -print0 | xargs -0 -L 1 $(foobar)