ファイルを削除しますが、シンボリックリンクの場合のみ


11

理想的にはこのようなコマンドが欲しい

rm --only-if-symlink link-to-file

ファイルを指すシンボリックリンクではなく、誤ってファイルを削除して何度も火傷したためです。これは、sudoが関係する場合に特に悪い場合があります。もちろん、ls -al実際にシンボリックリンクなどであることを確認するためにa を実行しますが、これはオペレーターのエラー(同じ名前のファイル、タイプミスなど)と競合状態(誰かが何らかの理由でファイルを削除したい場合)に対して脆弱です。ファイルがシンボリックリンクかどうかを確認し、1つのコマンド内にある場合にのみ削除する方法はありますか?


1
レースコンディションを気にする必要はないと思います。シンボリックリンクを削除してファイルに置き換えることができるユーザーは、ディレクトリに対する書き込み権限が必要です。つまり、ファイル自体を削除することもできます。
Nate Eldredge 2016年

回答:


19
 $ rm_if_link(){ [ ! -L "$1" ] || rm -v "$1"; }

 #test
 $ touch nonlink; ln -s link
 $ rm_if_link nonlink
 $ rm_if_link link
   removed 'link'     

4
確かに削除することがより明確になり!、変更||&&
グレン・ジャックマン

5
@glennjackman ||フォームを好むのを習慣にしています。モードになっ&&ていると、物事がダウンしset -eます。
PSkocik 2016年

@PSkocik興味深いケース(ファイルが存在し、シンボリックリンクである)と、引用符で囲まれていない空の値([ ! -L $1 ])など、無効な演算子([ ! -l foo ])、または構文エラー([ ! -q foo || echo foo
l0b0

2
@XiongChiamiovの問題rm_if_link(){ [ -L "$1" ] && rm -v "$1"; }は、非リンクset -e モードで実行するとシェルプロセスが終了することです。追加することもできます|| :が、IMHOは! ||バージョンよりも明確になりrmませんset -e。これにより、でエラーが発生してユーザーが強制終了されるのを防ぎます。これは望ましくない可能性があります。! ||非常に簡潔で明確であり、これらの問題のどれにも悩まされません。
PSkocik 2016年

1
いいえ。その他のオプション:a)rmテストの内部に置く、b)実際のifステートメントを使用する、c)-eインタラクティブシェルの内部を使用しない(およびスクリプトをテストする!)読みやすさについて議論したいif場合、何かがリンクであるかどうかをテストするために使用することは、明らかに勝者です。
モニカ

5

findとその-type lテスト条件を使用できます(検出されたオブジェクトがlインクかどうかをテストします)

たとえばfoo、現在のディレクトリに呼び出されたファイルがある場合、次のようにできます。

$ find . -type l -iname "foo" -delete

あなたはそれを簡単にすることができるかもしれません:

$ find . -maxdepth 1 -type l -delete

現在のディレクトリにあるすべてのシンボリックリンクを削除します。

警告:

-deleteオプションfindは本当に危険です。検索コマンドの最後に必ず配置してください。見当違いの場合、結果が条件に一致するかどうかに関係なく、検出したものはすべて削除されます。

コメントで示唆されているように、より安全なオプションはfindrm -i(およびファイルの削除を確認することを強制する)を使用することです:

$ $ find . -type l -iname "foo" | xargs rm -i

個人-exec trash {} \;的に、私はあなたと同じようrmに過去に焼失したため、一時的にファイルを削除するために使用します。Doubleは-deleteフラグを置き忘れました。

http://slackermedia.ml/trashy


1
-deleteの代わりに、出力してxargsに渡すだけで済みますfind . -type l -iname "foo" | xargs rm -i 。より安全です。
Boban P.

1
確かに、@ BobanP rm -i。の安全のための使用は好きです。
Klaatu von Schlacker 2016年

3
「これにより、現在のディレクトリにあるすべてのシンボリックリンクが削除されます」...およびその下のすべてのポイント。
ジョセフR.

1
@JosephRとして。と言った、それは道をずっと下ります。検索に-maxdepth 1を追加します。
Boban P.

1
それでもスペースのあるファイル名では壊れます。-print0for find-0forの使用を提案しxargsます。
ワイルドカード

4
zsh -c 'rm foo(@)'

@あるグロブ修飾子は、パターンはfoo(@)一致するものとfoo一致しますが、シンボリックリンクのみです。

foo(-@)壊れたシンボリックリンクにのみ一致します。foo(@,L0)シンボリックリンクと空のファイルのみに一致します。

もちろん、そもそもzshを実行している場合は、と入力するだけですrm foo(@)Enter入力する前にを押さないように注意する必要があります(@)


1
このような答えを見ると、Zshはますます強力に聞こえます。
Jeff Schaller
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.