0

これが問題になるとは思っていませんでした。coreutils がこれらのことをサポートしていると思ったので、cp ls と rm の汚い組み合わせで十分だと思ったからです。

しかし、そうではありませんでした。私のアプローチが失敗した理由と、さらに適切な方法でこれを行う方法を説明していただければ幸いです。

コード

function CheckoutFolder {
    local dir=$1


    mkdir "$dir/.CheckoutFolderTmp"
    (
        cd "$dir" \
        && cp -R $(ls -Q -A "$dir" --ignore=".CheckoutFolderTmp") "$dir/.CheckoutFolderTmp" \
        && rm -Rf  $(ls -Q -A "$dir" --ignore=".CheckoutFolderTmp")
    )
    mv "$dir/.CheckoutFolderTmp" "$dir/src"
    mkdir -p "$dir/"{build,log}
}

サンプル出力

++ CheckoutFolder /home/tobias/Develop/src/thelegacy/RCMeta
++ local dir=/home/tobias/Develop/src/thelegacy/RCMeta
++ mkdir /home/tobias/Develop/src/thelegacy/RCMeta/.CheckoutFolderTmp
++ cd /home/tobias/Develop/src/thelegacy/RCMeta
+++ ls -Q -A /home/tobias/Develop/src/thelegacy/RCMeta --ignore=.CheckoutFolderTmp
++ cp -R '"build"' '"buildmythli.sh"' '"CMakeLists.txt"' '".directory"' '".libbuildmythli.sh"' '"log"' '"RCMeta"' '"RCMetaTest"' '"src"' /home/tobias/Develop/src/thelegacy/RC
cp: cannot stat `"build"': No such file or directory
cp: cannot stat `"buildmythli.sh"': No such file or directory
cp: cannot stat `"CMakeLists.txt"': No such file or directory
cp: cannot stat `".directory"': No such file or directory
cp: cannot stat `".libbuildmythli.sh"': No such file or directory
cp: cannot stat `"log"': No such file or directory
cp: cannot stat `"RCMeta"': No such file or directory
cp: cannot stat `"RCMetaTest"': No such file or directory
cp: cannot stat `"src"': No such file or directory
++ mv /home/tobias/Develop/src/thelegacy/RCMeta/.CheckoutFolderTmp /home/tobias/Develop/src/thelegacy/RCMeta/src
++ mkdir -p /home/tobias/Develop/src/thelegacy/RCMeta/build /home/tobias/Develop/src/thelegacy/RCMeta/log
++ return 0

ミスリ

4

2 に答える 2

2

Les が言うように、ls -Qはファイル名を引用符で囲んでおり、それらの引用符は と の引数に渡されcpますrm。(引数を引用して区切るための引用符の使用は、実際にコマンドを入力するときの Bash コマンドラインの側面です。あるコマンドの出力を別のコマンドに渡すときは機能しません。)一般的に、 の出力を解析することlsは一般的には良い考えではありません。

別のアプローチを次に示します。

function CheckoutFolder() (
    cd "$1"

    mkdir .CheckoutFolderTmp

    find -mindepth 1 -maxdepth 1 -not -name .CheckoutFolderTmp \
         -exec mv {} .CheckoutFolderTmp/{} \;

    mv .CheckoutFolderTmp src

    mkdir build log
)

(関数本体を中括弧(...)ではなく括弧で囲んだことに注意してください{...}。これにより、関数全体がサブシェルで実行されます。)

于 2012-09-12T17:52:29.440 に答える
1

$(ls ...) コマンドは、名前を不要な引用符で囲んでいます。代わりに xargs と逆引用符を使用することを検討してください。例えば...

(cd "$dir" && cp -R `ls -Q -A "$dir" --ignore=".CheckoutFolderTmp"` "$dir/.CheckoutFolderTmp" && ls -Q -A "$dir" --ignore=".CheckoutFolderTmp" | xargs rm -Rf  )

cp の出力はあまりわかりやすいものではありませんが、必要な情報は得られます。

cp:  cannot stat '"build"': No such file or directory

最後のステートメント「そのようなファイルまたはディレクトリはありません」にスキップします。「cannot stat」という謎めいた言葉ですが、「cp」が「stat」を使用して、コピーしようとしていたファイルまたはディレクトリに関する情報を取得したことを意味します。「統計」に失敗しました。'"build"' という名前のファイル (またはディレクトリ) で、"no such file or directory" の errno で失敗しました。これは、cp の内部の実際の引数が "build" (引用符に注意) であるのに対し、必要なファイル名は build (引用符がないことに注意) であるためです。

$(ls... ) は -Q で呼び出され、引用符を付けます (おそらく、スペースやコンマ、その他の問題のある文字を含むファイル名を処理するため)。しかし、 $(ls...) はすでに引用符を付けています。-0 を使用すると、xargs はファンキーなファイル名も処理できます。

于 2012-09-12T17:33:23.163 に答える