Linuxマシン(実際にはコンピューティングクラスター)で、別のユーザー(適切なchmodを使用してコピーする権限を付与されたユーザー)からフォルダーをコピーしました。
このフォルダには、アクセスできないファイルへのシンボリックリンクが含まれています。私が所有している同じファイルのコピーを指すように更新したいと思います。
ただし、ln -sf
を使用してこれを実行しようとすると、Permission denied
が表示されます。
どうしてこんなことに?
それはリンクです:
$ ls -l 50ATC_Rep2.fastq
lrwxrwxrwx 1 bli cifs-BioIT 55 21 nov. 13:45 50ATC_Rep2.fastq -> /pasteur/homes/mmazzuol/Raw_data/CHIP_TEST/BM50.2.fastq
ターゲットにアクセスする権限がありませんが、コピーはあります。それが私が望む新しいターゲットです:
$ ls -l ../../../raw_data/CHIP_TEST/BM50.2.fastq
-rwxr-xr-x 1 bli cifs-BioIT 4872660831 21 nov. 14:00 ../../../raw_data/CHIP_TEST/BM50.2.fastq
そして、それは私がln -sf
を試すときに起こることです:
$ ln -sf ../../../raw_data/CHIP_TEST/BM50.2.fastq 50ATC_Rep2.fastq
ln: accessing `50ATC_Rep2.fastq': Permission denied
現在のターゲットのアクセス許可が重要であり、リンク自体のアクセス許可ではないようです。
最初にリンクを削除してから再作成することで、問題を回避できます。
$ rm 50ATC_Rep2.fastq
rm: remove symbolic link `50ATC_Rep2.fastq'? y
$ ln -s ../../../raw_data/CHIP_TEST/BM50.2.fastq 50ATC_Rep2.fastq
$ ls -l 50ATC_Rep2.fastq
lrwxrwxrwx 1 bli cifs-BioIT 40 21 nov. 18:57 50ATC_Rep2.fastq -> ../../../raw_data/CHIP_TEST/BM50.2.fastq
リンクを削除できるのに更新できないのはなぜですか?
LinuxのGNU ln
実装は、ターゲットが存在するかどうかを判断するために stat()
関数を使用しているように見えます。この関数はシンボリックリンクを解決するために必要であるため、既存のリンクのターゲットにアクセスできない場合、関数はEACCESS
( "permission denied")を返し、ユーティリティは失敗します。これは、UbuntuLinuxシステムでtrueであることがstrace
で確認されています。
GNU ln
を使用するようにするには、代わりに lstat()
を使用しますが、これはシンボリックリンクを解決しません。その(非標準)-n
オプション(GNUさらに、--no-dereference
のエイリアスとして-n
を使用します)。
ln -s -n -f ../../../raw_data/CHIP_TEST/BM50.2.fastq 50ATC_Rep2.fastq
ln
のPOSIX仕様 を読んで、GNU ln
が仕様の未定義または未指定の動作に対してこれを行うかどうかは、実際にはわかりませんが、可能性があります。という事実を使用して...
宛先パスが存在し、前の手順で作成された場合
ln
が診断メッセージを標準エラーに書き込むかどうかは指定されていません。現在のsource_file、および残りのsource_filesに進みます。または、現在のsource_fileの処理を続行します。
ここでの「未指定」ビットは、少なくとも「前のステップ」を「宛先パスがシンボリックリンクである」と解釈できる場合は、GNUln
にそのように動作するライセンスを与える可能性があります。
-n
オプションのGNUドキュメントは、ターゲットがディレクトリへのシンボリックリンクである場合を主に懸念しています。
'-n'
'--no-dereference'
Do not treat the last operand specially when it is a symbolic link
to a directory. Instead, treat it as if it were a normal file.
When the destination is an actual directory (not a symlink to one),
there is no ambiguity. The link is created in that directory. But
when the specified destination is a symlink to a directory, there
are two ways to treat the user's request. 'ln' can treat the
destination just as it would a normal directory and create the link
in it. On the other hand, the destination can be viewed as a
non-directory--as the symlink itself. In that case, 'ln' must
delete or backup that symlink before creating the new link. The
default is to treat a destination that is a symlink to a directory
just like a directory.
This option is weaker than the '--no-target-directory' ('-T')
option, so it has no effect if both options are given.
ターゲットがディレクトリへのシンボリックリンクである場合のGNU ln
のデフォルトの動作は、新しいシンボリックリンクをそのディレクトリ内に配置することです(つまり、ディレクトリへのリンクを逆参照します)。既存のリンクのターゲットにアクセスできない場合、診断メッセージを送信して失敗することを選択します(標準テキストで許可されています)。
一方、OpenBSD ln
(および他のBSDシステムではおそらくln
)は、ターゲットがaccessibleディレクトリへのシンボリックリンクである場合、GNU ln
のように動作しますが、リンクを解除します既存のリンクのターゲットがnotアクセス可能である場合は、要求に応じてシンボリックリンクを再作成します。つまり、操作を続行することを選択します(標準テキストで許可されています)。
また、OpenBSDのGNU ln
は、OpenBSDのネイティブのln
のように動作しますが、これはやや興味深いものです。
rm
を使用して既存のシンボリックリンクを削除しても、それが配置されているディレクトリに対する書き込み権限と実行可能権限があるように見えるため、問題にはなりません。