私が使うとき
cp -R inputFolder outputFolder
結果はcontext-dependentです。
outputFolder
が存在しない場合は作成され、クローンされたフォルダーのパスはoutputFolder
になります。outputFolder
が存在する場合、作成されるクローンはoutputFolder/inputFolder
になりますこれは恐ろしいです。これは、インストールスクリプトを作成したいためです。ユーザーが誤ってそれを2回実行すると、outputFolder
になります。最初に作成され、次に2回目の実行で、すべてのものはoutputFolder/inputFolder
にもう一度作成されます。
cp
を使用してポータブルにしたい(たとえば、MINGWにはrsync
が付属していない)cp -R --parents
をチェックしましたが、これによりディレクトリツリーまでのパスが再作成されます(したがって、クローンはoutputFolder
ではなくsome/path/outputFolder
になります)--remove-destination
または--update
(ケース2で何も変更されない場合、outputFolder/inputFolder
にコピーされます)最初にoutputFolder
の存在を確認することなく(フォルダーが存在しない場合...)、またはrm -rf outputFolder
を使用せずにこれを行う方法はありますか?
合意された移植可能なUNIXの方法は何ですか?
代わりにこれを使用してください:
cp -R inputFolder/. outputFolder
これは、たとえばcp -R aaa/bbb ccc
と同じように機能します。ccc
が存在しない場合は、bbb
とその内容のコピーとして作成されます。ただし、ccc
がすでに存在する場合は、bbb
とその内容のコピーとしてccc/bbb
が作成されます。
bbb
のほとんどすべてのインスタンスで、これは質問で指摘した望ましくない動作を示します。ただし、この特定の状況では、bbb
は.
なので、aaa/bbb
は実際にはaaa/.
であり、これは実際にはaaa
だけですが、別の名前。したがって、次の2つのシナリオがあります。
ccc
は存在しません:
コマンドcp -R aaa/. ccc
は、「ccc
を作成してaaa/.
の内容をccc/.
にコピーします。つまり、aaa
をccc
にコピーします。
ccc
は存在します:
コマンドcp -R aaa/. ccc
は、「aaa/.
の内容をccc/.
にコピーします。つまり、aaa
をccc
にコピーします。
フォルダーをコピーせず、内容のみをコピーします。
## Create the target directory. The -p suppresses error messages
## if the directory already exists
mkdir -p outputFolder
## Copy the contents recursively, this will not recreate the parent
cp -R inputfolder/* outputfolder/
このようにして、スクリプトが最初に実行されるときにターゲットディレクトリが作成されることを確認し、スクリプトを2回目に実行するときに問題を回避します。
Chris Downは、bashでは名前が.
で始まるファイルをスキップすることを非常に正確に指摘しています。これを回避するには、上記のコマンドを実行する前にshopt -s dotglob
を実行します。
-p
for mkdir
と -R
for cp
の両方がPOSIXで定義されているため、完全に移植可能である必要があります。
cp
に-T
オプションを試してください。これはGNU coreutils cp
バージョン8.22に存在します;それ以外では移植できないかもしれません。
rsync
を使用することもできます:
rsync -uav inputFolder/ outputFolder/
(特に最初のスラッシュの後のスラッシュに注意してください)
私の意見では、rm -rf outputFolder
よりも単純で移植性の高いものはありません。だから、私はいつもそれにこだわる。あなたの質問は違うと思いますが、これがベストプラクティスだと思います。
cp
コマンドの_-t
_オプションは次のように使用できます。
_cp -R inputFolder -t outputFolder
_
ターゲットフォルダーが存在しない場合、エラーがスローされます。
_cp: failed to access ‘outputFolder’: No such file or directory
_
上記のコマンドは、inputFolder
をそのコンテンツ(およびその中のコンテンツだけでなく)とともにコピーします。
inputFolder
の内容だけをコピーしたい場合は少しトリッキーになります(アスタリスク*を使用しているときにシェルグロビングを使用するときは注意が必要なため)
_cp -R -t outputFolder/ -- inputFolder/*
_
ターゲットフォルダーが存在しない場合、エラーがスローされます。
_cp: failed to access ‘outputFolder’: No such file or directory
_
cp (GNU coreutils) 8.23
で動作します