+6

Một số thủ thuật với Linux (1).

Từ khi những chiếc máy tính trở nên phổ biến thì luôn có những cuộc battle nảy lửa diễn ra giữa các luồng quan điểm khác nhau về cách sử dụng máy tính như Window hay OSX, GUI/TUI hay CLI, Vim hay Emacs... Và cuộc chiến mà mình đã tham gia gõ phím nhiều nhất trên các mặt trận Reddit, Facebook.. đó chính là trận siêu kinh điển giữa GUI và CLI (dùng giao diện vs dùng command line), mình không rõ hiện giờ phe nào đang áp đảo, nhưng sau trận chiến mình đã trở thành một người yêu thích sử dụng CLI hơn hẳn GUI (với những việc mà mình có thể tối ưu GUI bằng CLI thôi nha 🤣🤣). Và bài viết này sẽ trình bày một số kỹ thuật với CLI mà mình may mắn học được để giúp quá trình làm việc với terminal trở nên thú vị, bớt nhàm chán hơn.

Intro

Unfollow crush với Linux.

1. Quickly edit current command

Giữ CTRL, nhấn phím x rồi nhấn phím e. Thao tác này sẽ mở ra editor mặc định (echo $EDITOR | $VISUAL để kiểm tra) chứa sẵn câu lệnh mà bạn đang gõ trên terminal như đã được miêu tả trong man page:

edit-and-execute-command (C-xC-e)

Invoke an editor on the current command line, and execute the result as shell commands. Bash attempts to invoke $VISUAL, $EDITOR, and emacs as the editor, in that order.

Phím tắt này đặc biệt hữu ích trong trường hợp câu lệnh của bạn có độ dài từ vài dòng trở lên và tương đối tốn thời gian để chỉnh sửa ngay trên terminal bởi vì thư viện GNU Readlinebash sử dụng cho việc line-editing, bao gồm việc di chuyển con trỏ chuột, chỉnh sửa câu lệnh, tab completion, command history... có một hạn chế là thư viện này chỉ hỗ trợ việc tương tác sử dụng bàn phím cho nên khi bạn muốn chỉnh sửa câu lệnh tại một vị trí bất kì thì bạn không thể di chuột đến đó rồi click để thay đổi vị trí như trên những môi trường khác được mà bạn phải dí liên tục vào các phím mũi tên để có thể di chuyển một cách chậm chạp mà thôi. Mình không biết vì sao hạn chế của GNU Realine chưa được khắc phục (?) nhưng đó cũng là lý do mà có rất nhiều công cụ ra đời chỉ với một mục đích duy nhất là làm cho việc edit câu lệnh được nhanh chóng hơn.

Khi bạn sử dụng tổ hợp phím tắt này thì hãy chú ý rằng, nếu bạn không lưu lại và thoát ra, thì câu lệnh sẽ được thực thi ngay lập tức, điều này có thể gây ảnh hưởng lớn khi bạn đang thực hiện một số tác vụ cần sự cẩn trọng như là rm -rf /path/to/file.

Nếu default editor của bạn là vim thì bạn có thể dùng câu lệnh :cq để thoát ra khỏi editor an toàn bởi vì :cq trả về exit status khác 0, ám chỉ rằng, việc chỉnh sửa thất bại và bash sẽ không thực thi câu lệnh hiện tại nữa.

Khi mỗi câu lệnh được thực thi thì đều trả về exit status. Thông thường thì 0 ứng với xử lý thành công, còn 1 trở lên ứng với xử lý thất bại.

Bạn có thể xem demo ở đây.

2. Quickly edit last command (Fix Command)

fc là một câu lệnh tích hợp sẵn khi cài bash và được dùng để chỉnh sửa câu lệnh đã thực thi gần nhất với default editor có sẵn của bạn.

Ngoài ra với câu lệnh này bạn có thể xem thời điểm mà những câu lệnh đã được thực hiện trước đó như sau:

 fc -lf

 3087  5/25/2021 23:10  trash service
 3088  5/25/2021 23:11  trash tlp
 3089  5/25/2021 23:11  cd thinkpad-power-config
 3090  5/25/2021 23:11  vi powertop.service
 3091  5/25/2021 23:14  tlp-stat -c
 3092  5/25/2021 23:16  curl -sSL https://install.pi-hole.net | bash\n
 3093  5/25/2021 23:17  sudo curl -sSL https://install.pi-hole.net | bash\n

Xem thêm về fc command ở đây.

3. Repeat last command

Có những lúc bạn quên thêm sudo vào phía trước câu lệnh nhưng nhỡ thực thi rồi thì có thể nhanh chóng thực hiện lại bằng cách này nhé:

sudo !!

4. Repeat previous command start with specific prefix

Thực thi lại câu lệnh gần nhất bắt đầu với ls

!ls

5. Retain last argument

Giả sử bạn đang xem 500 dòng cuối cùng của file logbasex-v2020-06-30.txt theo thời gian thực

tail -fn500 logs/logbasex-v2020-06-30.txt

Bạn có thể dễ dàng thay thế tail bằng cat command mà vẫn giữ nguyên được tham số cuối cùng bằng câu lệnh sau:

cat !$
cat logs/logbasex-v2020-06-30.txt

6. Paste last argument of previous command(s)

alt + .

Bạn có thể lặp lại câu lệnh này để lấy được tham số cuối cùng của nhiều câu lệnh trước đó nữa chứ không chỉ dừng lại ở câu lệnh gần nhất.

7. Paste Nth argument of previous command(s)

alt-<n>-alt-.

8. Fix typo in command using thefuck

Lỗi typo à?

9. Quickly create an empty file / clear content of file

Đến lúc mà việc dùng câu lệnh touch dùng để tạo file là không cần thiết.


# bash
>file.extension
cat /dev/null > file.extension

# zsh
cat /dev/null >! file.extension

10. Recover the overwritten file

Nếu bạn có nhỡ tay xóa nội dung của tập tin nào quan trọng bằng những câu lệnh phía trên thì bạn vẫn có thể lấy lại được bằng cách sau:

CURRENT_FILE_SYSTEM=$(mount | grep $(df -P . | tail -n 1 | awk '{print $1}') | awk -F' ' '{print $1}')
sudo grep -i -a -B100 -A100 '<your-unique-string-in-file>' $CURRENT_FILE_SYSTEM | strings > /var/tmp/my-recovered-file

## strings command: get text inside a binary or data file.
## tập tin my-recovered-file sẽ có nhiều thông tin lộn xộn ngoài những thông tin bạn cần, nhớ lọc ra nhé.

11. Remove all but one specific file

Bạn sẽ có nhiều cách làm việc này nhưng ở đây mình muốn giới thiệu một kĩ thuật gọi là extended globbing (extglob), có thể hiểu như một dạng pattern matching nhưng không phải dành cho văn bản như regex mà là dành cho tập tin, đường dẫn và thư mục... sử dụng các ký tự đại diện (wildcard). Gõ man bash để xem hướng dẫn:

?(pattern-list)
             Matches zero or one occurrence of the given patterns
      *(pattern-list)
             Matches zero or more occurrences of the given patterns
      +(pattern-list)
             Matches one or more occurrences of the given patterns
      @(pattern-list)
             Matches one of the given patterns
      !(pattern-list)
             Matches anything except one of the given patterns

Tuy nhiên đây không phải tính năng được bật sẵn, bạn cần bật lên thông qua built-in command shopt (shell option) trước khi sử dụng:

shopt -s extglob
rm -f !(survivior.txt)

12. Remove all empty directory

find . -type d -empty -delete

13. Terminal cheatsheet (cht.sh)

Đôi khi bạn dùng vim mà không thể thoát ra, hoặc biết rồi mà hết lần này đến lần khác lại quên cách thoát ra thì xin chúc mừng bạn, trên thế giới có hàng vạn người như thế. Và một trong số đó đã viết ra một vài cái cheatsheet xịn xò để tiện cho việc tìm kiếm ở đây:

curl cht.sh/vim

...
# Editing

u               undo
yy              yank (copy) a line
y{motion}       yank text that {motion} moves over
p               paste after cursor
P               paste before cursor
<Del> or x      delete a character
dd              delete a line
d{motion}       delete text that {motion} moves over

# Search and replace with the `:substitute` (aka `:s`) command

:s/foo/bar/	replace the first match of 'foo' with 'bar' on the current line only
:s/foo/bar/g	replace all matches (`g` flag) of 'foo' with 'bar' on the current line only
:%s/foo/bar/g	replace all matches of 'foo' with 'bar' in the entire file (`:%s`)
:%s/foo/bar/gc	ask to manually confirm (`c` flag) each replacement
...

Ngoài ra bạn cũng có thể tìm kiếm rất nhiều cheatsheet khác bằng cách thay vim bằng một từ khóa khác như java chẳng hạn.

14. ASCII table in terminal

Nếu bạn đã từng phải google không biết bao nhiêu lần vì không nhớ code point trong bảng mã ASCII thì đã có câu lệnh này giúp bạn.

man ascii

15. File system document (hier command)

Nếu bạn mới bắt đầu với Linux, rất có thể bạn sẽ bị choáng ngợp bởi hệ thống file system trên Linux. Câu lệnh này sinh ra để giúp bạn tra cứu khi cần.

man hier

16. Bypass command yes/no question (yes to all)

Mỗi khi cài đặt package trên Linux, thì bạn sẽ thường được bạn được câu hỏi là có chắc chắn về việc cài đặt không, nếu có thì nhấn enter hoặc yes|no gì đó. Ví dụ:

sudo apt install openjdk-13-jdk-headless

Chuyện này quá đỗi là bình thường luôn nhưng nếu bạn quá lười để chờ đợi thì có thể làm như sau:

yes | sudo apt install openjdk-13-jdk-headless 

Hay thậm chí nếu bạn lười hơn nữa thì vẫn có cách đấy

sudo -i
echo "APT::Get::Assume-Yes \"true\";\nAPT::Get::force-yes \"true\";" > /etc/apt/apt.conf.d/90_no_prompt

## test
sudo apt install openjdk-14

17. sudo without password

Nếu việc ngăn chặn khỏi việc thực thi những câu lệnh gây ảnh hưởng nghiêm trọng đến hệ thống là không cần thiết đối với bạn, thì việc không phải nhập mật khẩu mỗi lần dùng câu lệnh sudo quả là một lợi thế lớn.

 echo "$USER ALL=(ALL) NOPASSWD: ALL" | sudo sh -c "cat - >> /etc/sudoers.d/nopassword; chmod 0440 /etc/sudoers.d/nopassword"

18. Keep process running after logout/exit terminal

Trong quá trình làm việc với vị trí backend, nhiều lúc bạn sẽ cần build frontend lên để test cho nó dễ.

eko-frontend/frontend on  test [⇣$!] is 📦 v0.0.1 
➜ sudo npm run dev -- -p 4001

event - compiled successfully
event - build page: /dashboard/status
wait  - compiling...
event - compiled successfully
event - build page: /login
wait  - compiling...
event - compiled successfully
event - build page: /dashboard/news
wait  - compiling...
event - compiled successfully
...

Tuy nhiên có một vấn đề là process này sẽ hold terminal của bạn, nếu tắt terminal thì tiến trình kết thúc, giữ lại thì cũng chẳng làm gì mà lại lãng phí một tab terminal. Để khắc phục việc này thì bạn có thể dùng nohup (stand for NO Hang UP) command, câu lệnh này sẽ bỏ qua việc gửi HUP (Hang UP) signal đến process khi đóng terminal, cho phép bạn có thể giữ cho process vẫn được chạy khi terminal bị đóng lại. STDOUT của process này sẽ được lưu trong tập tin nohup.out ở cùng thư mục bạn đang đứng.

eko-frontend/frontend on  test [⇣$!] is 📦 v0.0.1 took 7m 19s 
➜ nohup sudo npm run dev -- -p 4001 &

[2] 441199
nohup: ignoring input and appending output to 'nohup.out' 

Find nohup process id

ps -ef | grep <nohup command>

19. Share wifi as QR code

Mỗi lần có ai hỏi mật khẩu wifi thì thường mình trả lời là không biết, hoặc là phải tìm kiếm trong đây:

cat /etc/NetworkManager/system-connections/Bluebottle.nmconnection | grep psk

Việc này đôi khi gây ra đôi chút rắc rối nên mình đã tạo một cái thủ thuật nhỏ để có thể nhanh chóng chia sẻ mật khẩu wifi cho bất cứ ai muốn join vào network như sau:

[email protected]:~$ bash
[email protected]:~$ echo "\e[19~": 'nmcli device wifi show -s\015' > ~/.inputrc
[email protected]:~$ bind -f ~/.inputrc

Nhấn F8 để thấy điều kì diệu

20. ls command show binary permission

ls command show binary permission

ls -l | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/) \
             *2^(8-i));if(k)printf("%0o ",k);print}'

600 -rw------- 1 logbasex logbasex  3389 Mar 10 00:26 id_rsa
664 -rw-rw-r-- 1 logbasex logbasex  1460 Mar 10 00:10 id_rsa.ppk
664 -rw-rw-r-- 1 logbasex logbasex   752 Mar 10 00:10 id_rsa.pub

Tạo alias cho câu lệnh này thì việc thay đổi permission của tập tin/thư mục dùng chmod sẽ nhẹ nhàng hơn đôi chút đấy, tất nhiên là với điều kiện bạn đã quen làm việc với binary permission.

alias ls -l='ls -l | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/) \
             *2^(8-i));if(k)printf("%0o ",k);print}''

Final thought

Phần 1 đến đây là kết thúc, chúc mọi người năm mới vui vẻ an lành bên gia đình và người thân.

 ____________________
< Thanks for reading >
 --------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     |

Reference


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.