Python Stuff I Do in My Free Time

Bài này để mình ghi chú lại một số project Python nhỏ mà mình làm trong thời gian rảnh (thực ra là cũng không rảnh lắm chỉ là mình không thích đi học), mục đích là để không quên đi cách code cũng như cách suy nghĩ trong thời đại AI ngày càng mạnh : D mặc dù sau bài này thì mình cũng vibe coding thôi nhưng tất nhiên việc mình đang làm sẽ có ý nghĩa của riêng nó (ít nhất là đối với mình)

Directory Viewer

Project của ta, tạm gọi là treex, sẽ là một Directory Viewer. Vậy Directory Viewer là gì? Nó sẽ làm những gì?

Trên Linux thì ta đã quen với tree, cũng là một công cụ dòng lệnh hỗ trợ hiển thị cấu trúc thư mục theo dạng cây.

Ví dụ như sau:

❯ pwd
/home/dvck13/Desktop/CTF/htb
❯ tree
.
├── meow
│   └── starting_points_us-starting-point-2-dhcp.ovpn
└── oopsie
    ├── a.exe
    ├── backup.zip
    ├── hash.txt
    ├── hash.txt.1
    ├── index.php
    ├── msssqlclient.py
    ├── nc64.exe
    ├── php-reverse-shell.php
    ├── prod.dtsConfig
    ├── starting_points_eu-starting-point-vip-1-dhcp.ovpn
    ├── style.css
    └── wordlist.txt

3 directories, 13 files

Ok và bây giờ mình muốn làm điều tương tự với Python. Trong Python có một module giúp ta thao tác với các thư mục và file, đó là pathlib. Tài liệu chi tiết về thư viện.

Trước khi bắt đầu ta cần có cái nhìn tổng quan về filesystem trên hệ điều hành Linux.

File system được dùng để quản lý cách dữ liệu được đọc và lưu trên thiết bị. Nó cho phép người dùng truy cập nhanh chóng và an toàn khi cần thiết.

Cái ta cần quan tâm đến ở đây đó là Filesystem Hierarchy Standard (FHS) - tiêu chuẩn phân cấp hệ thống tập tin. Nó định nghĩa cấu trúc thư mục và nội dung của các thư mục trong hệ điều hành Linux.

Ví dụ cấu trúc cây thư mục trong Linux như sau:

❯ pwd
/
❯ ls
afs   builddir  home   lib64  opt   run   sniper  tmp  workspace
bin   dev       image  media  proc  sbin  srv     usr
boot  etc       lib    mnt    root  snap  sys     var

Linux dùng ký tự / để phân tách các thư mục và file, khác với Windows dùng ký tự \.

Đầu tiên ta có / là thư mục gốc (root directory), chứa tất cả các thư mục và file khác. Ta có thể điều hướng đến thư mục này bằng cách gõ cd /

Một số thư mục quan trọng trong Linux và đặc tả của nó:

Thư mụcMô tả
/binChứa các lệnh cơ bản của hệ thống
/sbinChứa các lệnh quản trị hệ thống
/libChứa các thư viện cần thiết cho hệ thống và chương trình
/homeThư mục cá nhân của người dùng
/usrChứa ứng dụng, thư viện và tài nguyên dùng chung
/optChứa phần mềm bên thứ ba
/etcChứa các tệp cấu hình hệ thống
/varChứa dữ liệu thường xuyên thay đổi như log, cache
/devChứa các tệp đại diện cho thiết bị
/procFilesystem ảo cung cấp thông tin về kernel và tiến trình
/sysFilesystem ảo cung cấp thông tin về thiết bị và kernel
/tmpChứa các tệp tạm thời
/bootChứa các tệp cần thiết cho quá trình khởi động
/rootThư mục cá nhân của người dùng root
/mntĐiểm mount tạm thời cho các filesystem

Còn về đường dẫn trên Linux thì sẽ có hai loại đường dẫn đó là đường dẫn tương đối và đường dẫn tuyệt đối.

Đường dẫn tuyệt đối của một tệp tin hay thư mục đều bắt đầu bởi thư mục gốc / và theo cây, theo nhánh cho đến thư mục hoặc tệp mà ta mong muốn. Ví dụ muốn chuyển vào thư mục /usr/bin thì ta có thể gõ đường dẫn tuỵệt đối của nó ra cd /usr/bin.

Đường dẫn tương đối thì không bắt buộc ta bắt đầu bằng root / mà có thể tiếp cận các thư mục hay tệp tin khác từ bên trong thư mục hiện hành. Để làm được việc này thì Linux cung cấp cho ta hai kí hiệu . để chỉ thư mục hiện hành và .. để chỉ thư mục mẹ của thư mục hiện hành.

Ví dụ ta đang đứng ở /home và muốn vào usr/bin thì có thể gõ cd ../../usr/bin hoặc cd /usr/bin đều được.

Dài dòng vậy là đủ, bây giờ ta bắt thay vào code từng phần của chương trình.

Tính năng đầu tiên mình muốn thử đó là làm sao nó list ra các file và thư mục đang có ở thư mục hiện hành trước tiên chỉ với một lần chạy, kiểu như python3 treex.py thì nó sẽ list ra các file và thư mục đang có trong thư mục hiện hành. Sau đó mới bắt đầu thêm vào các tính năng như truyền tham số (bằng argparse).

Một số note về thư viện:

  • Module cho ta các class để làm việc với đường dẫn tùy theo hệ điều hành của hệ thống. Có hai class chính là pure paths và concrete paths. Ở đây ta không cần quan tâm tới điểm khác nhau giữa chúng mà ta chỉ cần sử dụng Path trong pathlib là đủ. Khi gọi Path thì nó sẽ tự động chọn class phù hợp với hệ điều hành của hệ thống mà ta đang sử dụng (và sẽ đồng thời là concrete path).

  • Về argparse, khi sử dụng method add_argument() thì ta cần phân biệt giữa optional argument và positional argument. Optional argument là các tham số mà người dùng có thể không truyền vào khi chạy chương trình, còn positional argument là các tham số mà người dùng bắt buộc phải truyền vào khi chạy chương trình. Đối với đường dẫn thì ta nên sử dụng positional argument và optional argument ta sẽ để dành cho các tính năng sau.

import pathlib 
import argparse 
import os 

parser = argparse.ArgumentParser(description='Enter path name or using the current directory')
parser.add_argument('pathname', nargs = '?')

args = parser.parse_args() 

try: 
    if args.pathname is not None: 
        path = pathlib.Path(args.pathname)
    else:
        path = pathlib.Path.cwd()
    if not path.exists():
        raise FileNotFoundError(f"The path {path} does not exist.")
    if not path.is_dir():
        raise NotADirectoryError(f"The path {path} is not a directory.")
except:
    print('Invalid path')
    exit(1) 
print(path)
  • Trong pathlib có cả Path.absolute() và Path.resolve(). Cả hai đều trả về đường dẫn tuyệt đối của một tệp tin hay thư mục, nhưng Path.resolve() còn giải quyết các symbolic links và các phần tử . và .. trong đường dẫn. Còn Path.absolute() chỉ đơn giản là trả về đường dẫn tuyệt đối mà không giải quyết các liên kết tượng trưng hay các phần tử . và ...

Test:

❯ python3 treex.py ~
/home/dvck13
❯ python3 treex.py
/home/dvck13/Desktop/pet/treex
❯ python3 treex.py ~//Desktop/CTF
/home/dvck13/Desktop/CTF
 

dvck13

Math, Cryptography and CTF


2026-09-20


On this page: