Nghịch ngợm một chút với Unix Command Prompt
Unix
31
White

huydx viết ngày 23/05/2015

alt text

Chắc hẳn là một unix user (có thể mac os hay linux), lại là một programmer, bạn sẽ phải hàng ngày sử dụng terminal cho việc lập trình, quản lý source, monitoring hệ thống.... Và đã là người sử dụng terminal hàng ngày thì cái bạn phải nhìn thấy nhiều nhất chính là cái gọi là "Command prompt"

alt text

Cái command prompt này thì tùy thuộc vào shell bạn đang dùng (bash hay zsh..) mà sẽ có những cách tùy chỉnh khác nhau. Mình thì đang dùng bash (chắc một ngày gần đây sẽ chuyển qua zsh), nên bài viết này sẽ áp dụng chủ yếu ở trên bash. Command prompt ở trên bash thì gồm có 4 biến môi trường (environment variable) chính: PS1, PS2, PS3, PS4 (Ngoài ra còn có COMMAND_PROMPT nữa nhưng thằng này na ná PS1 nên mình không đề cập đến). Để sử dụng các biến môi trường này thì bạn chỉ cần:

export PS1 = "abcxyz"

hoặc đặt đoạn code đó vào ~/.bash_profile hoặc ~/.bashrc rồi

source ~/.bash_profile 

để shell load lại các setting trong file tương ứng là biến môi trường đã được set.

Dưới đây mình sẽ nói về việc sử dụng các biến môi trường này để biến cái command prompt của bạn trở nên màu mèthân thiện hơn. Về thứ tự thì mình sẽ nói về cái có độ tùy biến thấp đến cao

PS2

Trong 5 biến mình nói ở trên thì biến PS2 là thằng nhàm chán nhất. PS2 gọi là Continuation interactive prompt. Tại sao lại gọi như vậy thì: khi một câu lệnh unix quá dài thì bạn thường dùng kí hiệu "\" ở cuối dòng để làm cho câu lệnh đấy thành multiple-line (gõ được ở nhiều dòng). Và PS2 là biến quyết định cái gì được in ở đầu mỗi dòng đó

alt text

Cách sử dụng thì vô cùng đơn giản:

export PS2="continue here -> "

Và kết quả là:

alt text

Chắc bạn cũng đã hình dung ra cách dùng PS2 thế nào rồi nhỉ, và hẳn bạn đang nghĩ, biến này chả có gì thú vị lắm nhỉ, mình cũng nghĩ thế :D. Thế nên chúng ta qua thằng tiếp theo nhé: PS3

PS3

PS3 gọi là biến dùng cho việc "select inside shell script"
Giả sử bạn phải viết một đoạn script cho lựa chọn (ví dụ như bạn làm infra, phải viết script kiểu như: hãy chọn giữa install rvm hay rbenv chẳng hạn).Thì chắc đoạn script đó sẽ trông như sau:

==> code
echo "Select your option:"
select i in 1) 2) 3)
do
  case $i in 
    x)....
    y)....
    z)....
  esac
done

==> run
# /.select.sh
x)....
y)....
z)....

#? 1
x)

Như các bạn thấy, prompt để lựa chọn khi không có setting gì sẽ là không hiện gì, quite boring
Giờ nếu chúng ta chỉ cần setting PS3 cho đoạn code đó như sau

==> code
PS3="Select an option of installer (1-3): "
select i in 1) 2) 3)
do
  case $i in 
    x)....
    y)....
    z)....
  esac
done

==> run
# /.select.sh
x)....
y)....
z)....

#? Select an option of installer (1-3): 1
x)

Như vậy là chúng ta sẽ có một cái prompt có hiện gì, use case để dùng thì chắc trong phần lớn các trường hợp sẽ là để cung cấp thông tin cho user về các option lựa chọn phía dưới. PS3 có vẻ khá useful trong một số case nhất định đúng không :D, tiếp theo chúng ta sẽ đến với PS4

PS4

Khi execute một đoạn script mà bạn muốn tracking output (để debug chẳng hạn), bạn sẽ dùng {set -x} để làm việc đó. ví dụ như đoạn code ở dưới đây:

==> code tracking.sh
set -x
ls -all -lrt | grep xyz
pwd

==> run
++ ls -all -lrt
++ grep xyz
drwxr-xr-x   2 doxuanhuy  staff   68 Apr 28 11:45 xyz
++ pwd
/Users/doxuanhuy/cur-project/android-globalit

Như các bạn thấy, {set -x} sẽ output ra các câu lệnh được execute và prefix bằng cái "++". 2 kí tự này có vè không thể hiện được gì nhỉ, và với PS4, bạn có thể thêm thông tin hữu ích cho việc debug như line number thông qua biến $LINENO, hay function name thông qua biến $FUNCNAME, hay script name thông qua biến $0

==> code tracking.sh
export PS4='$0.$FUNCNAME $LINENO '

set -x
somefunction() {
    ls -all -lrt | grep xyz
      pwd
}
somefunction

==> run
../test.sh. 8 somefunction
../test.sh.somefunction 5 ls -all -lrt
../test.sh.somefunction 5 grep xyz
drwxr-xr-x   2 doxuanhuy  staff   68 Apr 28 11:45 xyz
../test.sh.somefunction 6 pwd
/Users/doxuanhuy/cur-project/android-globalit

Như vậy chúng ta đã có những thông tin khá hữu ích để debug đúng không.
Và tiếp theo chúng ta sẽ đi đến bộ đôi thú vị nhất trong ngày: PS1 và COMMAND_PROMPT

PS1

Đây chính là biến quyết định cái gì sẽ hiện lên ở command prompt, và là biến có nhiều cái để hack nhất trong các loại PSx

alt text

Đầu tiên chúng ta sẽ nói về PS1
Giả sử chúng ta muốn command prompt hiện lên Username, Hostname và full-path đến directory hiện tại, đơn giản chúng ta chỉ cần

export PS1="\u@\h \w> "

Ở đây \u là Username, \h là Hostname và \w là full path của current dir.
Như vậy chúng ta sẽ có 1 cái prompt như dưới đây

doxuanhuy@xxx ~/cur-project/android-globalit> 

Quite easy phải không :D
Hay hơn chút nữa, bạn muốn hiện thêm current time, lên prompt, rất đơn giản:

export PS1="\$(date +%k:%M:%S) \w> "

Ở đây (date +%k:%M:%S) là để format date và biến nó thành variable thông qua $

Và kết quả là

12:23:59 ~/cur-project/android-globalit> 

Ngoài ra còn rất nhiều cái bạn có thể cho vào command prompt để biến nó thêm phần phong phú như:

  • !: The history number of the command
  • $kernel_version: The output of the uname -r command from $kernel_version variable
  • \$?: Status of the last command

Hacking thêm chút nữa, bạn có thể thay đổi màu của từng phần trên command prompt thông qua 3 metacharacter sau:

  • \e[ - Indicates the beginning of color prompt ( giống như cái "^" của regex vậy)
  • x;ym - Indicates color code. Use the color code values mentioned below ( bạn đặt x;ym ở trước node nào thì node đó sẽ được colorize theo màu đó)
  • \e[m - indicates the end of color prompt (giống như cái "$" của regex)

Một ví dụ đơn giản:

export PS1="\e[0;34m\u@\h \w> \e[m"

Đoạn code trên có nghĩa là gì:

alt text

Hacking thêm một chút nữa, bạn hiện là một developer đang sử dụng git với rất nhiều repo, rất nhiều branch. Mỗi lần vào một repo nào đấy bạn lại phải {git branch} để xem bạn đang ở branch nào, bất tiện vô cùng. Bạn muốn prompt của bạn sẽ hiện branch name mỗi khi bạn vào folder của một repo nào đấy? Thật đơn giản, với backquote để execute bash command và sự trợ giúp của sed, bạn làm điều đó thật đơn giản:

export PS1='\e[0;36m\u⌘ \e[0;35m\W \e[0;33m`git branch 2> /dev/null | grep -e ^* | sed -E  s/^\*\ \(.+\)$/\(\1\)\ /`\e[m\]'

Trông có vẻ đáng sợ, nhưng thực ra lại rất đơn giản :D, Chúng ta sẽ đi từng phần nhé:

  • \e[ : start của command prompt
  • [0;36m\u⌘ : bạn tô màu phần user (\u) bởi 0;36m (màu xanh dương) và thêm vào đằng sau cái kí tự ⌘ (cho cool thôi :D)
  • \e[0;35m\W : bạn tô màu phần directory hiện tại (\W) bởi 0;35m (màu hồng)
  • \e[0;33m : tô màu toàn bộ phần đằng sau bởi màu 0;33m (màu vàng)
  • git branch 2> /dev/null | grep -e ^* | sed -E s/^\\*\ (.+)$/(\\\1)\ /: nguyên văn đoạn này sẽ như sau: đầu tiên bạn dùng "git branch" để lấy branch hiện tại. Trong trường hợp không ở trong git repo nào thì sẽ có lỗi ra stderr, bạn redirect cái lỗi này vào dev/null thông qua "2> /dev/null" để nó không hiện ra prompt (2 là stderr). Sau đấy bạn tìm line nào có * ở đầu (current git branch) thông qua việc pipe vào grep. Tìm được line đó rồi thì bạn sẽ tách phần đằng sau dấu * ra thông qua sed , và output phần đó ra ngoài với format (branch) thông qua $/(\1). Tất cả đoạn code này được để vào backquote để được execute trực tiếp mỗi khi PS1 được gọi. Và kết quả thật bất ngờ:

alt text

Looks so cool!!
Ngoài ra bạn còn có rất nhiều thứ có thể hacking với PS1 như:

Ending

Như vậy với PS[1-4], bạn đã có thể customize command prompt của bạn trở nên đẹp đẽ hơn, cool hơn và useful hơn. Trong các bài viết sắp tới mình sẽ nói về việc sử dụng các công cụ rất mạnh của unix family os như grep, sed, wc để giúp cho công việc development của bạn trở nên thú vị hơn :D. Happy hacking!

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

huydx

115 bài viết.
858 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
135 8
Introduction (Link) là một cuộc thi ở Nhật, và cũng chỉ có riêng ở Nhật. Đây là một cuộc thi khá đặc trưng bởi sự thú vị của cách thi của nó, những...
huydx viết hơn 1 năm trước
135 8
White
109 14
Happy programmer là gì nhỉ, chắc ai đọc xong title của bài post này cũng không hiểu ý mình định nói đến là gì :D. Đầu tiên với cá nhân mình thì hap...
huydx viết gần 3 năm trước
109 14
White
86 10
(Ảnh) Mở đầu Chắc nhiều bạn đã nghe đến khái niệm oauth. Về cơ bản thì oauth là một phương thức chứng thực, mà nhờ đó một web service hay một ap...
huydx viết hơn 2 năm trước
86 10
Bài viết liên quan
White
1 0
Sử dụng option I với xargs Với option I thì bạn có thể sử dụng place holder với biến được lấy ra từ xargs man của option này: I replacestr R...
LinhPT viết gần 2 năm trước
1 0
White
45 1
Chương 1. Tổng quan một hệ thống Linux Thiên chúa thấy mọi sự người đã làm, và thấy rằng nó đuợc làm rất tốt. Bible King James Version. Genesis 1:3...
Trần Đạt viết hơn 1 năm trước
45 1
White
17 1
Chương 2. Tổng quan về cây thư mục Chương này mô tả các phần quan trọng của cây thư mục trong Linux , dựa trên Tiêu chuẩn phân cấp cây thư mục Fil...
Trần Đạt viết hơn 1 năm trước
17 1
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
115 bài viết.
858 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!