Tại sao `cp` được thiết kế để âm thầm ghi đè lên các tệp hiện có? [đóng cửa]


30

Tôi đã thử nghiệm cpvới các lệnh sau:

$ ls
first.html   second.html  third.html

$ cat first.html
first

$ cat second.html
second

$ cat third.html
third

Sau đó tôi sao chép first.htmlvào second.html:

$ cp first.html second.html

$ cat second.html
first

Các tập tin second.htmlđược âm thầm ghi đè mà không có bất kỳ lỗi. Tuy nhiên, nếu tôi làm điều đó trong GUI của máy tính để bàn bằng cách kéo và thả tệp có cùng tên, nó sẽ được first1.htmltự động thêm vào. Điều này tránh vô tình ghi đè lên một tập tin hiện có.

Tại sao không cptheo mô hình này thay vì ghi đè các tệp âm thầm?


10
Tôi tưởng tượng chỉ có các nhà thiết kế coreutils thực sự có thể trả lời câu hỏi, nhưng đó chỉ là cách nó hoạt động cho đến bây giờ. Thông thường các ứng dụng được xây dựng giả sử người dùng thực sự có nghĩa là những gì họ đang làm và để giảm thiểu nhắc nhở thêm. Nếu bạn muốn thay đổi hành vi, bí danh 'cp' thành 'cp -i' hoặc 'cp -n'.
kevlinux

8
@kevlinux Các nhà phát triển coreutils chỉ đang thực hiện tiêu chuẩn POSIX.
Kusalananda

17
Bởi vì trở lại khi nó được thiết kế, mọi người muốn trở nên ngắn gọn nhất có thể với những gì họ làm (do đó cp không sao chép) và biết những gì họ đã làm và khi họ mắc lỗi, họ đã không cố đổ lỗi cho các công cụ. Đó là một loại người hoàn toàn khác trước đó đã làm máy tính. Nó giống như hỏi tại sao một con dao mổ cho một bác sĩ phẫu thuật tim cũng có thể cắt vào tay.
PlasmaHH

4
Unix được thiết kế bởi và dành cho các chuyên gia máy tính, với giả định rằng người dùng biết mình đang làm gì. HĐH sẽ thực hiện chính xác những gì người dùng đã nói với nó nếu có thể - không cần nắm tay người dùng và không yêu cầu xác nhận vô tận. Nếu một hoạt động ghi đè lên một cái gì đó, nó đã được giả định đó là những gì người dùng muốn. Cũng nên nhớ rằng đây là đầu những năm 1970 - tiền MS MS, Windows và máy tính gia đình - hướng dẫn và nắm tay người dùng từng bước, vẫn chưa phổ biến. Ngoài ra, với teletype được gia công như thiết bị đầu cuối, yêu cầu xác nhận luôn luôn sẽ quá cồng kềnh.
Baard Kopperud

10
Đừng bí danh cpđể cp -ihoặc tương tự bởi vì bạn sẽ làm quen với việc có một mạng lưới an toàn, làm cho hệ thống mà nó không có sẵn (hầu hết trong số họ) mà nhiều rủi ro. Tốt hơn nên dạy bản thân thường xuyên, cp -ivv nếu đó là những gì bạn thích.
Reid

Câu trả lời:


52

Hành vi ghi đè mặc định của cpđược chỉ định trong POSIX.

  1. Nếu source_file thuộc loại tệp thông thường, các bước sau sẽ được thực hiện:

    3.a. Hành vi không được chỉ định nếu Dest_file tồn tại và được viết bởi bước trước. Mặt khác, nếu Dest_file tồn tại, các bước sau sẽ được thực hiện:

    3.ai Nếu tùy chọn -i có hiệu lực, tiện ích cp sẽ viết lời nhắc đến lỗi tiêu chuẩn và đọc một dòng từ đầu vào tiêu chuẩn. Nếu phản hồi không được xác nhận, cp sẽ không làm gì thêm với source_file và chuyển sang bất kỳ tệp nào còn lại.

    3.a.ii. Một bộ mô tả tệp cho Dest_file sẽ được lấy bằng cách thực hiện các hành động tương đương với hàm open () được xác định trong khối Giao diện hệ thống của POSIX.1-2017 được gọi bằng cách sử dụng Dest_file làm đối số đường dẫn và bao gồm bit OR của O_WRONLY và O_TRUNC như lập luận oflag.

    3.a.iii. Nếu cố gắng lấy bộ mô tả tệp không thành công và tùy chọn -f có hiệu lực, cp sẽ cố gắng xóa tệp bằng cách thực hiện các hành động tương đương với hàm unlink () được xác định trong khối lượng Giao diện hệ thống của POSIX.1-2017 được gọi bằng Dest_file như đối số đường dẫn. Nếu lần thử này thành công, cp sẽ tiếp tục với bước 3b.

Khi đặc tả POSIX được viết, đã có một số lượng lớn các tập lệnh tồn tại, với giả định tích hợp sẵn cho hành vi ghi đè mặc định. Nhiều tập lệnh trong số đó được thiết kế để chạy mà không có sự hiện diện của người dùng trực tiếp, ví dụ như các công việc định kỳ hoặc các tác vụ nền khác. Thay đổi hành vi sẽ phá vỡ chúng. Xem xét và sửa đổi tất cả chúng để thêm một tùy chọn để buộc ghi đè bất cứ nơi nào cần thiết có thể được coi là một nhiệm vụ lớn với lợi ích tối thiểu.

Ngoài ra, dòng lệnh Unix luôn được thiết kế để cho phép người dùng có kinh nghiệm làm việc hiệu quả, thậm chí phải trả giá bằng một đường cong học tập chăm chỉ cho người mới bắt đầu. Khi người dùng nhập một lệnh, máy tính sẽ mong đợi rằng người dùng thực sự có nghĩa là nó, mà không cần đoán lần thứ hai; Trách nhiệm của người dùng là phải cẩn thận với các lệnh có khả năng phá hủy.

Khi Unix ban đầu được phát triển, các hệ thống sau đó có rất ít bộ nhớ và dung lượng lưu trữ lớn so với các máy tính hiện đại ghi đè lên các cảnh báo và lời nhắc có lẽ được coi là xa xỉ lãng phí và không cần thiết.

Khi tiêu chuẩn POSIX được viết, tiền lệ đã được thiết lập vững chắc, và các tác giả của tiêu chuẩn đã nhận thức rõ về những ưu điểm của việc không phá vỡ tính tương thích ngược .

Ngoài ra, như những người khác đã mô tả, bất kỳ người dùng nào cũng có thể tự thêm / bật các tính năng đó bằng cách sử dụng bí danh shell hoặc thậm chí bằng cách xây dựng cplệnh thay thế và sửa đổi chúng $PATHđể tìm thay thế trước lệnh hệ thống tiêu chuẩn và lấy mạng an toàn theo cách đó nếu mong muốn.

Nhưng nếu bạn làm như vậy, bạn sẽ thấy rằng bạn đang tạo ra mối nguy hiểm cho chính mình. Nếu cplệnh hành xử một chiều khi được sử dụng tương tác và một cách khác khi được gọi từ một tập lệnh, bạn có thể không nhớ rằng sự khác biệt tồn tại. Trên một hệ thống khác, bạn có thể sẽ bất cẩn vì bạn đã quen với các cảnh báo và lời nhắc trên hệ thống của riêng bạn.

Nếu hành vi trong các tập lệnh vẫn khớp với tiêu chuẩn POSIX, bạn có thể đã quen với các lời nhắc trong sử dụng tương tác, sau đó viết một tập lệnh sao chép hàng loạt - và sau đó bạn lại vô tình ghi đè lên một cái gì đó.

Nếu bạn cũng thực thi nhắc nhở trong các tập lệnh, lệnh sẽ làm gì khi chạy trong ngữ cảnh không có người dùng xung quanh, ví dụ: các quy trình nền hoặc công việc cron? Kịch bản sẽ bị treo, hủy bỏ hoặc ghi đè?

Treo hoặc hủy bỏ có nghĩa là một nhiệm vụ được cho là hoàn thành tự động sẽ không được thực hiện. Không ghi đè đôi khi cũng có thể tự gây ra sự cố: ví dụ: nó có thể khiến dữ liệu cũ được xử lý hai lần bởi một hệ thống khác thay vì được thay thế bằng dữ liệu cập nhật.

Một phần lớn sức mạnh của dòng lệnh xuất phát từ thực tế là một khi bạn biết cách làm điều gì đó trên dòng lệnh, bạn cũng sẽ biết cách làm cho nó diễn ra tự động bằng cách viết kịch bản . Nhưng điều đó chỉ đúng nếu các lệnh bạn sử dụng tương tác cũng hoạt động chính xác như nhau khi được gọi trong ngữ cảnh tập lệnh. Bất kỳ sự khác biệt đáng kể nào trong hành vi giữa sử dụng tương tác và sử dụng theo kịch bản sẽ tạo ra một loại bất đồng về nhận thức gây khó chịu cho người sử dụng điện.


54
"Tại sao nó hoạt động như thế này?" "Bởi vì tiêu chuẩn nói như vậy." "Tại sao tiêu chuẩn nói như vậy?" "Bởi vì nó đã hoạt động như thế này."
Baptiste Candello

16
Đoạn cuối là lý do thực sự. Các hộp thoại xác nhận và " Bạn có thực sự muốn làm điều này không? " Lời nhắc dành cho wimps :-)
TripeHound

@BaptisteCand tướng - Đồng ý. Nó giống như lý do cuối cùng ở ngoài kia, nhưng trêu ngươi chỉ ngoài tầm với của câu trả lời này.
TED

2
Đoạn cuối đó là lý do tại sao rm -rfrất hiệu quả, ngay cả khi bạn không thực sự muốn chạy nó trong thư mục nhà của bạn ...
Max Vernon

2
@TED ​​Buồn cười làm sao không ai từng đề cập đến việc tòa nhà unlink (2) cũng 'thất bại' khi hỏi Mẹ Mẹ, tôi có thể xác nhận bất cứ khi nào những cuộc thảo luận về sempiternal này lại đứng sau những cái đầu lịch sự của họ. :)
tchrist

20

cpxuất phát từ sự khởi đầu của Unix. Nó đã ở đó trước khi tiêu chuẩn Posix được viết. Thật vậy: Posix chỉ chính thức hóa hành vi hiện có cpvề vấn đề này.

Chúng ta đang nói về Epoch (1970-01-01), khi đàn ông là đàn ông thực sự, phụ nữ là phụ nữ thực sự và những sinh vật nhỏ bé lông lá ... (tôi lạc đề). Trong những ngày đó, việc thêm mã làm cho một chương trình lớn hơn. Đó là một vấn đề sau đó, bởi vì máy tính đầu tiên chạy Unix là PDP-7 (có thể nâng cấp lên 144KB RAM!). Vì vậy, mọi thứ là nhỏ, hiệu quả, không có tính năng an toàn.

Vì vậy, trong những ngày đó, bạn phải biết những gì bạn đang làm, bởi vì máy tính không có khả năng ngăn bạn làm bất cứ điều gì bạn hối tiếc sau này.

(Có một phim hoạt hình hay của Zevar; tìm kiếm "zevar cerveaux hỗ trợ mệnh lệnh" để tìm sự phát triển của máy tính. Hoặc thử http://perinet.blogspirit.com/archive/2012/02/12/zevar-et- cointe.html miễn là nó tồn tại)

Đối với những người thực sự quan tâm (tôi đã thấy một số suy đoán trong các bình luận): Bản gốc cptrên Unix đầu tiên là về hai trang mã trình biên dịch (C đến sau). Phần liên quan là:

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

(Vì vậy, một khó khăn sys creat)

Và, trong khi chúng tôi đang ở đó: Phiên bản 2 của Unix được sử dụng (đoạn mã)

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

đó cũng là một khó khăn creatmà không có bài kiểm tra hoặc biện pháp bảo vệ. Lưu ý rằng mã C cho V2 Unix của cpít hơn 55 dòng!


5
Hầu như chính xác, excepr đó là " lông nhỏ " (sinh vật từ Alpha Centauri) không " lông nhỏ "!
TripeHound

1
@TED: Nó hoàn toàn phiên bản đầu có thể xảy ra cpchỉ opened đến đích với O_CREAT | O_TRUNCvà thực hiện một read/ writevòng lặp; chắc chắn, với hiện đại cpcó rất nhiều nút bấm mà về cơ bản nó phải cố gắng đến statđích trước và có thể dễ dàng kiểm tra sự tồn tại trước (và thực hiện với cp -i/ cp -n), nhưng nếu kỳ vọng được thiết lập từ cpcác công cụ xương nguyên bản , thay đổi hành vi đó sẽ phá vỡ các kịch bản hiện có một cách không cần thiết. Rốt cuộc, nó không giống như các shell hiện đại với việc aliaskhông thể tạo cp -imặc định cho việc sử dụng tương tác.
ShadowRanger

@ShadowRanger - Hừm. Bạn hoàn toàn đúng khi tôi thực sự không biết nên làm nó dễ hay khó. Bình luận đã bị xóa.
TED

1
@ShadowRanger Vâng, nhưng sau đó chỉ là đẩy bài học khó xuống đường cho đến khi nó xuất hiện trên một hệ thống sản xuất ...
chrylis -on strike-

1
@sourcejedi: Vui! Không thay đổi lý thuyết cơ bản của tôi (rằng việc mở vô điều kiện dễ dàng hơn với việc cắt ngắn và creatxảy ra tương đương với open+ O_CREAT | O_TRUNC), nhưng việc thiếu O_EXCLgiải thích tại sao việc xử lý các tệp hiện có lại quá dễ dàng; cố gắng làm như vậy vốn dĩ sẽ không phù hợp (về cơ bản bạn phải open/ statkiểm tra sự tồn tại, sau đó sử dụng creat, nhưng trên các hệ thống chia sẻ lớn, luôn luôn có thể vào lúc bạn nhận được creat, một người khác đã tạo tệp và bây giờ bạn đã thổi dù sao nó cũng đi). Cũng có thể chỉ ghi đè lên vô điều kiện.
ShadowRanger

19

Bởi vì các lệnh này cũng được sử dụng trong các tập lệnh, có thể chạy mà không có sự giám sát của con người và cũng vì có nhiều trường hợp bạn thực sự muốn ghi đè lên mục tiêu (triết lý của trình bao Linux là con người biết điều gì cô ấy đang làm)

Vẫn còn một vài biện pháp bảo vệ:

  • GNU cpcó một -n| --no-clobberTùy chọn
  • nếu bạn sao chép một số tệp vào một tệp cpsẽ khiếu nại rằng tệp cuối cùng không phải là thư mục.

Điều này chỉ áp dụng cho việc triển khai cụ thể của nhà cung cấp và câu hỏi không phải là về việc triển khai cụ thể của nhà cung cấp đó.
schily

10

Có phải "làm một việc một lúc" không?

Nhận xét này nghe giống như một câu hỏi về một nguyên tắc thiết kế chung. Thông thường, các câu hỏi về những điều này rất chủ quan, và chúng tôi không thể viết một câu trả lời thích hợp. Được cảnh báo rằng chúng tôi có thể đóng câu hỏi trong trường hợp này.

Đôi khi chúng tôi có một lời giải thích cho sự lựa chọn thiết kế ban đầu, bởi vì (các) nhà phát triển đã viết về chúng. Nhưng tôi không có câu trả lời hay cho câu hỏi này.

Tại sao cpđược thiết kế theo cách này?

Vấn đề là Unix đã hơn 40 tuổi.

Nếu bạn đang tạo một hệ thống mới bây giờ, bạn có thể đưa ra các lựa chọn thiết kế khác nhau. Nhưng thay đổi Unix sẽ phá vỡ các tập lệnh hiện có, như được đề cập trong các câu trả lời khác.

Tại sao được cp thiết kế để âm thầm ghi đè lên các tập tin hiện có?

Câu trả lời ngắn gọn là "Tôi không biết" :-).

Hiểu rằng đó cpchỉ là một vấn đề. Tôi nghĩ rằng không có chương trình lệnh gốc nào được bảo vệ chống lại việc ghi đè hoặc xóa các tập tin. Shell có một vấn đề tương tự khi chuyển hướng đầu ra:

$ cat first.html > second.html

Lệnh này cũng âm thầm ghi đè second.html.

Tôi quan tâm để nghĩ làm thế nào tất cả các chương trình này có thể được thiết kế lại. Nó có thể đòi hỏi một số phức tạp thêm.

Tôi nghĩ rằng đây là một phần của lời giải thích: Unix ban đầu nhấn mạnh việc triển khai đơn giản . Để giải thích chi tiết hơn về điều này, hãy xem "tệ hơn là tốt hơn", được liên kết ở cuối câu trả lời này.

Bạn có thể thay đổi > second.htmlđể nó dừng lại với một lỗi, nếu second.htmlđã tồn tại. Tuy nhiên, như chúng tôi đã đề cập, đôi khi người dùng không muốn thay thế một tệp hiện có. Ví dụ, cô ấy có thể đang xây dựng một lệnh phức tạp, thử nhiều lần cho đến khi nó làm được điều cô ấy muốn.

Người dùng có thể chạy rm second.htmltrước nếu cô ấy cần. Đây có thể là một sự thỏa hiệp tốt! Nó có một số nhược điểm có thể có của riêng nó.

  1. Người dùng phải nhập tên tệp hai lần.
  2. Mọi người cũng gặp nhiều rắc rối khi sử dụng rm. Vì vậy, tôi cũng muốn làm cho rman toàn hơn. Nhưng bằng cách nào? Nếu chúng tôi rmhiển thị từng tên tệp và yêu cầu người dùng xác nhận, giờ đây cô ấy phải viết ba dòng lệnh thay vì một dòng. Ngoài ra, nếu cô ấy phải làm điều này quá thường xuyên, cô ấy sẽ tập thói quen và gõ "y" để xác nhận mà không cần suy nghĩ. Vì vậy, nó có thể rất khó chịu, và nó vẫn có thể nguy hiểm.

Trên một hệ thống hiện đại, tôi khuyên bạn nên cài đặt trashlệnh và sử dụng nó thay vì rmkhi có thể. Việc giới thiệu bộ lưu trữ Thùng rác là một ý tưởng tuyệt vời, ví dụ như cho một PC đồ họa một người dùng .

Tôi nghĩ điều quan trọng là phải hiểu những hạn chế của phần cứng Unix gốc - dung lượng RAM và ổ đĩa bị giới hạn, đầu ra được hiển thị trên các máy in chậm cũng như hệ thống và phần mềm phát triển.

Lưu ý rằng Unix ban đầu không có tab hoàn thành , để nhanh chóng điền tên tệp cho một rmlệnh. (Ngoài ra, trình bao Bourne ban đầu không có lịch sử lệnh, ví dụ như khi bạn sử dụng phím mũi tên Lên trong bash).

Với đầu ra máy in, bạn sẽ sử dụng trình chỉnh sửa dựa trên dòng , ed. Điều này khó học hơn một trình soạn thảo văn bản trực quan. Bạn phải in một số dòng hiện tại, quyết định cách bạn muốn thay đổi chúng và nhập lệnh chỉnh sửa.

Sử dụng > second.htmlgiống như sử dụng một lệnh trong trình chỉnh sửa dòng. Hiệu quả của nó phụ thuộc vào trạng thái hiện tại. (Nếu second.htmlđã tồn tại, nội dung của nó sẽ bị loại bỏ). Nếu người dùng không chắc chắn về trạng thái hiện tại, cô ấy sẽ chạy lshoặc ls second.htmltrước tiên.

"Thực hiện đơn giản" như một nguyên tắc thiết kế

Có một cách giải thích phổ biến về thiết kế Unix, bắt đầu:

Thiết kế phải đơn giản, cả về cách thực hiện và giao diện. Điều quan trọng là việc thực hiện phải đơn giản hơn giao diện. Đơn giản là sự xem xét quan trọng nhất trong một thiết kế.

...

Gabriel lập luận rằng "Tệ hơn là tốt hơn" đã tạo ra phần mềm thành công hơn so với phương pháp của MIT: Miễn là chương trình ban đầu về cơ bản là tốt, sẽ mất ít thời gian và công sức hơn để thực hiện ban đầu và sẽ dễ thích nghi hơn với các tình huống mới. Chuyển phần mềm sang các máy mới, chẳng hạn, trở nên dễ dàng hơn nhiều theo cách này. Do đó, việc sử dụng nó sẽ lan truyền nhanh chóng, rất lâu trước khi một chương trình [tốt hơn] có cơ hội được phát triển và triển khai (lợi thế đầu tiên).

https://en.wikipedia.org/wiki/Worse_is_better


Tại sao ghi đè lên mục tiêu với cpmột "vấn đề"? Có nó tương tác xin phép, hoặc thất bại có thể là một "vấn đề" lớn như vậy.
Kusalananda

ồ, cảm ơn bạn. bổ sung cho hướng dẫn: 1) Viết các chương trình làm một việc và làm tốt. 2) Tin tưởng vào lập trình viên.
Đại số

2
Mất dữ liệu @Kusalananda là một vấn đề. Cá nhân tôi quan tâm đến việc giảm rủi ro mất dữ liệu. Có nhiều cách tiếp cận khác nhau. Nói rằng đó là một vấn đề không có nghĩa là các lựa chọn thay thế cũng không có vấn đề.
nguồn

1
@riderdragon Các chương trình được viết bằng ngôn ngữ C thường có thể thất bại theo những cách rất đáng ngạc nhiên, vì C tin tưởng vào lập trình viên. Nhưng các lập trình viên chỉ là không đáng tin cậy. Chúng tôi phải viết các công cụ rất tiên tiến, như valgrind , cần thiết để thử và tìm ra những sai lầm mà các lập trình viên mắc phải. Tôi nghĩ điều quan trọng là phải có các ngôn ngữ lập trình như Rust hoặc Python hoặc C # cố gắng thực thi "an toàn bộ nhớ" mà không tin tưởng vào lập trình viên. (Ngôn ngữ C được tạo bởi một trong những tác giả của UNIX, để viết UNIX bằng ngôn ngữ di động).
nguồn

1
Thậm chí tốt hơn cat first.html second.html > first.htmlsẽ cho kết quả first.htmllà bị ghi đè với nội dung của second.htmlchỉ. Các nội dung ban đầu bị mất cho tất cả các thời gian.
doneal24

9

Thiết kế của "cp" quay trở lại thiết kế ban đầu của Unix. Trên thực tế, có một triết lý mạch lạc đằng sau thiết kế Unix, ít hơn một chút mà nửa đùa nửa thật được gọi là Worse-is-Better * .

Ý tưởng cơ bản là giữ cho mã đơn giản thực sự là một xem xét thiết kế quan trọng hơn để có một giao diện hoàn hảo hoặc "thực hiện đúng".

  • Đơn giản - thiết kế phải đơn giản, cả về cách thực hiện và giao diện. Điều quan trọng là việc thực hiện phải đơn giản hơn giao diện . Đơn giản là sự xem xét quan trọng nhất trong một thiết kế.

  • Tính chính xác - thiết kế phải chính xác trong tất cả các khía cạnh quan sát được. Nó là một chút tốt hơn để đơn giản hơn chính xác.

  • Tính nhất quán - thiết kế không được quá nhất quán. Tính nhất quán có thể được hy sinh vì đơn giản trong một số trường hợp, nhưng tốt hơn là bỏ những phần đó của thiết kế xử lý các trường hợp ít phổ biến hơn là đưa ra sự phức tạp triển khai hoặc không nhất quán.

  • Tính đầy đủ - thiết kế phải bao gồm nhiều tình huống quan trọng như thực tế. Tất cả các trường hợp dự kiến ​​hợp lý nên được bảo hiểm. Sự hoàn thiện có thể được hy sinh để ủng hộ bất kỳ chất lượng nào khác. Trong thực tế, tính đầy đủ phải được hy sinh bất cứ khi nào việc thực hiện đơn giản bị nguy hiểm. Tính nhất quán có thể được hy sinh để đạt được sự hoàn thiện nếu sự đơn giản được giữ lại; đặc biệt vô giá trị là sự nhất quán của giao diện.

( nhấn mạnh của tôi )

Hãy nhớ rằng đây là năm 1970, trường hợp sử dụng "Tôi muốn sao chép tệp này chỉ nếu nó chưa tồn tại" sẽ là một trường hợp sử dụng khá hiếm hoi cho một người nào đó thực hiện một bản sao. Nếu đó là những gì bạn muốn, bạn hoàn toàn có khả năng kiểm tra trước khi sao chép và thậm chí có thể được viết kịch bản.

Về lý do tại sao một hệ điều hành với phương pháp thiết kế đó tình cờ trở thành hệ điều hành chiến thắng tất cả các hệ điều hành khác đang được xây dựng vào thời điểm đó, tác giả của bài tiểu luận cũng có một lý thuyết cho điều đó.

Một lợi ích nữa của triết lý tồi tệ hơn là lập trình viên có điều kiện hy sinh một số an toàn, thuận tiện và rắc rối để có được hiệu suất tốt và sử dụng tài nguyên khiêm tốn. Các chương trình được viết bằng cách tiếp cận New Jersey sẽ hoạt động tốt cả trong các máy nhỏ và lớn, và mã sẽ có thể mang theo được vì nó được viết trên đầu của virus.

Điều quan trọng cần nhớ là virus ban đầu phải cơ bản là tốt. Nếu vậy, sự lây lan virus được đảm bảo miễn là nó có thể mang theo được. Một khi virus đã lây lan, sẽ có áp lực để cải thiện nó, có thể bằng cách tăng chức năng của nó lên gần 90%, nhưng người dùng đã được điều hòa để chấp nhận điều tồi tệ hơn là điều đúng đắn. Do đó, phần mềm tồi tệ hơn trước tiên sẽ được chấp nhận, thứ hai sẽ khiến người dùng mong đợi ít hơn và thứ ba sẽ được cải thiện đến mức gần như là điều đúng đắn.

* - hoặc những gì tác giả, nhưng không ai khác, gọi là "Cách tiếp cận New Jersey" .


1
Đây là câu trả lời đúng.
tchrist

+1, nhưng tôi nghĩ sẽ có một ví dụ cụ thể. Khi bạn cài đặt phiên bản mới của chương trình mà bạn đã chỉnh sửa và biên dịch lại (và có thể đã thử nghiệm :-), bạn cố tình muốn ghi đè lên phiên bản cũ của chương trình. (Và có thể bạn muốn hành vi tương tự từ trình biên dịch của bạn. Vì vậy, đầu UNIX chỉ có creat()vs open(). open()Không thể tạo ra một tập tin nếu nó không tồn tại. Nó chỉ mất 0/1/2 để đọc / ghi / cả hai. Nó vẫn chưa mất O_CREAT, và không có O_EXCL).
nguồn

@sourcejedi - Xin lỗi, nhưng với tư cách là một nhà phát triển phần mềm, tôi thực sự không thể nghĩ ra một kịch bản nào khác ngoài kịch bản mà tôi đang thực hiện một bản sao. :-)
TED

@TED ​​xin lỗi, ý tôi là tôi đang đề xuất ví dụ này, là một trong những trường hợp không hiếm gặp khi bạn chắc chắn muốn ghi đè, so với so sánh trong câu hỏi mà có lẽ bạn đã không làm.
nguồn

0

Lý do chính là GUI có định nghĩa tương tác, trong khi một tệp nhị phân /bin/cpchỉ là một chương trình có thể được gọi từ tất cả các nơi, ví dụ từ GUI của bạn ;-). Tôi cá rằng ngay cả ngày nay, phần lớn các cuộc gọi /bin/cpsẽ không đến từ một thiết bị đầu cuối thực sự với người dùng đang gõ lệnh shell mà là từ máy chủ HTTP hoặc hệ thống thư hoặc NAS. Một bảo vệ tích hợp chống lại lỗi người dùng có ý nghĩa hoàn toàn trong một môi trường tương tác; ít hơn trong một nhị phân đơn giản. Ví dụ: GUI của bạn rất có thể sẽ gọi /bin/cptrong nền để thực hiện các hoạt động thực tế và sẽ phải xử lý các câu hỏi an toàn trên tiêu chuẩn ngay cả khi nó chỉ hỏi người dùng!

Lưu ý rằng đó là từ ngày đầu tiên gần như tầm thường để viết một trình bao bọc an toàn xung quanh /bin/cpnếu muốn. Triết lý * nix là cung cấp các khối xây dựng đơn giản cho người dùng: trong số này, /bin/cplà một.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.