2009-09-06 12 views
18

シンボリックリンクのターゲットをbashスクリプトから変更したいと思います。新しいターゲットはつまり、何かをすることを何の可能性は存在しません、すぐに古い削除した後に使用可能になります重要なシンボリックリンクを '安全に置き換える'

  1. :という問題がシンボリックリンクが非常に重要であるということである(それはつまり、/bin/shだ)と私はファッションでそれを行うことを希望
  2. 途中で変更が失敗する可能性はありません。すなわち、シンボリックリンクが削除され、新しいものは削除されたままになる可能性はありません。

私は2つの方法を考えました。どちらの平野lnを使用して:

ln -fs /bin/bash /bin/sh 

またはmv使用:

ln -s /bin/bash /bin/sh.new 
mv /bin/sh.new /bin/sh 

1がより良い私のニーズに合うのだろうか?シンボリックリンクの代わりにシンボリックリンクを置き換える可能性はありますか?

答えて

22

名前変更(mv)はアトミック操作です。新しいシンボリックリンクを作成することはできません(古いシンボリックリンクを削除し、新しいシンボリックリンクを作成します)。だから、mvを使用する必要があります。

$ ln -s new current_tmp && mv -Tf current_tmp current 

ここでこれを議論するblog postです。また、何が起こるか心配している場合は、最初に重要ではないシンボリックリンクで試してみてはいかがですか?

+1

あなたが試してみると潜在的な問題はないと確信することはできません:)。 「通知が消える」のテストを行うことは非常に難しいです。 – Eugene

+1

ブログ記事について - '-T'は移植可能なオプションではないようです。 –

-1

(マニュアルページより)ln -fは新しいものを作成する前にシンボリックリンクのリンクを解除しています。つまり、mvがこれに適しています。

に対してをリンクすることを強くお勧めします。/bin/shbashです。多くのスクリプトは次のものを使用します:

#!/bin/sh 

と書かれています。シェルは古典的なBourneシェルであると仮定して書かれています。これは代わりにbashを実行した場合、あなたは簡単にスクリプトがshがないと仮定し、bash実際が何をどのような間のあいまいな非互換性を得ることができます。これらは追跡することはほとんど不可能です。

+5

もちろん、多くのシステムでは、/ bin/sh *は/ bin/bashへのシンボリックリンクです。それを介して呼び出されると、bashはsh互換モードに入ります。 –

+0

bashはsh互換性がありません。実際のshとbashでこれを試してください: i = 0; ls |を読んでいる間; do i = expr $ i + 1;完了しました。あなたは本当の SHを持っていない場合は$ I エコー、上記の結果もSHのバージョン間で異なることをkshの注意をしてみてください。 solarisでは、非常に古いshは0を出力しますが、xpg4のバージョンはkshのようにゼロ以外の値を返します。 – Gunstick

+1

@Gun: "sh"は "sh"互換性がありません(あなたが言っていることです)。 ..ええ、確かに、bashを含む何も、古い "sh"のすべての未定義の動作と互換性があります。しかし、bash *ができることは、一般的に想定されている/受け入れられている/定義されているsh-standardと互換性があります。 POSIXまたはSUSv2が考えられます。 –

関連する問題