回答:
「簡単」のいくつかの定義:
#!/bin/sh
set -e
for link; do
test -h "$link" || continue
dir=$(dirname "$link")
reltarget=$(readlink "$link")
case $reltarget in
/*) abstarget=$reltarget;;
*) abstarget=$dir/$reltarget;;
esac
rm -fv "$link"
cp -afv "$abstarget" "$link" || {
# on failure, restore the symlink
rm -rfv "$link"
ln -sfv "$reltarget" "$link"
}
done
リンク名を引数としてこのスクリプトを実行します。たとえば find . -type l -exec /path/tos/script {} +
"$var"
には、"${var}"
SH / bashでNOOPです。1つのbashism([[
)を削除しました。残りはPOSIX shと互換性があります。
cp
は、同じディレクトリ内の一時ファイルを使用してから、mv -f
その一時ファイルを元の状態にすることです。これCtrl-C
によりrm
、cp
コマンドを押し続けたり、コマンドとコマンドの間でファイルシステムがいっぱいになるなどの問題を防ぐことができます(したがって、新しいln
ものでも動作しなくなります)。一時ファイル名はls -a
、必要に応じて後でクリーンアップするために簡単に見つけることができます。
abstarget=$(readlink -f "$link")
代わりに単に使用しなかった理由を真剣に思い出すことができませんが、それは移植性の理由だったかもしれません。
tarを使用してデータを新しいディレクトリにコピーする方が簡単な場合があります。
-H (c and r mode only) Symbolic links named on the command line will be followed; the target of the link will be archived, not the link itself.
このようなものを使用できます
tar -hcf - sourcedir | tar -xf - -C newdir
tar --help:
-H, --format=FORMAT create archive of the given format
-h, --dereference follow symlinks; archive and dump the files they point to
tar -hcf - sourcedir | tar -xf - -C newdir
cp -L
より簡単なソリューションです
cp
実装がディレクトリをコピーするわけではありません。
「簡単」はおそらくあなたの機能です。
「find」コマンドラインユーティリティを使用してシンボリックにリンクされたファイルを検索し、rmとcpを呼び出してファイルを削除および置換するスクリプトをおそらく作成します。symリンクを移動する前に、十分な空き領域が残っていることをfindチェックで呼び出すアクションを実行することもできます。
別の解決策は、symリンクなどのsymリンクを隠す何かを通して問題のファイルシステムをマウントし、そこからすべてをコピーすることです。しかし、多くの場合、そのようなことは他の問題を引き起こすでしょう。
あなたの質問に対するより直接的な答えはおそらく「はい」でしょう。
編集:より具体的な情報のリクエストに応じて。findのmanページによると、このコマンドは/からの2つのディレクトリの深さまでのすべてのsymリンクファイルをリストします。
find / -maxdepth 2 -type l -print
findを見つけて何かを実行させるには:
find / -maxdepth 2 -type l -exec ./ReplaceSymLink.sh {} \;
作成したばかりのスクリプトを呼び出し、見つけたファイル名を渡すと思います。または、find出力をファイルにキャプチャし(「find [blah]> symlinks.data」などを使用)、そのファイルを元のコピーを適切に処理するために記述したスクリプトに渡すこともできます。
-exec ./ReplaceSymLink.sh {} \;
これは私が使用したonelinerです。すべてのローカルファイルが「ソース」内の別のファイルへのリンクであると仮定します。パターンまたは「検索」でファイル選択を絞り込むことができます。ご使用前にご理解ください。
for in *; do cp --remove-destination source / $ f $ f; やった
お役に立てれば
find ./ -type l -print0|xargs -0 -n1 -i sh -c 'cp --remove-destination $(readlink "{}") "{}" '
基づいてhttps://superuser.com/a/1301199/499386 MastroGeppettoの
通常、リンクをたどってファイルをコピーすると予想されるときに、リンクをコピーするgwenviewで同じ問題が発生しました。
すべてのリンクをたどり、指示されたすべてのファイルをディレクトリにコピーすることでディレクトリを「クリーン」にするために、スクラッチディレクトリを作成しました。たとえば、
"for file in `ls`; do cp -L $file scratchdir/$file; done; mv scratchdir/* ./"
これはチェックが行われないためスクリプトに入れるには危険すぎますが、私の問題は解決しました。
for f in *; do cp --remove-destination $(readlink "$f") "$f"; done