Đ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 HOMEbiến đã thực sự được thay đổi trong môi trường mà các echolệnh đang chạy trong, tuy nhiên, bạn đang in $HOMEtừ 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 HOMEvà 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.