`ln -sf`が単にシンボリックリンクである既存のファイルを上書きするかどうか

`ln -sf`が単にシンボリックリンクである既存のファイルを上書きするかどうか

~からコアツール ln手動:

通常なぜなら既存のファイルは削除されません。使用- 力- F)無条件に削除するオプション
- インタラクティブ-私
)条件付きで削除するオプション- サポート-雨) オプションを使用して名前を変更できます。

$ mkdir output

私はこの失敗を理解することができます。

$ ln -sT /etc/passwd output
ln: failed to create symbolic link ‘output’: File exists

しかし、なぜ追加しないのですか?-f 返品失敗する:

$ ln -sfT /etc/passwd output
ln: ‘output’: cannot overwrite directory

-f 他の種類のファイル(ディレクトリ、一般ファイル...)ではなく、シンボリックリンクでのみ構成された既存のファイルを上書きしますか?

-T最後のパラメータ(ターゲットファイルパラメータなど)が既存のディレクトリであり、そのディレクトリをリンクで上書きしたい場合に使用できますか?

答え1

UNIXでは、ディレクトリは次のようになります。特別な(Saturday Night Liveの教会の女性をチャネリングするような気がしました。)ディレクトリには他のファイルが含まれているので、そのファイルを削除するには別の作業が必要です。ディレクトリが空であってもまだ2つのファイル(.および..)があるため、ディレクトリが実際に空であり、関連ファイルのリンク数が更新されるまでディレクトリを削除することはできません。

UNIXの初期(私の最初の経験はBell Labsのバージョン6でした)には、通常のファイルとディレクトリに対して2つの異なるコマンド(および)がありました。rmこれrmdirは、2つの異なるシステムコールという基本的な事実を反映しています。 rm簡単に言えば、名前を付けたエントリをディレクトリから削除し、そのエントリが指すファイルの参照数を減らします(もちろん、参照数がゼロでない限り、ファイルは実際には削除されません)。 rmdir必要があれば(実際にはアプリケーションではなくシステムコールで)、ディレクトリに行き、エントリを見つけてその.inode..に移動して参照カウントを減らし、親エントリを削除して参照カウントを減らす必要があります。 (ディレクトリ自体で参照された数だけ減少し、.この時点ではゼロでなければなりません。)これはすべて異なるディスクセクタにまたがるため、fsckがいつでも中断(システムクラッシュ)の可能性から回復できるように慎重に調整する必要があります。 。

もちろん、最新のUNIXシステムでは、ハードウェア制限(例:最大プログラムサイズ64Kbyte、はい「K」)が緩和され、今ではrm -r多くの潜在的なタスクを実行できるようになりました。特別なディレクトリの性格はあまり明確ではありませんが、まだ存在します。 6版コンピュータから大きな木を削除しなければならなかった記憶があります。これには、すべてのディレクトリに移動してすべてのファイルを削除し、親ディレクトリに戻り、ディレクトリツリー全体rmdirですべての再帰操作を手動で実行することが含まれていました。私たちはこれを助けるためにスクリプトを検討しましたが、当時は非常にまれであり、危険すぎたので、誰かに全力を尽くすように頼むことは致命的なエラーを防ぐのに役立ちます。

最初に「復元する方法sudo rm -rf /の代わりに」と入力しました。./

答え2

ファイルを削除できますが、ディレクトリは「ファイル」ではありません。

➜  lab touch file        
➜  lab mkdir dir
➜  lab ln -sfT /home file
➜  lab ln -sfT /home dir 
ln: dir: cannot overwrite directory

これで見ることができます源泉:

  if (remove_existing_files || interactive || backup_type != no_backups)
    {
      dest_lstat_ok = (lstat (dest, &dest_stats) == 0);
      if (!dest_lstat_ok && errno != ENOENT)
        {
          error (0, errno, _("failed to access %s"), quoteaf (dest));
          return false;
        }
    }
[...]
  if (dest_lstat_ok)
    {
      if (S_ISDIR (dest_stats.st_mode))
        {
          error (0, 0, _("%s: cannot overwrite directory"), quotef (dest));
          return false;
        }
      if (interactive)
        {
          fprintf (stderr, _("%s: replace %s? "), program_name, quoteaf (dest));
          if (!yesno ())
            return true;
          remove_existing_files = true;
        }

dest_lstat_okfalseで始まるブール値はtrueになり、最初のifステートメントを呼び出します。それがremove_existing_files本当だから、--forceサインがあるから、次に2番目のifステートメントを確認できます。期待しているので、ディレクトリの削除を拒否します。文書

-Tそうしないとln はディレクトリをディレクトリではないものとして扱いません。、lnはソースのデフォルト名を使用して、ディレクトリの下にシンボリックリンクのみを生成します。

関連情報