このsvnスクリプトはどのように機能しますか?

このsvnスクリプトはどのように機能しますか?

svn単一のコマンドを使用して複数の項目を更新するために、このbash関数を定義しました。

svn_update_all () 
{ 
    repos=`find . -name '.svn'`;
    for i in "$repos";
    do
        svn update `dirname $i`;
        echo;
    done
}

それが提供する出力は次のとおりです。

Updating 'project1':
At revision 26713.
Updating 'project2':
At revision 26723.
Summary of updates:
  Updated 'project1' to r26713.
  Updated 'project2' to r26723.

出力がSummary of updates少し混乱しています。各行はプログラムへの別々の呼び出しで印刷されます。統合された概要をどのように取得できますか?

ベストアンサー1

短い答え:これは別の呼び出しではなく、svn update一度だけ実行されます。

(以下の関数を実行してこれをテストできますset -x。これにより、bashが実行されると各コマンドが印刷されますset -x; svn_update_all; set +x。)

何度も何度も実行したいと思ったらsvn(そしてそうなると確信しています。)いいえパスにスペースがあります。引用符を入れるだけです$repos

svn_update_all ()
{ 
    repos=`find . -name '.svn'`
    for i in $repos
    do
        svn update `dirname $i`
        echo
    done
}

これがサイクルの処理ですforbash(1)説明する:

~のため 名前[[[存在する[言葉 ...]]];する リスト;完璧

次の単語リスト存在する展開され、アイテムのリストが生成されます。変わりやすい名前リストの各要素に順番に設定されます。リスト毎回実行されます。

したがって、ブロックの内容はforそれぞれ1回ずつ実行される。言葉後ろにin。例は次のとおりです。

count=0
for num in one two three; do
do
    let count++
    echo "loop $count: '$num'"
done
ループ1:「1つ」
ループ2:「2」
ループ3:「3」

しかし、引用符付き文字列考慮一言。これは基本的にスクリプトで発生することです。

count=0
for num in "one two three"; do
    let count++
    echo "loop $count: '$num'"
done
ループ1:「1、2、3」

引用符を削除し、別$reposの単語に再分割し、期待どおりにsvn update各リポジトリに対して一度実行します。

しかし、注意してください:スペースを含むパスがあると壊れます。

これ最も単純なパスを処理する方法可能出力を組み込みコマンドfindにパイプするスペースがあります。read

find . -name '.svn' | while read i
do
    svn update `dirname $i`
    echo
done

これ最も安全なfindこれを行う方法は、-execまたはタスクを使用してファイル名の分割を-execdir心配する必要がないようにすることです。bash

# print the repo dir, then run "svn update" in it
find . -name '.svn' -printf '%h: ' -execdir svn update \;
./mpc: "."アップデート:
Uトランク/src/pow.c
Uトランク/テスト/pow.dat
Uトランク/m4/mpc.m4
リビジョン1455に更新されました。
./mpfr: "."アップデート:
[等]

おすすめ記事