54 điểm bởi GN⁺ 2026-03-13 | 5 bình luận | Chia sẻ qua WhatsApp
  • Khi phiên SSH bị treo, bạn có thể điều khiển nhiều thứ thông qua menu escape sequence tích hợp sẵn trong SSH mà không cần ép buộc kết thúc tiến trình
  • Trong phiên làm việc, sau khi nhấn ↵Enter rồi nhập ~?, danh sách lệnh ẩn sẽ được hiển thị, và với ~. bạn có thể ngắt kết nối ngay lập tức trong mọi tình huống
  • Escape sequence này được tích hợp ngay trong chính SSH client nên vẫn hoạt động ngay cả khi máy chủ không phản hồi hoặc kết nối bị đứt
  • Trong các phiên SSH lồng nhau, có thể dùng ~~ để chuyển sequence vào client bên trong
  • Ngoài ra còn giới thiệu thêm các tùy chọn SSH hữu ích như -C, -v, -D

Menu escape sequence của SSH

  • Trong phiên SSH, nhấn ↵Enter rồi nhập ~? để xem danh sách các escape sequence được hỗ trợ
  • Danh sách các sequence chính:
    • ~. — đóng kết nối (bao gồm cả các phiên được multiplex)
    • ~B — gửi tín hiệu BREAK tới hệ thống từ xa
    • ~C — mở dòng lệnh (có thể cấu hình port forwarding, nhập help để xem hướng dẫn)
    • ~Ryêu cầu rekey
    • ~V/v — tăng/giảm verbosity (LogLevel)
    • ~^Ztạm dừng SSH (suspend)
    • ~# — hiển thị danh sách các kết nối đã được forward
    • ~&chuyển SSH xuống nền (khi đang chờ kết nối đóng)
    • ~~ — gửi chính ký tự escape (nhập hai lần)
  • Các sequence này được tích hợp trong chính SSH client, nên vẫn hoạt động cả khi SSH server không phản hồi hoặc kết nối đã bị đứt
  • Hữu ích nhất là ~., vì khi phiên bị treo bạn có thể thoát ngay lập tức trong mọi tình huống
  • Escape sequence chỉ được nhận diện ngay sau một dòng mới (newline)

Cách dùng trong phiên SSH lồng nhau

  • Trong môi trường lồng SSH, tức là SSH vào trong một phiên SSH khác, bạn có thể dùng ~~ để chuyển sequence vào client bên trong
  • Ví dụ:
  pinkie@stable:~$ ssh ponyville        # stable  
  pinkie@ponyville:~$ ssh manehatten    # stable › ponyville  
  pinkie@manehatten: ~$                 # stable › ponyville › manehatten  
  pinkie@manehatten:~$ Connection to manehatten closed. # ↵Enter `~~.`  
  pinkie@ponyville:~$                   # stable › ponyville  
  pinkie@ponyville:~$ ssh manehatten stable › ponyville  
  pinkie@manehatten: ~$                 # stable › ponyville › manehatten  
  pinkie@manehatten:~$ Connection to ponyville closed. # ↵Enter `~.`  
  pinkie@stable:~$                      # stable  
  • Ở trạng thái kết nối stable → ponyville → manehatten
  • Khi nhập ~~., chỉ phiên trong cùng (manehatten) bị đóng và quay về ponyville
  • Khi nhập ~., phiên ở giữa (ponyville) cũng bị đóng và quay về stable

Một vài tùy chọn SSH bổ sung

  • ssh -C — bật nén gzip; trong tài liệu có nói không cần thiết trên mạng nhanh, nhưng khi dùng TUI hoặc xuất lượng lớn log thì cải thiện rõ rệt độ trễ và độ phản hồi
  • ssh -v — bật ghi log chi tiết (-vv, -vvv để in nhiều thông tin hơn), hữu ích để phân biệt kết nối thực sự bị treo hay chỉ đơn giản là chậm khi truy cập đường truyền chậm hoặc thiết bị yếu như Raspberry Pi
  • ssh -D 1234 — tạo SOCKS proxy tại localhost:1234, cho phép truy cập thông qua mạng của máy chủ, hữu ích cho công việc trong LAN phía máy chủ hoặc như một VPN DIY đơn giản

5 bình luận

 
t7vonn 2026-03-13

Wow, đúng là tính năng lần đầu tiên mình thấy luôn; giờ thì chắc không cần tắt terminal nữa rồi.

 
xguru 2026-03-13

Wow.. Dùng SSH hơn chục năm rồi mà đây là lần đầu tôi thấy tính năng này.
Thật sự là có hiện menu hiện ra luôn.

 
bus710 2026-03-13

Dừng thiết bị
Ờ......

 
GN⁺ 2026-03-13
Ý kiến trên Hacker News
  • Tôi từng rất muốn bênh vực manpage. Phần lớn manpage của phần mềm nguồn mở có chất lượng cao, một số thực sự xuất sắc
    Nhưng bản thân công cụ man lại có vấn đề. Ví dụ tôi muốn tìm cú pháp escape như ~? của client openssh, nhưng không thể tìm trong manpage
    Lý do là vì man biến ký tự ~ thành một dấu ngã Unicode kỳ quặc nên không thể grep được. Ký tự - cũng bị chuyển đổi tương tự nên không tìm được
    Với tài liệu cho công cụ dòng lệnh, đây là lỗi chí mạng. Những tính năng chuyển đổi kiểu này lẽ ra phải bị tắt theo mặc định

    • Tôi không rõ vấn đề chuyển đổi ký tự, nhưng có thể nhấn ctrl-r để tìm kiếm theo ký tự nguyên gốc (/<ctrl-r>~?)
    • Trên less, pager mặc định của Debian, nó hoạt động tốt
    • Tôi giải quyết bằng tùy chọn man -E ascii. Môi trường của tôi là Cygwin 3.6.6 nên cũng có thể là khác biệt giữa các distro
    • Nếu dùng neovim làm pager thì tìm ~? rất ổn. Chỉ cần biết escape regex (\\~?)
    • Trên macOS và CentOS, tìm \\~\\? cũng hoạt động tốt
  • Tôi đã dùng phím tắt ~. từ lâu, nhưng lại không biết có menu trợ giúp
    Nếu nhập ~ hai lần thì có thể gửi ký tự ngã thật, và trong phiên bình thường nó sẽ không bị nhận là escape trừ khi là ký tự đầu tiên được nhập
    Tức là ~ chỉ hoạt động như escape khi nó là ký tự đầu dòng và ngay sau một dòng mới. Thiết kế UI khá tinh tế

    • Giải thích cho độc giả trẻ hơn: trong chế độ echo của terminal, phím backspace thực ra không xóa khỏi bộ đệm nhập liệu
      Vì vậy có thể xuất hiện kiểu đầu ra như ls ~/^?^?^?^?^?~/a.out. SSH theo dõi luồng nhập chứ không phải màn hình
    • Điểm trừ là khi phiên bị treo, để thoát bằng ~. thì phải nhấn Enter trước, và thao tác này có thể bị gửi lên server
  • Tôi đã dùng SSH hơn 15 năm nhưng đây là lần đầu biết đến các chuỗi escape như vậy
    Lần sau nếu phiên bị treo tôi nhất định sẽ thử ~.. Chắc chắn tốt hơn nhiều so với đóng hẳn terminal

    • Nếu kết nối SSH của bạn hay bị ngắt, có thể là do TCP timeout ngắn của CGNAT
      Dùng VPN hoặc Tailscale có thể giải quyết được, hoặc điều chỉnh tham số tcp_keepalive để giữ kết nối sống
      Cấu hình ví dụ:
      net.ipv4.tcp_keepalive_time=240
      net.ipv4.tcp_keepalive_intvl=60
      net.ipv4.tcp_keepalive_probes=120
      
      Làm vậy thì phiên vẫn được giữ ngay cả trong môi trường CGNAT
    • Tôi đã dùng ~. hàng tuần suốt 20 năm. Thêm tùy chọn -v cho SSH cũng hữu ích để debug sự cố kết nối
    • Khi SSH qua nhiều bước, có thể dùng ~~. để đóng hop thứ hai
    • Tôi cũng đã dùng gần 30 năm, và trước đó còn dùng rsh. Xem Berkeley r-commands
    • Trước khi nhập ~., nhất định phải nhấn Enter để bắt đầu ở dòng mới
  • Tôi cũng đã dùng ~. từ lâu nhưng không biết các escape khác. Ở shell prompt thì nó không ăn ngay, nên phải chạy cat rồi nhập ~?

    • Dù vậy nó vẫn hoạt động. OpenSSH chỉ theo dõi đầu vào chứ không theo dõi đầu ra, nên có thể thoát bằng <enter>~.
    • Tôi cũng luôn dùng ~. để ngắt phiên, nhưng không biết rằng ~ chỉ hoạt động ở đầu dòng mới. ~^Z có vẻ cũng hữu ích
      Nó làm tôi nhớ đến chuỗi ctrl-[ của telnet
    • Client SSH nhận diện escape mà không cần biết phiên từ xa đang ở chế độ nào. Enter chỉ có tác dụng đưa nó về trạng thái sẵn sàng nhận escape mới
  • Những tính năng này thực ra bắt nguồn từ rsh. Người lớn tuổi như tôi còn nhớ

    • Thực ra kiểu lệnh ~ có trước ở cu(1). Đó là thời 4.1BSD, còn sớm hơn cả rsh
    • Bây giờ nếu muốn dùng scp theo kiểu rcp thì phải thêm tùy chọn -O
    • Là người còn nhớ thời uucp!bangpath, tôi thấy thật buồn cười
  • Menu của SSH hữu ích khi làm tunneling. Dù ngày nay phần nào bị thay thế bởi Tailscale và những thứ tương tự, nó vẫn còn giá trị

    • Khi mở “kết nối mới” trong tab mới, tôi dùng tính năng ControlMaster
      multiplex nhiều phiên SSH vào một kết nối nên không phải xác thực lặp lại, và tab completion cũng nhanh hơn
      Chỉ có điều khi kết nối bị treo thì hơi phiền
    • Tôi thường dùng tuns.sh. Nó tiện vì có thể phơi localhost ra bên ngoài
  • Gọi là “bí mật” thì không hẳn, chỉ là đa số mọi người không đọc manpage đến cuối nên không biết tới tính năng này

  • Escape ~ đã được dùng từ UNIX cu những năm 1970. Có thể xem SSH là hậu duệ của nó

  • Cấu hình ControlMaster mặc định khá bất tiện, nên thêm block như dưới đây sẽ tốt hơn

    Host *
      ControlMaster auto
      ControlPath ~/.ssh/sockets/%r@%h:%p
      ControlPersist 10m
    

    Làm vậy thì SSH/scp/rsync đến cùng một host sẽ tái sử dụng kết nối sẵn có
    Cũng có thể dùng escape ~C để thêm port forwarding ngay giữa phiên

    • Nếu tăng ControlPersist lên khoảng 1 giờ thì kết nối vẫn được giữ giữa các lần đăng nhập ngắn cách nhau
    • Cũng có người đùa rằng bình luận này trông như do LLM viết
  • Khi phiên SSH bị treo, tôi cũng chỉ có thể khôi phục bằng [Enter] ~.
    Có vẻ đây là một tính năng ẩn mà nếu không phải dân Linux rành thì khó biết

 
kayws426 2026-03-13

Tôi cũng biết về nó, nhưng hầu như chẳng có dịp để dùng. (...)