Resposta curta: essas não são invocações separadas; você está executando apenas svn update uma vez.
(Você pode testar isso executando a função em set -x , que faz o bash imprimir todos os comandos durante a execução: set -x; svn_update_all; set +x )
Se você realmente quiser executar svn várias vezes (e tiver certeza de que nunca terá espaços em seus caminhos), basta soltar as aspas em torno de $repos :
svn_update_all ()
{
repos='find . -name '.svn''
for i in $repos
do
svn update 'dirname $i'
echo
done
}
Aqui está a transação com for loops. bash(1) diz:
for name [ [ in [ word ... ] ] ; ] do list ; done
The list of words following in is expanded, generating a list of items. The variable name is set to each element of this list in turn, and list is executed each time.
Portanto, o conteúdo do bloco for é executado uma vez para cada palavra após in . Aqui está um exemplo:
count=0
for num in one two three; do
do
let count++
echo "loop $count: '$num'"
done
loop 1: 'one' loop 2: 'two' loop 3: 'three'
Mas uma string entre aspas é considerada uma única palavra . Isso é basicamente o que está acontecendo no seu script:
count=0
for num in "one two three"; do
let count++
echo "loop $count: '$num'"
done
loop 1: 'one two three'
Remova as aspas e $repos será dividido em palavras separadas novamente e, em seguida, svn update será executado uma vez para cada repo, como esperado.
Note bem, no entanto: isso será quebrado se você tiver um caminho com espaços .
A maneira mais simples de manipular caminhos que podem ter espaços é canalizar a saída de find para o comando read builtin:
find . -name '.svn' | while read i
do
svn update 'dirname $i'
echo
done
A maneira mais segura é usar as ações find -exec ou -execdir , para que você não precise se preocupar com bash de divisão de nomes de arquivos:
# print the repo dir, then run "svn update" in it
find . -name '.svn' -printf '%h: ' -execdir svn update \;
./mpc: Updating '.': U trunk/src/pow.c U trunk/tests/pow.dat U trunk/m4/mpc.m4 Updated to revision 1455. ./mpfr: Updating '.': [etc]