Điều này dẫn đến một câu hỏi về cách đánh giá hoạt động. Cả hai ví dụ đều hoạt động theo cùng một cách, vấn đề xảy ra do cách shell (bash, ở đây) mở rộng các biến.
Khi bạn viết lệnh này:
HOME="foo" echo $HOME
Các $HOME
được mở rộng trước khi lệnh được chạy . Do đó, nó được mở rộng thành giá trị ban đầu chứ không phải giá trị mới mà bạn đã đặt cho lệnh. Các HOME
biến đã thực sự được thay đổi trong môi trường mà các echo
lệnh đang chạy trong, tuy nhiên, bạn đang in $HOME
từ công ty mẹ.
Để minh họa, hãy xem xét điều này:
$ HOME="foo" bash -c 'echo $HOME'
foo
$ echo $HOME
/home/terdon
Như bạn có thể thấy ở trên, lệnh đầu tiên in giá trị thay đổi tạm thời HOME
và lệnh thứ hai in bản gốc, chứng minh rằng biến chỉ được thay đổi tạm thời. Bởi vì bash -c ...
lệnh được đặt trong dấu ngoặc đơn ( ' '
) thay vì dấu ngoặc kép ( ) " "
, biến không được mở rộng và được chuyển như nguyên trạng của quy trình bash mới. Quá trình mới này sau đó mở rộng nó và in giá trị mới mà nó đã được đặt thành. Bạn có thể thấy điều này xảy ra nếu bạn sử dụng set -x
:
$ set -x
$ HOME="hello" echo "$HOME"
+ HOME=hello
+ echo hello
hello
Như bạn có thể thấy ở trên, biến $HOME
không bao giờ được chuyển đến echo
. Nó chỉ thấy giá trị mở rộng của nó. So sánh với:
$ HOME="hello" bash -c 'echo $HOME'
+ HOME=hello
+ bash -c 'echo $HOME'
hello
Ở đây, vì các dấu ngoặc đơn, biến và không phải giá trị của nó được chuyển sang quy trình mới.
local
.