Theo thời gian, hầu hết những người đam mê Linux đều tích lũy một kho chiến tranh lấp lánh chứa đầy những thủ thuật khó thắng có thể cực kỳ hữu ích khi một tình huống đòi hỏi sự suy nghĩ nhanh chóng ở thiết bị đầu cuối của bạn. Tôi đã cất giữ rất nhiều kiến thức trong số này qua nhiều năm và bất cứ khi nào tôi có cơ hội để trông chừng một người nào đó đặc biệt thành thạo với Linux.
Hôm nay, bạn đang ghép nối với tôi ở nhà ga. Chúng tôi đang khám phá chiều sâu của hệ thống tệp Linux và các công cụ cũng như thủ thuật.
/proc
với tôi Một trong những thư mục hữu ích nhất trong hệ thống Linux là /proc
. Từ trang man
cho proc
:
Hệ thống tệp proc là một hệ thống tệp giả cung cấp giao diện cho cấu trúc dữ liệu nhân.
Khi trang man
nói "hệ thống tệp giả", điều đó có nghĩa là nếu bạn nhìn vào bên dưới đĩa của mình, nơi bạn có thể mong đợi tìm thấy các bit đại diện cho một tệp giống như bạn làm đối với tệp văn bản tại /tmp/launch-codes.txt
, thì có không có gì tại /proc
. Nó hiện diện và tồn tại trên một hệ thống Linux đang chạy, nhưng hoàn toàn không có nếu bạn kéo đĩa ra và kiểm tra nó. /proc
một bảng điều khiển cho hạt nhân đang chạy của bạn!
Nếu bạn xem xét /proc
của riêng mình ngay bây giờ, bạn có thể tìm thấy rất nhiều thư mục như sau:
ls /proc
1 10 10021 10059 10144 ...hundreds more files...
Mỗi số đó đại diện cho một ID quy trình hoặc PID
- vâng, chính PID
đó xác định quy trình cho trình duyệt hoặc chương trình đầu cuối của bạn. Trên thực tế, bạn có thể thẩm vấn rất nhiều thông tin về chính quá trình này. Ví dụ: bạn có thể nhớ lại rằng quy trình 1
trên hệ thống Linux theo truyền thống là quy trình init
cấp cao nhất, trong hầu hết các hệ thống hiện đại là dựa trên systemd. Hãy xem lệnh khởi động PID 1
trên hệ thống của tôi:
cat /proc/1/cmdline
/run/current-system/systemd/lib/systemd/systemd
cmdline
là một tệp cho chúng ta biết lệnh khởi động quy trình 1
- trong trường hợp này là chính systemd
.
Có một tệp cmdline
trong /proc
đặc biệt hữu ích - /proc/cmdline
, thực sự hiển thị cho bạn các đối số được truyền vào chính hạt nhân của bạn tại thời điểm khởi động. Của tôi rất dài dòng, nhưng cho tôi biết initrd
mà hệ thống của tôi đã khởi động cùng với bất kỳ cờ nào khác, trong trường hợp của tôi là init
và loglevel
:
cat /proc/cmdline
initrd=\efi\nixos\hx5g5rmvq748m64r32yjmpjk3pmgqmr1-initrd-linux-5.17.11-initrd.efi init=/nix/store/9zvklk45yx41pak2hdxsxmmnq12n712k-nixos-system-diesel-22.05.20220604.d9794b0/init loglevel=4
Tên máy chủ NixOS của tôi là diesel
. Xin lưu ý rằng tôi không để xăng dầu trong máy tính xách tay của mình.
/proc
cũng không chỉ đọc. Giống như trang người của nó đã nói, /proc
là một giao diện với hạt nhân, bao gồm việc tương tác với chính hạt nhân. Thư mục /proc/sys
chứa nhiều nút và quay số, nhưng tôi muốn cho bạn thấy /proc/sys/vm
, cho phép chúng ta xem qua bộ nhớ ảo của hạt nhân. Muốn mạo hiểm hơn?
Xem xét mức sử dụng bộ nhớ hiện tại của máy tôi.
free -h
total used free shared buff/cache available Mem: 31Gi 22Gi 3.0Gi 4.4Gi 5.6Gi 3.6Gi Swap: 31Gi 130Mi 31Gi
Không có gì quá bất thường ở đây - nhưng nếu tôi muốn giải phóng bộ nhớ của mình một cách tích cực thì sao? Hầu hết thời gian, hạt nhân biết rõ nhất khi sử dụng bộ nhớ để lưu vào bộ nhớ đệm, nhưng có một số tình huống mà bạn có thể muốn xóa bất kỳ bộ nhớ nào an toàn để xóa - chúng tôi không muốn phá vỡ bất kỳ quá trình đang chạy nào, chỉ lấy lại bộ nhớ nếu có thể.
Nó chỉ ra rằng có một tập tin cho điều đó. Chúng tôi đưa một lệnh echo
vào sudo tee
vì /proc/sys/vm
thường được bảo vệ chống ghi và chỉ người root
mới có thể ghi vào tệp mà chúng tôi quan tâm.
echo 1 | sudo tee -a /proc/sys/vm/drop_caches
Những gì lệnh này thực hiện là tín hiệu hiệu quả cho hạt nhân, "vui lòng xóa bất kỳ bộ nhớ đệm nào trong bộ nhớ mà bạn có thể để mất mà không phá vỡ bất kỳ tiến trình đang chạy nào trên hệ thống của tôi." Trên máy của tôi, điều này mở ra khoảng 500M bộ nhớ:
total used free shared buff/cache available Mem: 31Gi 22Gi 3.5Gi 4.4Gi 5.1Gi 3.6Gi Swap: 31Gi 130Mi 31Gi
Mát mẻ! Có tất cả các loại đối tượng giống tệp hữu ích trong /proc
có thể làm những điều thú vị như thế này. Hãy mở man proc
nếu bạn muốn tìm hiểu thêm.
/dev
như một curl
thời tiền sử Một thiết bị ký tự như /dev/sda
đại diện cho một đĩa đính kèm, nhưng có một cách sử dụng khác cho đường dẫn /dev
: một cách ít được biết đến để gửi các yêu cầu mạng.
Đường dẫn /dev/tcp
thực sự không phải là một thiết bị giống như tệp được hiển thị bởi nhân Linux, mà thực sự là một tính năng của trình bao bạn đã chọn như bash
. Vỏ có thể chặn các hoạt động trên đường dẫn này để mở ra các kết nối ổ cắm cấp thấp tới các thiết bị đầu cuối từ xa như máy chủ web đang nghe trên cổng 80
.
Để bắt đầu, hãy mở bộ mô tả tệp mới được kết nối với đường dẫn tệp trong /dev/tcp
cho biết điểm cuối và cổng mong muốn. Giống như cách các số 0, 1 và 2 của bộ mô tả tệp lần lượt đại diện cho stdin
, stdout
và stderr
, bạn có thể coi bộ mô tả tệp 3 mới này như đại diện cho một đường ống dẫn đến một điểm cuối mạng từ xa. Chúng tôi sẽ giả sử việc sử dụng bash
từ đây trở đi.
exec 3<>/dev/tcp/httpbin.org/80
Tiếp theo, gửi dạng bản rõ của một yêu cầu HTTP đơn giản đến bộ mô tả tệp đang mở. Yêu cầu GET
tới /status/200
này cũng yêu cầu tiêu đề Host
phải được đặt để được hầu hết các proxy ngược xử lý đúng cách. Hai dòng mới báo hiệu kết thúc yêu cầu:
echo -e "GET /status/200 HTTP/1.1\r\nHost: httpbin.org\r\n\r\n" >&3
Cuối cùng, một thao tác đọc đơn giản sẽ truy xuất phản hồi HTTP:
cat <&3
Bạn sẽ thấy một phản hồi tương tự như bên dưới:
HTTP/1.1 200 OK Date: Fri, 10 Jun 2022 21:39:43 GMT Content-Type: text/html; charset=utf-8 Content-Length: 0 Connection: keep-alive Server: gunicorn/19.9.0 Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: true
Xin chúc mừng! Bạn vừa gửi một yêu cầu HTTP không sử dụng gì ngoài trình bao của bạn.
/sys
Có một thư mục cấp gốc nữa để khám phá sau khi tìm hiểu sâu vào /proc
và /dev
: thư mục enigmatic /sys
.
Giống như /proc
và /dev
, /sys
là một giao diện giống tệp khác với các cơ chế cấp thấp nằm rất gần với hệ điều hành. Không giống như /proc
- tương đối tập trung vào quy trình - và /dev
- mô hình khối các thiết bị và hơn thế nữa - /sys
là một giao diện hữu ích cho nhiều phần trừu tượng mà nhân mô hình.
Ví dụ: lấy thư mục /sys/class/net
. Bên trong thư mục này, bạn sẽ tìm thấy danh sách các liên kết đại diện cho các giao diện mạng trên máy chủ của bạn. Đây là những gì tôi trông giống như:
ls /sys/class/net
enp0s20f0u6u4u1 lo tailscale0 wlan0
Như bạn có thể thấy, các kết nối mạng đang hoạt động mà hệ thống của tôi đang quản lý bao gồm giao diện có dây (giao diện bắt đầu bằng en
), giao diện lo
loopback, giao diện Tailscale và giao diện không dây của tôi wlan0
. Liệt kê nội dung của một trong những thư mục này cho thấy một danh sách dài các tệp, nhưng chúng ta hãy xem xét kỹ hơn hai tệp đặc biệt cho giao diện mạng có dây của tôi:
cat /sys/class/net/enp0s20f0u6u4u1/statistics/rx_bytes cat /sys/class/net/enp0s20f0u6u4u1/statistics/tx_bytes
11281235262 274308842
Mỗi tệp này đại diện cho số byte nhận và byte truyền, tương ứng. Kiểm tra cách các con số thay đổi nếu tôi sử dụng lệnh tương tự vài giây sau:
cat /sys/class/net/enp0s20f0u6u4u1/statistics/rx_bytes cat /sys/class/net/enp0s20f0u6u4u1/statistics/tx_bytes
11289633209 274760138
Con số lớn hơn! Rõ ràng là tôi đang tận dụng tối đa băng thông của mình. Làm thế nào là điều này hữu ích?
Bạn đã bao giờ thắc mắc các widget sử dụng mạng được viết như thế nào chưa? Chà, làm thế nào về việc làm của riêng bạn?
Kiểm tra tập lệnh bash
nhỏ này sử dụng các tệp nói trên trong thư mục statistics
để tính tỷ lệ hoạt động mạng.
interval=1 interface=$1 rx_bytes=$(cat /sys/class/net/$interface/statistics/rx_bytes) tx_bytes=$(cat /sys/class/net/$interface/statistics/tx_bytes) rx_bytes_rate=0 tx_bytes_rate=0 function fmt() { numfmt --to=iec-i --suffix=B $1 } while true do echo -en " $(fmt $tx_bytes_rate)/s ⬆ $(fmt $rx_bytes_rate)/s ⬇\t\r" sleep $interval old_rx_bytes=$rx_bytes old_tx_bytes=$tx_bytes rx_bytes=$(cat /sys/class/net/$interface/statistics/rx_bytes) tx_bytes=$(cat /sys/class/net/$interface/statistics/tx_bytes) tx_bytes_rate=$(( ($tx_bytes - $old_tx_bytes) / $interval )) rx_bytes_rate=$(( ($rx_bytes - $old_rx_bytes) / $interval )) done
Bạn có thể đặt tập lệnh này ở đâu đó trong $PATH
của mình, làm cho nó thực thi được với chmod +x <script>
và dùng thử với script.sh <interface name>
. Đây là kết quả đầu ra trên máy của tôi:
13KiB/s ⬆ 379KiB/s ⬇
Điều đó khá tuyệt! Bạn có thể hình dung một số cách sử dụng cho việc này: ví dụ, như một tiện ích cho một công cụ có thể hiển thị đầu ra lệnh hoặc như một cách nhanh chóng để xem hoạt động mạng cho một giao diện mạng cụ thể. Trong cả hai trường hợp, giao diện dựa trên tệp cho dữ liệu này giúp việc truy cập và sử dụng nó trở nên dễ dàng một cách đặc biệt.
Đây chỉ là một phần nhỏ đi sâu vào các loại thông tin có sẵn cho bạn khi bạn tìm hiểu sâu hơn về các khả năng của một hệ thống Linux hiện đại. Bạn có thể tìm kiếm các hướng dẫn bổ sung như hướng dẫn này hoặc truy cập thẳng vào nguồn bằng cách đọc các trang man
cho các mục nhập như man hier
để đọc chức năng và mục đích của các thư mục khác nhau trong /
.
Hãy khám phá vui vẻ!