Xem lại và dùng lại lệnh cũ trong Linux với history
Nội dung bài viết

Trong Bash, history hiển thị danh sách các câu lệnh đã thực thi bởi tài khoản hiện tại. Nghe đơn giản nhưng đây là một trong những công cụ tiết kiệm thời gian nhất khi làm việc trên máy chủ, nhất là với những câu lệnh dài mà bạn không muốn gõ lại.

Xem lịch sử

history        # toàn bộ lịch sử, kèm số thứ tự
history 10     # 10 lệnh gần nhất

Kết quả có dạng:

  501  cd /var/www/html
  502  tail -f storage/logs/laravel.log
  503  systemctl reload nginx
  504  history 10

Con số bên trái là số thứ tự của lệnh trong lịch sử, và bạn sẽ dùng nó ngay sau đây.

Chạy lại lệnh cũ

!503      # chạy lại lệnh số 503
!!        # chạy lại lệnh vừa gõ
!systemctl # chạy lại lệnh gần nhất bắt đầu bằng "systemctl"

!! đặc biệt hữu ích khi bạn quên sudo:

$ systemctl restart nginx
Failed to restart nginx.service: Access denied

$ sudo !!
# tương đương: sudo systemctl restart nginx

Một mẹo khác là !$, lấy lại tham số cuối cùng của lệnh trước:

$ mkdir /var/www/duan-moi
$ cd !$
# tương đương: cd /var/www/duan-moi

Tìm kiếm trong lịch sử

Cách nhanh nhất không phải là history mà là Ctrl + R. Nhấn tổ hợp này rồi gõ vài ký tự, Bash sẽ tìm ngược trong lịch sử và hiện ra lệnh khớp gần nhất:

(reverse-i-search)`nginx': systemctl reload nginx

Nhấn Ctrl + R thêm lần nữa để chuyển sang kết quả cũ hơn. Nhấn Enter để chạy, hoặc mũi tên phải để sửa lệnh trước khi chạy. Nhấn Ctrl + G để hủy.

Đây là phím tắt tôi dùng nhiều nhất trong toàn bộ công việc dòng lệnh.

Cách khác là lọc bằng grep:

history | grep mysql

Xóa lịch sử

Đôi khi bạn lỡ gõ mật khẩu hoặc token vào dòng lệnh và nó nằm lại trong lịch sử.

history -d 503        # xóa một dòng cụ thể
history -c            # xóa toàn bộ lịch sử trong phiên hiện tại
history -c && history -w   # xóa và ghi đè xuống file

Lịch sử được lưu vĩnh viễn trong file ~/.bash_history. Chỉ dùng history -c thôi là chưa đủ vì file trên đĩa vẫn còn, phải kèm history -w để ghi đè.

Cách tốt hơn cả là đừng để bí mật lọt vào lịch sử ngay từ đầu. Trong Bash, nếu bạn gõ một dấu cách trước câu lệnh và biến HISTCONTROL có chứa ignorespace, lệnh đó sẽ không được ghi lại:

 mysql -u root -pMatKhauCuaBan    # có dấu cách ở đầu dòng

Tùy chỉnh cách lưu lịch sử

Thêm vào file ~/.bashrc:

# Số lệnh giữ trong bộ nhớ và trong file
HISTSIZE=10000
HISTFILESIZE=20000

# Bỏ qua lệnh trùng lặp và lệnh bắt đầu bằng dấu cách
HISTCONTROL=ignoreboth

# Ghi kèm ngày giờ cho mỗi lệnh
HISTTIMEFORMAT="%d/%m/%Y %H:%M:%S  "

# Nối thêm vào file thay vì ghi đè khi đóng phiên
shopt -s histappend

HISTTIMEFORMAT rất đáng bật. Khi cần truy lại “hôm thứ ba tôi đã chạy lệnh gì trên máy chủ này”, có mốc thời gian sẽ khác hẳn.

Sau khi sửa, nạp lại cấu hình:

source ~/.bashrc

Lưu ý khi mở nhiều phiên SSH

Bash chỉ ghi lịch sử xuống file khi bạn thoát phiên làm việc. Nếu bạn mở nhiều cửa sổ SSH cùng lúc, phiên đóng sau cùng có thể ghi đè lịch sử của các phiên khác. Dòng shopt -s histappend ở trên xử lý đúng vấn đề này.

Muốn mọi lệnh được ghi ngay lập tức và chia sẻ giữa các phiên, thêm:

PROMPT_COMMAND="history -a; history -c; history -r"