Gần đây làm shell script và thấy significant difference behavior của bash special variable $$ và $BASHPID. Mọi process chạy Linux được assign process ID, OS handle process theo đó.
Related Read: Learn Difference Between Sourcing and Forking in Bash
Tương tự, bash terminal session cũng assign process ID. Special variable $$ và $BASHPID store process ID của current shell.
Chạy command xem process ID current shell. Cả $$ và $BASHPID return same value.
$ echo $$ # Printing special variable $$
$ echo $BASHPID # Printing variable $BASHPID
Trong bash khi call external program từ shell, nó tạo child process/subshell và program submitted in child process only. Ví dụ: put simple process monitor command trong script "sample.sh" demo parent shell tạo subshell run program.
#!/usr/bin/env bash
ps -ef --forest | grep -i bash
Chạy script get process ID của bash. Từ image hiểu khi call script bash tạo child process chạy script.
$ ./sample.sh
Dùng cả $$ và $BASHPID trong script xem return gì.
#!/usr/bin/env bash
echo "============================"
ps -ef --forest | grep -i bash
echo "============================"
echo "PID USING $$ FOR SCRIPT $0 ==> $$"
echo "PID USING BASHPID FOR SCRIPT $0 ==> $BASHPID"
echo
Chạy script lại.
$ ./sample.sh
Okay, return same process ID. Đây là actual difference. Tạo another child process bên trong script bằng chạy command trong parentheses().
# STORING THE PID INTO A VARIABLE…
VAR_HASH=$(echo $$)
VAR_BASHPID=$(echo $BASHPID)
echo "VALUE OF VAR_HASH ==> $VAR_HASH"
echo "VALUE OF VAR_BASHPID ==> $VAR_BASHPID"
Trong bash, Parentheses invoke child process chạy whatever inside parentheses. Trong case đó, cả $$ và $BASHPID nên store new child process ID. Nhưng từ image thấy difference: $$ store 382 là parent ID (Process ID của script sample.sh), và $BASHPID store created child process ID bởi parentheses.
Hiểu behavior này. Xem man page.
$ man bash
Khi dùng $$, even trong subshell, nó store process ID của parent process nó được tạo từ. Nhưng BASHPID store current process ID, tức khi gọi bên trong parentheses nó store child process ID.
Không thể assign hoặc modify variable $$, nhưng BASHPID có thể reassign nhưng no effect.
$ $$=10
$ BASHPID=10
$ echo $BASHPID
Có thể unset BASHPID. Khi unset nó mất special state và dùng như normal variable.
$ unset BASHPID
$ echo $BASHPID
$ BASHPID="Tecmint"
$ echo $BASHPID
Thậm chí thử assign process ID của shell, nó treated as user-defined variable vì đã mất special state.
$ BASHPID=$(echo $$)
$ echo $$;echo $BASHPID
Trường hợp này, cần new terminal session cho BASHPID lấy lại special state.
Đó là tất cả bài viết. Đã thấy difference giữa $$ và BASHPID và behavior. Đọc bài viết và share feedback.