「cp」が既存のファイルを自動的に上書きするように設計されているのはなぜですか? [閉鎖]

「cp」が既存のファイルを自動的に上書きするように設計されているのはなぜですか? [閉鎖]

cp次のコマンドを使用してテストしました。

$ ls
first.html   second.html  third.html

$ cat first.html
first

$ cat second.html
second

$ cat third.html
third

first.htmlその後、次の場所にコピーしましたsecond.html

$ cp first.html second.html

$ cat second.html
first

ファイルはsecond.htmlエラーなしで自動的に上書きされます。ただし、デスクトップGUIから同じ名前のファイルをドラッグアンドドロップしてこれを実行すると、first1.html自動的にサフィックスが追加されます。これにより、誤って既存のファイルを上書きするのを防ぎます。

cpファイルを自動的に上書きするのではなく、このパターンに従うことはどうですか?

答え1

デフォルトの上書き動作はcpPOSIXで指定されています。

  1. source_fileが通常のファイル形式の場合は、次の手順を実行する必要があります。

    3.a. dest_fileが存在し、前のステップで作成された場合、動作は指定されません。それ以外で dest_file がある場合は、次の手順を実行します。

    3.ai -iオプションが適用される場合、cpユーティリティは標準エラーのプロンプトを作成し、標準入力から1行を読み取る必要があります。応答が肯定的でない場合、cp は source_file の処理を​​実行せずに残りのファイルを処理し続けます。

    3.a.ii dest_fileのファイル記述子は、dest_fileをパスパラメータとして使用し、O_WRONLYおよびO_TRUNC Bitwiseを使用するPOSIX.1-2017システムインタフェースボリュームで定義されているopen()関数と同じことを実行します。 OR oflag 引数として使用されます。

    3.a.iii.ファイル記述子を取得しようとして失敗し、-fオプションが有効な場合、cpはPOSIX.1-で定義されているunlink()関数と同じ操作を実行してファイル記述子を取得しようとします。 2017 dest_fileで呼び出されたシステムインターフェイスのボリュームパスパラメータでファイルを削除します。この試みが成功すると、cpはステップ3bに進みます。

POSIX仕様が作成されたときに、基本オーバーライドの動作に関する基本仮定を含む多数のスクリプトがすでに存在していました。これらのスクリプトの多くは、cronジョブやその他のバックグラウンドジョブなど、ユーザーが直接存在せずに実行するように設計されています。行動を変えるとそれらを破壊します。必要に応じて強制オーバーライドオプションを追加するためにこれをチェックして修正することは、利点がほとんどない厳しい作業と見なすことができます。

さらに、Unixコマンドラインは、初心者の学習曲線を犠牲にしても経験豊富なユーザーが効率的に作業できるように常に設計されています。ユーザーがコマンドを入力すると、コンピューターはユーザーが推測せずにそのコマンドを意味すると期待します。潜在的に破壊的なコマンドに注意するのはユーザーの責任です。

もともとUnixが開発されたとき、システムは最新のコンピュータに比べてメモリと大容量の記憶領域がほとんどなく、警告やプロンプトを上書きすることは無駄で不要な贅沢と考えられているかもしれません。

POSIX標準が作成されたとき、先例はしっかりと確立され、標準作成者はPOSIX標準の利点をよく知っていました。以前のバージョンとの互換性を壊さない

cpまた、他の人が説明したように、すべてのユーザーはシェルエイリアスを使用するか、代替コマンドを作成して変更して$PATH標準システムコマンドの前に代替コマンドを見つけ、必要に応じてセキュリティを確保することで、これらの機能を自分で追加/アクティブ化できます。

しかし、これを行うと、自分に危険がもたらされることがわかります。cpコマンドが対話的に使用されているときに一方向に実行され、スクリプトから呼び出されたときに別の方法で実行される場合、違いがあることを覚えていない可能性があります。他のシステムでは、自分のシステムの警告やプロンプトに慣れているため、不注意になる可能性があります。

スクリプトの動作がまだPOSIXに準拠している場合は、インタラクティブな使用時にプロンプ​​トに慣れてから、多くのコピーを実行するスクリプトを作成してから、誤って何かを上書きしたことがわかります。

スクリプトがプロンプトを強制的に表示する場合、ユーザーなしでコンテキスト(バックグラウンドプロセスやクローン操作など)で実行されたときにコマンドは何をしますか?スクリプトが中断、中断、または上書きされますか?

中断または中断は、自動的に完了する必要がある操作が完了しないことを意味します。時には上書きしないこと自体も問題を引き起こす可能性があります。たとえば、古いデータを最新のデータに置き換えるのではなく、他のシステムで2回処理することができます。

コマンドラインの強力な機能は、次の事実に由来します。コマンドラインでどのような操作を実行するかがわかったら、スクリプトを作成してそのタスクを自動的に実行する方法を暗黙的に知ることができます。。ただし、インタラクティブに使用するコマンドがスクリプトコンテキストで呼び出された場合でもまったく同じように機能する場合にのみ当てはまります。インタラクティブ使用とスクリプト使用の動作に大きな違いがあると、上級ユーザーを迷惑にする可能性がある認知不調和が発生する可能性があります。

答え2

cpUnixの始まりから。 Posix 標準が作成される前に存在していました。本当です。 Posixはcpこれに関連して既存の動作を定式化します。

私たちは、男性が本物の男であり、女性が本物の女性であり、毛皮のような小さな生き物であった時代(1970-01-01)について話しています。当時、コードを追加するとプログラムが大きくなりました。 Unixを実行する最初のコンピュータがPDP-7(144KB RAMにアップグレード可能!)だったため、これは当時問題となりました。だからそのものは小さく、非常に効率的で、安全機能もありません。

そのため、当時は後で後悔することをすることをコンピュータが阻止する能力がなかったので、自分が何をしているのか知らなければなりませんでした。

(Zevarには素晴らしい漫画があります。「zevar cerveaux Assiste par ordordur」を検索してコンピュータの進化を見つけてください。または試してください。http://a54.idata.over-blog.com/2/07/74/62/dessins-et-bd/le-CAO-de-Zevar---reduc.jpg存在する限り)

本当に興味がある人のために(コメントから少し推測を見ました):cp最初のUnixの元のコードは約2ページのアセンブリコードでした(Cは後で出ました)。関連部分は次のとおりです。

sys open; name1: 0; 0   " Open the input file
spa
  jmp error         " File open error
lac o17         " Why load 15 (017) into AC?
sys creat; name2: 0     " Create the output file
spa
  jmp error         " File create error

(だから難しいsys creat

そして、それを行うと:Unixバージョン2が使用されます(コードスニペット)。

mode = buf[2] & 037;
if((fnew = creat(argv[2],mode)) < 0){
    stat(argv[2], buf);

creatこれはテストや保護装置がなければ難しいことです。 V2 Unix用のCコードはcp55行未満であることに注意してください。

答え3

これらのコマンドはスクリプトでも使用するためのものなので、人の監督なしで実行することができ、多くの場合、ターゲットをオーバーライドしたいからです(Linuxシェルの哲学は、人が自分が何をしているのかを知っているということです)。

また、次のようないくつかの保護装置もあります。

  • GNUcpには|-n--no-clobber
  • 複数のファイルを1つにコピーすると、cp最後のファイルがディレクトリではないと文句を言います。

答え4

「cp」のデザインはUnixのオリジナルデザインにさかのぼります。実際、Unixのデザインの背後には、冗談半分と呼ぶよりも少し少ない一貫した哲学があります。悪いほど良い*

基本的なアイデアは、コードを単純に保つことが、実際に完璧なインターフェースを持っているか、「正しいことをする」よりも重要な設計上の考慮事項であるということです。

  • シンプルさ - デザインは実装とインターフェイスの両方で単純でなければなりません。インターフェースよりも実装の簡素性が重要。シンプルさは、デザインで最も重要な考慮事項です。

  • 精度 - デザインは観察可能なあらゆる点で正確でなければなりません。単純なものが正しいよりも少し優れています。

  • 一貫性 - デザインが一貫性がないようにする必要があります。場合によっては、単純さのために一貫性を犠牲にすることができますが、あまり一般的ではない状況に対処するデザイン部分を捨てることをお勧めします。実装の複雑さや不一致を導入する代わりに。

  • 完全性 - デザインはできるだけ多くの実際の状況に対処する必要があります。合理的に予想されるすべての状況に対処する必要があります。他の品質のために完全性が犠牲になる可能性があります。実際、実装の単純さが損なわれるたびに完全性を犠牲にする必要があります。単純さが維持されると、完全性のために一貫性が犠牲になる可能性があります。特にインタフェースの一貫性は価値がない。

私のことを強調する)

1970年に「このファイルをコピーしたい」というユースケースを思い出してください。ただコピーしている人に「存在しなかったら」という言葉はかなり珍しいユースケースです。それがあなたが望むものであれば、コピーする前に確認したり、スクリプトを書くこともできます。

この記事の著者は、これらの設計アプローチを使用するオペレーティングシステムが当時構築された他のすべてのオペレーティングシステムよりも優れている理由について独自の理論を持っています。

「悪いほど良い」という哲学のもう一つの利点は、プログラマーが良いパフォーマンスと適切なリソース使用を達成するために、いくつかのセキュリティ、利便性、および面倒を犠牲にすることに精通していることです。ニュージャージー方式で書かれたプログラムは、小型システムと大型システムの両方でうまく動作し、コードはウイルスの上に書かれているため、移植性に優れています。

元のウイルスは基本的に良くなければならないことを覚えておくことが重要です。もしそうなら、携帯可能な限り、ウイルスの拡散は保証されます。いったん口コミが出たら、機能を90%に近づけて向上させようとする圧力があります。しかし、ユーザーは正しいよりも悪いことを受け入れるように条件付けられています。したがって、「悪いほど良い」というソフトウェアは最初に受け入れられ、2番目にユーザーの期待を下げ、3番目にほぼ正しいレベルに改善されます。

* - または著者(他の人はいない)が「ニュージャージー法」と呼ばれるものです

関連情報