Hãy nói rằng tôi gọi A=B commandvà env A=B commandvào bash. Có bất kỳ tình huống nào có thể có một sự khác biệt giữa cả hai điều khoản?
Hãy nói rằng tôi gọi A=B commandvà env A=B commandvào bash. Có bất kỳ tình huống nào có thể có một sự khác biệt giữa cả hai điều khoản?
Câu trả lời:
Chúng phục vụ cùng một mục đích (truyền các lọ env đã cho cho lệnh). Tuy nhiên, một vài khác biệt đáng chú ý:
A=B command
là một cấu trúc shell (Bourne / POSIX / rc).
Chẳng hạn, bạn có thể làm:
A=B find . -exec cmd '{}' +
hoặc là:
find . -exec env A=B cmd '{}' +
Nhưng bạn không thể làm:
find . -exec A=B cmd '{}' +
Bởi vì findkhông gọi shell để chạy lệnh đó.
Mặt khác, envlà một lệnh bên ngoài, bạn không thể làm:
f() { ...; }
env A=B f
hoặc là:
env A=B eval '...'
Cũng thế:
A=B cmd
chỉ hoạt động với các env vars là tên biến shell hợp lệ . Bạn cần envcho bất kỳ tên var env khác:
env 'my var=foo' cmd...
bashđặt lại _biến:
bash-4.3$ _=xxx env | grep '^_='
_=/usr/bin/env
bash-4.3$ env _=xxx env | grep '^_='
_=xxx
Trong zsh, ARGV0và STTYcó ý nghĩa đặc biệt trong bối cảnh đó:
STTY=-echo cat
Chạy catvới thiết bị đầu cuối bị echovô hiệu hóa. Và:
ARGV0=foo cmd
chạy cmdvới foonhư của nó argv[0].
Nếu bạn không muốn xử lý đặc biệt, bạn phải sử dụng env.
Lưu ý rằng sudohỗ trợ:
sudo A=B cmd
Đó không phải là sử dụng vỏ hoặc envđể làm điều đó. Nó tự làm điều đó.
Nó có thể truyền các biến với bất kỳ tên nào ngoại trừ những tên bắt đầu bằng -.
Chuyển nhượng là một cấu trúc shell trong khi một dấu bằng trong đối số envkhông có ý nghĩa đặc biệt với shell, vì vậy A=$B cmdan toàn trong khi env A="$B" cmd(hoặc sudo A="$B" cmd) yêu cầu dấu ngoặc kép.
Các A=B cmdcú pháp chỉ được hỗ trợ trong vỏ của Bourne và rcgia đình (không esmặc dù). Trong vỏ của gia đình cshhoặc fishví dụ, bạn phải dùng đến env.