Thứ Sáu, 27 tháng 12, 2019

Hướng dẫn dùng lệnh WHICH trong Linux

Binary và đường dẫn

Khi bạn cố chạy một chương trình hoặc lệnh từ cửa sổ Terminal, shell (thường là Bash trên các bản phân phối hiện đại) phải tìm lệnh đó và khởi chạy nó. Một số lệnh, chẳng hạn như cdhistory và pwd, được tích hợp vào shell, vì vậy Bash không mất nhiều công sức để tìm ra chúng.

Nhưng làm thế nào để Bash định vị những lệnh, chương trình và các binary độc lập bên ngoài khác? Bash sử dụng đường dẫn, chính xác là một tập hợp các đường dẫn, mỗi cái dẫn đến một thư mục. Sau đó, nó tìm kiếm từng thư mục để đưa ra file thực thi phù hợp với lệnh hoặc chương trình mà bạn đang cố gắng chạy. Khi tìm thấy một file phù hợp, Bash sẽ khởi chạy nó và từ bỏ tìm kiếm.
Bạn có thể sử dụng echo để kiểm tra biến môi trường $PATH và xem các thư mục trong đường dẫn. Để làm như vậy, hãy nhập như sau, rồi nhấn Enter:
echo $PATH
Bạn có thể sử dụng echo để kiểm tra biến môi trường $PATH
Danh sách đầu ra phân tách từng đường dẫn bằng dấu hai chấm (:). Trên máy tính mà bài viết sử dụng, Bash sẽ tìm kiếm các thư mục theo thứ tự sau:
  • /usr/local/sbin
  • /usr/local/bin
  • /usr/sbin
  • /usr/bin
  • /sbin
  • /bin
  • /user/games
  • /usr/local/games
  • /snap/bin
Có nhiều thư mục được gọi là /sbin và /bin trong hệ thống file, điều này có thể dẫn đến một số nhầm lẫn.

Xem những đường dẫn

Giả sử có phiên bản cập nhật của một chương trình gọi là htg. Nó có tên trong thư mục hiện tại và bạn có thể chạy nó bằng cách gõ lệnh sau:
./htg
Chạy htg
Đây không hẳn là chương trình, nó chỉ in số phiên bản và sau đó đóng lại. Phiên bản mới là 1.2.138.
Để chạy một chương trình trong thư mục làm việc hiện tại, bạn phải nhập “./” trước tên chương trình, để Bash biết nơi tìm nó.
Vì bài viết muốn chạy chương trình cụ thể này từ bất kỳ thư mục nào, nên ví dụ sẽ chuyển chương trình thực thi vào thư mục /usr/bin. Bash sẽ tìm thấy chương trình đó trong đường dẫn và chạy nó.
Ví dụ không có nhu cầu thực thi trong thư mục hiện tại, nên không cần phải gõ “./” trước tên chương trình, như hình dưới đây:
sudo mv htg /usr/bin
Không cần phải gõ “./”
Bây giờ, hãy để chạy chương trình bằng cách gõ:
htg
Chạy chương trình
Lệnh chạy, nhưng không phải là chương trình mới, được cập nhật mà thay vào đó, đó là phiên bản cũ hơn, 1.2.105.

Lệnh which

Vấn đề bài viết đã chứng minh ở trên là tại sao lệnh which lại được tạo ra.
Trong ví dụ này, ta sẽ sử dụng which và chuyển tên của chương trình đang kiểm tra như một tham số dòng lệnh:
which htg
Sử dụng which và chuyển tên của chương trình đang kiểm tra như một tham số dòng lệnh
Lệnh which báo cáo nó đã tìm thấy một phiên bản của htg trong thư mục /usr/local/bin. Vì vị trí đó xuất hiện trong đường dẫn trước thư mục mà ta đã di chuyển htg được cập nhật, Bash sẽ sử dụng phiên bản trước đó của chương trình.
Tuy nhiên, nếu ta sử dụng tùy chọn -a (all) như hiển thị bên dưới, nó sẽ tiếp tục tìm kiếm ngay cả khi tìm thấy kết quả khớp:
which -a htg
Với -a,sẽ tiếp tục tìm kiếm ngay cả khi tìm thấy kết quả khớp
Sau đó, nó liệt kê tất cả các kết quả phù hợp thuộc bất kỳ thư mục nào trong đường dẫn.
Vì vậy, xuất hiện một vấn đề, đó là phiên bản trước đó của chương trình trong thư mục cũng có trong bản vá. Và thư mục đó đang được tìm kiếm trước thư mục mà ta đã đặt phiên bản mới của chương trình.
Để xác minh, bạn có thể nhập nội dung sau và chạy từng phiên bản của chương trình:
/usr/local/bin/htg
/usr/bin/htg
Xác minh phiên bản
Điều này giải thích nguyên nhân vấn đề, và giải pháp rất đơn giản.
Trên thực tế, bạn có các lựa chọn: Xóa phiên bản cũ trong thư mục /use/local/bin hoặc di chuyển nó từ /usr/bin đến /usr/local/bin.

Xem kết quả

Hai kết quả không có nghĩa là hai file nhị phân.
Hãy cùng xem một ví dụ trong đó bài viết sẽ sử dụng lệnh which với tùy chọn -a (all) và tìm các phiên bản của chương trình less:
which -a less
Tìm phiên bản của chương trình less
Lệnh which báo cáo hai địa điểm chứa một phiên bản của chương trình less, nhưng điều đó có đúng không? Thật kỳ lạ khi có hai phiên bản khác nhau (hoặc cùng một phiên bản ở nhiều vị trí) của chương trình less được cài đặt trên máy tính Linux. Vì vậy, ta sẽ không chấp nhận đầu ra từ which. Thay vào đó, hãy đào sâu hơn một chút.
Bạn có thể sử dụng các tùy chọn ls-l (long listing) và -h (human-readable) để xem những gì diễn ra tiếp theo:
ls -lh /usr/bin/less
Sử dụng một số tùy chọn khác
Dung lượng file được báo cáo là 9 byte! Đây chắc chắn không phải là một bản sao đầy đủ của less.
Ký tự đầu tiên của danh sách là một chữ l. Một file bình thường sẽ có dấu gạch nối (-) là ký tự đầu tiên. “l” là biểu tượng của liên kết tượng trưng (symbolic link). Nếu bạn bỏ lỡ chi tiết đó, biểu tượng --> cũng cho biết đây là một liên kết tượng trưng (​​bạn có thể coi đó là một loại shortcut). Điều này chỉ ra bản sao của less trong /bin.
Hãy thử lại với phiên bản less trong /bin:
ls -lh /bin/less
Hãy thử lại với phiên bản less trong /bin
Mục nhập này rõ ràng là một binary executable (file thực thi nhị phân) thực sự. Ký tự đầu tiên của danh sách là dấu gạch nối (-), có nghĩa nó là một file thông thường và dung lượng file là 167KB. Vì vậy, chỉ có một bản sao less được cài đặt, nhưng có một liên kết tượng trưng đến nó từ một thư mục khác, mà Bash cũng tìm thấy khi tìm kiếm đường dẫn.

Kiểm tra nhiều lệnh cùng một lúc

Bạn có thể truyền nhiều chương trình và lệnh tới which và nó sẽ kiểm tra chúng theo thứ tự.
Ví dụ, nếu bạn gõ:
which ping cat uptime date head
Kiểm tra nhiều lệnh cùng một lúc
Lệnh which sẽ hoạt động theo danh sách các chương trình và lệnh bạn đã cung cấp, rồi liệt kê kết quả cho từng chương trình.
Ngoài việc khám phá sâu vào hệ thống file Linux vì tò mò, which hữu ích nhất khi bạn mong đợi một tập hợp các hành vi từ một lệnh hoặc chương trình, nhưng lại nhận được cái khác.
Bạn có thể sử dụng which trong những trường hợp này để xác minh lệnh Bash đang khởi chạy có phải là lệnh bạn muốn sử dụng không.
#linux #linux_which

ĐỌC NHIỀU

Trần Văn Bình - Oracle Database Master