"Tất cả mọi thứ là một tập tin" là một chút glib. "Mọi thứ xuất hiện ở đâu đó trong hệ thống tập tin " gần với nhãn hiệu hơn và thậm chí sau đó, nó còn lý tưởng hơn cả luật thiết kế hệ thống.
Ví dụ, ổ cắm tên miền Unix không phải là tệp, nhưng chúng xuất hiện trong hệ thống tệp. Bạn có thể ls -l
một ổ cắm miền để hiển thị các thuộc tính, cat
dữ liệu đến / từ một, sửa đổi điều khiển truy cập của nó thông qua chmod
, v.v.
Nhưng, mặc dù các ổ cắm mạng TCP / IP thông thường được tạo và thao tác với cùng các hệ thống ổ cắm BSD giống như các ổ cắm tên miền Unix, các ổ cắm TCP / IP không hiển thị trong hệ thống tệp, mặc dù không có lý do nào đặc biệt tốt vì điều này nên đúng.
Một ví dụ khác về các đối tượng không phải tệp xuất hiện trong hệ thống tệp là hệ thống tệp của Linux/proc
. Tính năng này hiển thị rất nhiều chi tiết về hoạt động trong thời gian chạy của kernel cho không gian người dùng , chủ yếu là các tệp văn bản thuần ảo. Nhiều /proc
mục chỉ đọc, nhưng nhiều mục /proc
cũng có thể ghi, vì vậy bạn có thể thay đổi cách hệ thống chạy bằng bất kỳ chương trình nào có thể sửa đổi tệp. Than ôi, ở đây một lần nữa chúng ta có một tính không phổ biến: Unix loại BSD thường chạy mà không có/proc
, và System V Unixes phơi bày ít hơn rất nhiều /proc
so với Linux.
Tôi không thể đối chiếu với MS Windows
Đầu tiên, phần lớn tình cảm bạn có thể tìm thấy trực tuyến và trong các cuốn sách về Unix là tất cả về tệp I / O và Windows bị "phá vỡ" về vấn đề này đã lỗi thời. Windows NT đã sửa rất nhiều thứ này.
Các phiên bản Windows hiện đại có hệ thống I / O hợp nhất, giống như Unix, vì vậy bạn có thể đọc dữ liệu mạng từ ổ cắm TCP / IP thông qua ReadFile()
API cụ thể của Windows Sockets WSARecv()
, nếu bạn muốn. Đây chính xác song song với Way Unix , nơi bạn có thể đọc từ một ổ cắm mạng với một trong hai generic read(2)
Unix gọi hệ thống hoặc ổ cắm cụ thể recv(2)
call.²
Tuy nhiên, Windows vẫn không đưa khái niệm này lên cùng cấp với Unix, ngay cả ở đây vào năm 2018. Có nhiều khu vực của kiến trúc Windows không thể được truy cập thông qua hệ thống tệp hoặc không thể xem là giống như tệp. Vài ví dụ:
Tài xế.
Hệ thống con trình điều khiển của Windows dễ dàng và phong phú như Unix, nhưng để viết chương trình để thao tác trình điều khiển, bạn thường phải sử dụng Windows Driver Kit , có nghĩa là viết mã C hoặc .NET.
Trên các hệ điều hành Unix, bạn có thể làm rất nhiều trình điều khiển từ dòng lệnh. Bạn gần như chắc chắn đã làm điều này, nếu chỉ bằng cách chuyển hướng đầu ra không mong muốn sang /dev/null
.³
Truyền thông liên chương trình.
Các chương trình Windows không giao tiếp dễ dàng với nhau.
Các chương trình dòng lệnh Unix giao tiếp dễ dàng thông qua các luồng văn bản và đường ống. Các chương trình GUI thường được xây dựng dựa trên các chương trình dòng lệnh hoặc xuất giao diện lệnh văn bản, để các cơ chế giao tiếp dựa trên văn bản đơn giản cũng hoạt động với các chương trình GUI.
Việc đăng ký.
Unix không có tương đương trực tiếp với Windows registry. Thông tin tương tự được phân tán thông qua hệ thống tập tin, hầu hết trong đó /etc
, /proc
và /sys
.
Nếu bạn không thấy rằng trình điều khiển, đường ống và câu trả lời của Unix cho Windows registry có liên quan gì đến "mọi thứ đều là tệp", hãy đọc tiếp.
Làm thế nào để triết lý "Mọi thứ là một tập tin" tạo ra sự khác biệt ở đây?
Tôi sẽ giải thích rằng bằng cách mở rộng trên ba điểm của tôi ở trên, một cách chi tiết.
Câu trả lời dài, phần 1: Ổ đĩa so với tệp thiết bị
Giả sử đầu đọc thẻ CF của bạn xuất hiện E:
dưới Windows và /dev/sdc
Linux. Nó khác biệt thực tế gì?
Nó không chỉ là một sự khác biệt cú pháp nhỏ.
Trên Linux, tôi có thể nói dd if=/dev/zero of=/dev/sdc
để ghi đè lên nội dung /dev/sdc
bằng số không.
Hãy suy nghĩ về những gì có nghĩa là trong một giây. Ở đây tôi có một chương trình không gian người dùng bình thường ( dd(1)
) mà tôi đã yêu cầu đọc dữ liệu từ một thiết bị ảo ( /dev/zero
) và viết những gì nó đọc ra cho một thiết bị vật lý thực ( /dev/sdc
) thông qua hệ thống tệp Unix hợp nhất. dd
không biết nó đang đọc và ghi vào các thiết bị đặc biệt. Nó cũng sẽ hoạt động trên các tệp thông thường, hoặc trên hỗn hợp các thiết bị và tệp, như chúng ta sẽ thấy bên dưới.
Không có cách nào dễ dàng để làm trống E:
ổ đĩa trên Windows, vì Windows phân biệt giữa các tệp và ổ đĩa, vì vậy bạn không thể sử dụng các lệnh tương tự để thao tác chúng. Cách gần nhất bạn có thể nhận là thực hiện một định dạng đĩa mà không có tùy chọn Định dạng nhanh, nó sẽ thay đổi hầu hết các nội dung ổ đĩa, nhưng sau đó ghi một hệ thống tệp mới lên trên nó. Nếu tôi không muốn có một hệ thống tập tin mới thì sao? Điều gì sẽ xảy ra nếu tôi thực sự muốn đĩa được lấp đầy không có gì ngoài số không?
Hãy hào phóng và nói rằng chúng tôi thực sự muốn có một hệ thống tập tin mới E:
. Để làm điều đó trong một chương trình trên Windows, tôi phải gọi một API định dạng đặc biệt. Trên Linux, bạn không cần phải viết chương trình để truy cập chức năng "đĩa định dạng" của HĐH. Bạn chỉ cần chạy chương trình không gian sử dụng phù hợp với loại hệ thống tập tin bạn muốn tạo: mkfs.ext4
, mkfs.xfs
, hoặc những gì có bạn. Các chương trình này sẽ ghi một hệ thống tệp vào bất kỳ tệp hoặc /dev
nút nào bạn vượt qua.
Vì mkfs
các chương trình loại trên hệ thống Unixy hoạt động trên các tệp mà không tạo ra sự khác biệt giả tạo giữa các thiết bị và các tệp thông thường, điều đó có nghĩa là tôi có thể tạo một hệ thống tệp ext4 bên trong một tệp bình thường trên hộp Linux của mình:
$ dd if=/dev/zero of=myfs bs=1k count=1k
$ mkfs.ext4 -F myfs
Điều đó thực sự tạo ra một hình ảnh đĩa 1 MiB trong thư mục hiện tại, được gọi myfs
. Sau đó tôi có thể gắn kết nó như thể nó là bất kỳ hệ thống tập tin bên ngoài nào khác:
$ mkdir mountpoint
$ sudo mount -o loop myfs mountpoint
$ grep $USER /etc/passwd > mountpoint/my-passwd-entry
$ sudo umount mountpoint
Bây giờ tôi có một hình ảnh đĩa ext4 với một tệp được gọi my-passwd-entry
trong đó có /etc/passwd
mục nhập của người dùng của tôi .
Nếu tôi muốn, tôi có thể đưa hình ảnh đó vào thẻ CF của mình:
$ sudo dd if=myfs of=/dev/sdc1
Hoặc, tôi có thể đóng gói hình ảnh đĩa đó, gửi nó cho bạn và cho phép bạn ghi nó vào phương tiện bạn chọn, chẳng hạn như thẻ nhớ USB:
$ gzip myfs
$ echo "Here's the disk image I promised to send you." |
mutt -a myfs.gz -s "Password file disk image" you@example.com
Tất cả điều này có thể có trên Linux⁵ vì không có sự phân biệt giả tạo giữa các tệp, hệ thống tệp và thiết bị. Nhiều thứ trên các hệ thống Unix là tệp hoặc được truy cập thông qua hệ thống tệp để chúng trông giống như tệp hoặc theo một cách khác trông giống như tệp đủ để chúng có thể được xử lý như vậy.
Khái niệm hệ thống tập tin của Windows là một hodgepodge; nó tạo ra sự khác biệt giữa các thư mục, ổ đĩa và tài nguyên mạng. Có ba cú pháp khác nhau, tất cả được pha trộn với nhau trong Windows: ..\FOO\BAR
hệ thống đường dẫn giống Unix , các ký tự như thế C:
và các đường dẫn UNC như thế nào \\SERVER\PATH\FILE.TXT
. Điều này là do đó là sự bồi đắp các ý tưởng từ Unix, CP / M , MS-DOS và LAN Manager , thay vì một thiết kế mạch lạc. Đó là lý do tại sao có rất nhiều ký tự không hợp lệ trong tên tệp Windows .
Unix có một hệ thống tập tin thống nhất, với mọi thứ được truy cập bởi một lược đồ chung duy nhất. Để một chương trình chạy trên một hộp Linux, không có sự khác biệt về chức năng giữa /etc/passwd
, /media/CF_CARD/etc/passwd
và /mnt/server/etc/passwd
. Tất cả các tệp cục bộ, phương tiện bên ngoài và chia sẻ mạng đều được xử lý theo cùng một cách.
Windows có thể đạt được kết thúc tương tự như ví dụ hình ảnh đĩa của tôi ở trên, nhưng bạn phải sử dụng các chương trình đặc biệt được viết bởi các lập trình viên tài năng khác thường. Đây là lý do tại sao có rất nhiều chương trình loại "DVD ảo" trên Windows . Việc thiếu tính năng hệ điều hành cốt lõi đã tạo ra một thị trường nhân tạo cho các chương trình để lấp đầy khoảng trống, điều đó có nghĩa là bạn có một nhóm người cạnh tranh để tạo ra chương trình loại DVD ảo tốt nhất. Chúng tôi không cần các chương trình như vậy trên các hệ thống * ix, bởi vì chúng tôi chỉ có thể gắn hình ảnh đĩa ISO bằng thiết bị lặp .
Điều tương tự cũng xảy ra với các công cụ khác như chương trình xóa đĩa mà chúng ta cũng không cần trên các hệ thống Unix. Bạn muốn nội dung của thẻ CF của bạn bị xáo trộn một cách đáng tiếc thay vì chỉ là 0? Được rồi, sử dụng /dev/random
làm nguồn dữ liệu thay vì /dev/zero
:
$ sudo dd if=/dev/random of=/dev/sdc
Trên Linux, chúng tôi không tiếp tục phát minh lại các bánh xe như vậy bởi vì các tính năng hệ điều hành cốt lõi không chỉ hoạt động đủ tốt, chúng còn hoạt động tốt đến mức chúng được sử dụng một cách phổ biến. Một lược đồ điển hình để khởi động hộp Linux liên quan đến hình ảnh đĩa ảo, chỉ với một ví dụ, được tạo bằng các kỹ thuật như tôi hiển thị ở trên.
Tôi cảm thấy thật công bằng khi chỉ ra rằng nếu Unix đã tích hợp I / O TCP / IP vào hệ thống tập tin ngay từ đầu, chúng tôi sẽ không có netcat
vs socat
vs Ncat
vs mess , nguyên nhân là do điểm yếu thiết kế tương tự dẫn đến hình ảnh đĩa và công cụ xóa sạch phổ biến trên Windows: thiếu một cơ sở HĐH chấp nhận được.nc
Câu trả lời dài, phần 2: Các đường ống dưới dạng tệp ảo
Mặc dù có nguồn gốc từ DOS, Windows chưa bao giờ có truyền thống dòng lệnh phong phú.
Điều này không có nghĩa là Windows không có dòng lệnh hoặc nó thiếu nhiều chương trình dòng lệnh. Windows thậm chí còn có một vỏ lệnh rất mạnh mẽ ngày nay, được gọi một cách thích hợp là PowerShell .
Tuy nhiên, có những tác động kích thích của việc thiếu truyền thống dòng lệnh này. Bạn sẽ có được công cụ giống DISKPART
đó là hầu như chưa biết trong thế giới Windows, bởi vì hầu hết mọi người làm phân vùng đĩa và như vậy thông qua MMC Computer Management snap-in. Sau đó, khi bạn cần kịch bản tạo phân vùng, bạn thấy rằng điều đó DISKPART
thực sự không được điều khiển bởi một chương trình khác. Có, bạn có thể viết một loạt các lệnh vào một tệp script và chạy nó qua DISKPART /S scriptfile
, nhưng nó hoàn toàn hoặc không có gì. Những gì bạn thực sự muốn trong một tình huống như vậy là một cái gì đó giống như GNUparted
, sẽ chấp nhận các lệnh đơn như thế nào parted /dev/sdb mklabel gpt
. Điều đó cho phép tập lệnh của bạn thực hiện xử lý lỗi trên cơ sở từng bước.
Tất cả những điều này có liên quan gì đến "mọi thứ là một tập tin"? Dễ dàng: các đường ống làm cho I / O chương trình dòng lệnh thành "tập tin". Các đường ống là các luồng đơn hướng , không truy cập ngẫu nhiên như một tệp đĩa thông thường, nhưng trong nhiều trường hợp, sự khác biệt là không có kết quả. Điều quan trọng là bạn có thể đính kèm hai chương trình được phát triển độc lập và khiến chúng giao tiếp qua văn bản đơn giản. Theo nghĩa đó, bất kỳ hai chương trình được thiết kế với Unix Way trong tâm trí đều có thể giao tiếp.
Trong những trường hợp bạn thực sự cần một tệp, thật dễ dàng để biến đầu ra chương trình thành một tệp:
$ some-program --some --args > myfile
$ vi myfile
Nhưng tại sao lại ghi đầu ra vào một tệp tạm thời khi triết lý "mọi thứ là một tệp" mang đến cho bạn một cách tốt hơn? Nếu tất cả những gì bạn muốn làm là đọc đầu ra của lệnh đó vào vi
bộ đệm trình soạn thảo, vi
có thể làm điều đó trực tiếp cho bạn. Từ vi
chế độ "bình thường", nói:
:r !some-program --some --args
Điều đó chèn đầu ra của chương trình vào bộ đệm trình chỉnh sửa hoạt động ở vị trí con trỏ hiện tại. Dưới mui xe, vi
đang sử dụng các đường ống để kết nối đầu ra của chương trình với một chút mã sử dụng cùng các lệnh gọi hệ điều hành mà nó sẽ sử dụng để đọc từ một tệp thay thế. Tôi sẽ không ngạc nhiên nếu hai trường hợp :r
- nghĩa là có và không có !
- cả hai đều sử dụng cùng một vòng đọc dữ liệu chung trong tất cả các triển khai chung của vi
. Tôi không thể nghĩ ra một lý do tốt để không.
Đây cũng không phải là một tính năng gần đây của vi
; nó trở lại rõ ràng với trình ed(1)
soạn thảo văn bản cổ đại.
Ý tưởng mạnh mẽ này xuất hiện nhiều lần trong Unix.
Đối với một ví dụ thứ hai về điều này, hãy nhớ lại mutt
lệnh email của tôi ở trên. Lý do duy nhất tôi phải viết là hai lệnh riêng biệt là tôi muốn tệp tạm thời được đặt tên *.gz
, để tệp đính kèm email sẽ được đặt tên chính xác. Nếu tôi không quan tâm đến tên tệp, tôi có thể đã sử dụng thay thế quy trình để tránh tạo tệp tạm thời:
$ echo "Here's the disk image I promised to send you." |
mutt -a <(gzip -c myfs) -s "Password file disk image" you@example.com
Điều đó tránh tạm thời bằng cách chuyển đầu ra gzip -c
thành một dạng FIFO (giống như tệp) hoặc một /dev/fd
đối tượng (giống như tệp). (Bash chọn phương thức dựa trên khả năng của hệ thống, vì /dev/fd
không có sẵn ở mọi nơi.)
Đối với cách thứ ba, ý tưởng mạnh mẽ này xuất hiện trong Unix, hãy xem xét gdb
trên các hệ thống Linux. Đây là trình gỡ lỗi được sử dụng cho bất kỳ phần mềm nào được viết bằng C và C ++. Các lập trình viên đến với Unix từ các hệ thống khác nhìn vào gdb
và gần như luôn luôn nắm bắt về nó, "Yuck, nó rất nguyên thủy!" Sau đó, họ đi tìm kiếm một trình gỡ lỗi GUI, tìm thấy một trong số đó tồn tại và vui vẻ tiếp tục công việc của mình ... thường không bao giờ nhận ra rằng GUI chỉ chạy gdb
bên dưới, cung cấp một lớp vỏ đẹp ở trên nó. Không có trình gỡ lỗi cấp thấp cạnh tranh trên hầu hết các hệ thống Unix vì không cần chương trình để cạnh tranh ở cấp đó. Tất cả những gì chúng ta cần là một công cụ cấp thấp tốt mà tất cả chúng ta đều có thể dựa trên các công cụ cấp cao của mình, nếu công cụ cấp thấp đó giao tiếp dễ dàng qua đường ống.
Điều này có nghĩa là chúng ta hiện có một giao diện trình gỡ lỗi được ghi thành tài liệu cho phép thay thế thả vào gdb
, nhưng thật không may, đối thủ cạnh tranh chính gdb
không đi theo con đường ma sát thấp .
Tuy nhiên, ít nhất có thể một số gdb
thay thế trong tương lai sẽ giảm trong suốt chỉ bằng cách nhân bản giao diện dòng lệnh của nó. Để loại bỏ điều tương tự trên hộp Windows, những người tạo ra công cụ có thể thay thế sẽ phải xác định một số loại plugin chính thức hoặc API tự động hóa. Điều đó có nghĩa là điều đó không xảy ra ngoại trừ các chương trình phổ biến nhất, bởi vì rất nhiều công việc để xây dựng cả giao diện người dùng dòng lệnh thông thường và API lập trình hoàn chỉnh.
Phép thuật này xảy ra thông qua ân sủng của IPC dựa trên văn bản phổ biến .
Mặc dù nhân của Windows có các đường dẫn ẩn danh kiểu Unix , nhưng hiếm khi thấy các chương trình người dùng bình thường sử dụng chúng cho IPC bên ngoài vỏ lệnh, vì Windows thiếu truyền thống tạo tất cả các dịch vụ cốt lõi trong phiên bản dòng lệnh, sau đó xây dựng GUI trên đầu của nó một cách riêng biệt. Điều này dẫn đến việc không thể thực hiện một số thứ nếu không có GUI, đó là một lý do tại sao có rất nhiều hệ thống máy tính để bàn từ xa cho Windows, so với Linux: Windows rất khó sử dụng nếu không có GUI.
Ngược lại, việc quản lý từ xa các hộp Unix, BSD, OS X và Linux từ xa thông qua SSH. Và làm thế nào để làm việc đó, bạn yêu cầu? SSH kết nối một ổ cắm mạng (giống như tệp) với một giả giả tại /dev/pty*
(giống như tệp). Bây giờ hệ thống từ xa của bạn được kết nối với hệ thống cục bộ của bạn thông qua một kết nối hoàn toàn khớp với Cách thức Unix mà bạn có thể dẫn dữ liệu qua kết nối SSH , nếu bạn cần.
Bạn có nhận được một ý tưởng về việc khái niệm này mạnh mẽ như thế nào bây giờ?
Một luồng văn bản được phân biệt không thể phân biệt được từ một tệp từ góc độ của chương trình, ngoại trừ việc nó là một hướng. Một chương trình đọc từ một đường ống giống như cách nó đọc từ một tệp: thông qua một bộ mô tả tệp . FD hoàn toàn là cốt lõi của Unix; thực tế là các tệp và đường ống sử dụng cùng một sự trừu tượng hóa cho cả I / O trên cả hai sẽ cho bạn biết điều gì đó.⁹
Thế giới Windows, thiếu truyền thống giao tiếp văn bản đơn giản này, thực hiện với các giao diện OOP nặng thông qua COM hoặc .NET . Nếu bạn cần tự động hóa một chương trình như vậy, bạn cũng phải viết chương trình COM hoặc .NET. Đây là một chút khó khăn hơn so với việc thiết lập một đường ống trên một hộp Unix.
Các chương trình Windows thiếu các API lập trình phức tạp này chỉ có thể giao tiếp thông qua các giao diện nghèo nàn như bảng tạm hoặc Tệp / Lưu theo sau là Tệp / Mở.
Câu trả lời dài, phần 3: Sổ đăng ký và tập tin cấu hình
Sự khác biệt thực tế giữa Windows registry và cấu hình hệ thống Unix cũng minh họa lợi ích của triết lý "mọi thứ là một tập tin".
Trên các hệ thống loại Unix, tôi có thể xem thông tin cấu hình hệ thống từ dòng lệnh chỉ bằng cách kiểm tra các tệp. Tôi có thể thay đổi hành vi hệ thống bằng cách sửa đổi các tệp tương tự. Đối với hầu hết các phần, các tệp cấu hình này chỉ là các tệp văn bản thuần, có nghĩa là tôi có thể sử dụng bất kỳ công cụ nào trên Unix để thao tác chúng có thể hoạt động với các tệp văn bản thuần túy.
Viết kịch bản đăng ký không phải là quá dễ dàng trên Windows.
Phương pháp đơn giản nhất là thực hiện các thay đổi của bạn thông qua GUI Editor Editor trên một máy, sau đó áp dụng một cách mù quáng những thay đổi đó cho các máy khác regedit
thông qua *.reg
các tệp . Đó không thực sự là "kịch bản", vì nó không cho phép bạn làm bất cứ điều gì có điều kiện: đó là tất cả hoặc không có gì.
Nếu các thay đổi đăng ký của bạn cần bất kỳ số lượng logic nào, tùy chọn dễ nhất tiếp theo là tìm hiểu PowerShell , về cơ bản là tương đương với việc học lập trình hệ thống .NET. Nó sẽ giống như nếu Unix chỉ có Perl và bạn phải thực hiện tất cả quản trị hệ thống ad hoc thông qua nó. Bây giờ, tôi là một người hâm mộ Perl, nhưng không phải ai cũng vậy. Unix cho phép bạn sử dụng bất kỳ công cụ nào bạn thích, miễn là nó có thể thao tác các tệp văn bản thuần túy.
Chú thích:
Plan 9 cố định sai lầm thiết kế này, phơi bày mạng I / O thông qua các /net
hệ thống tập tin ảo .
Bash có một tính năng được gọi là/dev/tcp
cho phép I / O mạng thông qua các chức năng hệ thống tập tin thông thường. Vì nó là một tính năng Bash, thay vì một tính năng kernel, nó không hiển thị bên ngoài Bash hoặc trên các hệ thống hoàn toàn không sử dụng Bash . Điều này cho thấy, bằng ví dụ, tại sao nó là một ý tưởng tốt để làm cho tất cả các tài nguyên dữ liệu hiển thị thông qua hệ thống tập tin.
Theo "Windows hiện đại", ý tôi là Windows NT và tất cả các hậu duệ trực tiếp của nó, bao gồm Windows 2000, tất cả các phiên bản Windows Server và tất cả các phiên bản Windows hướng máy tính để bàn từ XP trở đi. Tôi sử dụng thuật ngữ này để loại trừ các phiên bản Windows dựa trên DOS, là Windows 95 và hậu duệ trực tiếp của nó, Windows 98 và Windows ME, cộng với các phiên bản tiền nhiệm 16 bit của chúng.
Bạn có thể thấy sự khác biệt bởi việc thiếu một hệ thống I / O thống nhất trong các HĐH sau này. Bạn không thể truyền ổ cắm TCP / IP cho ReadFile()
Windows 95; bạn chỉ có thể chuyển ổ cắm cho API của Windows Sockets. Xem bài báo chuyên đề của Andrew Schulman, Windows 95: Điều gì không phải để đi sâu hơn vào chủ đề này.
Đừng nhầm lẫn, /dev/null
là một thiết bị hạt nhân thực sự trên các hệ thống loại Unix, không chỉ là một tên tệp có vỏ bọc đặc biệt, như là tương đương bề ngoài NUL
trong Windows.
Mặc dù Windows cố gắng ngăn bạn tạo một NUL
tệp, nhưng có thể bỏ qua sự bảo vệ này bằng thủ thuật đơn thuần , đánh lừa logic phân tích tên tệp của Windows. Nếu bạn cố truy cập tệp đó bằng cmd.exe
hoặc Explorer, Windows sẽ từ chối mở tệp đó, nhưng bạn có thể ghi vào tệp đó qua Cygwin, vì nó mở tệp bằng các phương thức tương tự với chương trình ví dụ và bạn có thể xóa tệp đó thông qua thủ thuật tương tự .
Ngược lại, Unix sẽ vui vẻ cho phép bạn rm /dev/null
, miễn là bạn có quyền truy cập ghi /dev
và cho phép bạn tạo lại một tệp mới ở vị trí của nó, tất cả đều không có mánh khóe, bởi vì nút dev chỉ là một tệp khác. Trong khi nút dev bị thiếu, thiết bị null của kernel vẫn tồn tại; nó chỉ không thể truy cập cho đến khi bạn tạo lại nút dev thông qua mknod
.
Bạn thậm chí có thể tạo thêm các nút dev thiết bị null ở nơi khác: không thành vấn đề nếu bạn gọi nó /home/grandma/Recycle Bin
, miễn là nó là nút dev cho thiết bị null, nó sẽ hoạt động chính xác như /dev/null
.
Thực tế, có hai API "định dạng đĩa" cấp cao trong Windows: SHFormatDrive()
và Win32_Volume.Format()
.
Có hai lý do rất ... à ... Windows . Người đầu tiên yêu cầu Windows Explorer hiển thị hộp thoại "Format Disk" bình thường, có nghĩa là nó hoạt động trên mọi phiên bản Windows hiện đại, nhưng chỉ khi người dùng đăng nhập tương tác. Người khác bạn có thể gọi trong nền mà không cần người dùng nhập, nhưng nó không được thêm vào Windows cho đến Windows Server 2003. Đúng vậy, hành vi cốt lõi của hệ điều hành đã bị ẩn sau GUI cho đến năm 2003, trong một thế giới nơi Unix xuất xưởng mkfs
từ ngày 1 .
Tôi bản sao của Unix V5 từ năm 1974 bao gồm /etc/mkfs
, một 4136 byte tĩnh liên kết PDP-11 thực thi. (Unix đã không nhận được liên kết động cho đến cuối những năm 1980 , do đó, không giống như có một thư viện lớn ở nơi khác làm tất cả công việc thực sự.) Mã nguồn của nó - được bao gồm trong hình ảnh hệ thống V5 như /usr/source/s2/mkfs.c
- hoàn toàn khép kín 457- chương trình dòng C. Thậm chí không có bất kỳ #include
tuyên bố nào !
Điều này có nghĩa là bạn không chỉ kiểm tra những gì mkfs
ở mức cao, bạn có thể thử nghiệm nó bằng cách sử dụng cùng một bộ công cụ mà Unix đã tạo ra, giống như bạn là Ken Thompson , bốn thập kỷ trước. Hãy thử điều đó với Windows. Cách gần nhất bạn có thể đến hôm nay là tải xuống mã nguồn DOS , được phát hành lần đầu tiên vào năm 2014 , mà bạn tìm thấy số tiền chỉ bằng một đống nguồn lắp ráp . Nó sẽ chỉ được xây dựng với các công cụ lỗi thời mà bạn có thể sẽ không có trong tay, và cuối cùng bạn sẽ có được bản sao DOS 2.0 của riêng mình, một hệ điều hành kém mạnh mẽ hơn so với Unix V5 năm 1974 , mặc dù đã được phát hành gần một thập kỷ sau đó.
(Tại sao nói về Unix V5? Bởi vì nó là hệ thống Unix hoàn thành sớm vẫn có sẵn. Phiên bản trước được rõ ràng mất thời gian . Có một dự án mà ráp lại với nhau một V1 / V2 kỷ nguyên Unix, nhưng nó dường như mất tích mkfs
, mặc dù sự tồn tại của trang hướng dẫn V1 được liên kết ở trên chứng tỏ nó phải tồn tại ở đâu đó, đôi khi. Những người đặt dự án này cùng nhau không thể tìm thấy một bản sao còn lại mkfs
để bao gồm, hoặc tôi không tìm thấy các tệp mà find(1)
không tồn tại trong hệ thống đó . :)
)
Bây giờ, bạn có thể nghĩ, "Tôi không thể gọi format.com
à? Không phải trên Windows cũng giống như gọi mkfs
trên Unix sao?" Than ôi, không, nó không giống nhau, vì một loạt các lý do:
Đầu tiên, format.com
không được thiết kế để được viết kịch bản. Nó sẽ nhắc bạn "nhấn ENTER khi sẵn sàng", điều đó có nghĩa là bạn cần gửi một phím Enter đến đầu vào của nó, hoặc nó sẽ bị treo.
Sau đó, nếu bạn muốn bất cứ điều gì ngoài mã trạng thái thành công / thất bại, bạn phải mở đầu ra tiêu chuẩn của nó để đọc, điều này phức tạp hơn nhiều so với Windows . (Trên Unix, mọi thứ trong bài viết được liên kết đó có thể được thực hiện bằng một popen(3)
cuộc gọi đơn giản .)
Đã trải qua tất cả các biến chứng này, đầu ra của format.com
các chương trình máy tính khó phân tích hơn so với đầu ra của mkfs
, chủ yếu dành cho tiêu dùng của con người.
Nếu bạn theo dõi những gì format.com
không, bạn thấy rằng nó làm một loạt các cuộc gọi phức tạp để DeviceIoControl()
, ufat.dll
và như vậy. Nó không chỉ đơn giản là mở một tệp thiết bị và viết một hệ thống tệp mới vào thiết bị đó. Đây là loại thiết kế bạn nhận được từ một công ty sử dụng 126000 người và cần tiếp tục sử dụng chúng.
Khi nói về các thiết bị lặp, tôi chỉ nói về Linux chứ không phải Unix nói chung vì các thiết bị lặp không có khả năng di động giữa các hệ thống loại Unix. Có các cơ chế tương tự trong OS X, BSD, v.v., nhưng cú pháp có phần khác nhau .
Quay trở lại thời mà ổ đĩa có kích thước bằng máy giặt và có giá cao hơn xe hơi hạng sang của bộ phận, các phòng máy tính lớn sẽ chia sẻ tỷ lệ không gian đĩa tập thể lớn hơn so với môi trường máy tính hiện đại. Khả năng ghép trong suốt một đĩa từ xa vào hệ thống tệp cục bộ làm cho các hệ thống phân tán như vậy dễ sử dụng hơn nhiều. Đây là nơi chúng tôi nhận được /usr/share
, ví dụ.
Tương phản Windows, trong đó một đĩa từ xa thường được ánh xạ tới ký tự ổ đĩa hoặc phải được truy cập thông qua đường dẫn UNC, thay vì được tích hợp trong suốt vào hệ thống tệp cục bộ. Các ký tự ổ đĩa cung cấp cho bạn một số lựa chọn cho biểu thức tượng trưng; có P:
đề cập đến không gian "công khai" trên BigServer hoặc thư mục "gói" trên máy chủ nhân bản phần mềm không? Đường dẫn UNC có nghĩa là bạn phải nhớ máy chủ từ xa đang bật máy chủ nào, điều này gây khó khăn trong một tổ chức lớn với hàng trăm hoặc hàng nghìn máy chủ tệp.
Windows đã không nhận được liên kết tượng trưng cho đến khi Windows Vista, phát hành năm 2007, giới thiệu các liên kết tượng trưng NTFS . Các liên kết tượng trưng của Windows mạnh hơn một chút so với các liên kết tượng trưng của Unix - một tính năng của Unix kể từ năm 1977 - ở chỗ chúng cũng có thể trỏ đến chia sẻ tệp từ xa, không chỉ là đường dẫn cục bộ. Unix đã làm điều đó một cách khác biệt, thông qua NFS vào năm 1984 , được xây dựng dựa trên tính năng điểm gắn kết có sẵn của Unix , mà nó đã có từ đầu.
Vì vậy, tùy thuộc vào cách bạn nhìn vào nó, Windows kéo theo Unix khoảng 2 hoặc 3 thập kỷ.
Ngay cả khi đó, các liên kết tượng trưng không phải là một phần bình thường trong trải nghiệm của người dùng Windows, vì một vài lý do.
Đầu tiên, bạn chỉ có thể tạo chúng bằng chương trình dòng lệnh ngượcMKLINK
. Bạn không thể tạo chúng từ Windows Explorer, trong khi các khoản tương đương Unix Windows Explorer thường làm phép bạn tạo các liên kết tượng trưng.
Thứ hai, cấu hình Windows mặc định ngăn người dùng bình thường tạo các liên kết tượng trưng, yêu cầu bạn chạy shell lệnh với tư cách Quản trị viên hoặc cấp cho người dùng quyền tạo chúng thông qua một đường dẫn tối nghĩa trong một công cụ mà người dùng trung bình của bạn chưa từng thấy, ít biết Cách sử dụng. (Và không giống như hầu hết các vấn đề đặc quyền của Quản trị viên trong Windows, UAC không giúp ích gì trong trường hợp này.)
Các hộp Linux không phải lúc nào cũng sử dụng hình ảnh đĩa ảo trong chuỗi khởi động. Có một loạt các cách khác nhau để làm điều đó .
man ed
Nhân tiện, các mô tả ổ cắm mạng cũng là các FD bên dưới.