Hãy nói rằng tôi gọi A=B command
và env A=B command
và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 command
và env A=B command
và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ì find
không gọi shell để chạy lệnh đó.
Mặt khác, env
là 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 env
cho 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
, ARGV0
và STTY
có ý nghĩa đặc biệt trong bối cảnh đó:
STTY=-echo cat
Chạy cat
với thiết bị đầu cuối bị echo
vô hiệu hóa. Và:
ARGV0=foo cmd
chạy cmd
với foo
như 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 sudo
hỗ 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ố env
không có ý nghĩa đặc biệt với shell, vì vậy A=$B cmd
an 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 cmd
cú pháp chỉ được hỗ trợ trong vỏ của Bourne và rc
gia đình (không es
mặc dù). Trong vỏ của gia đình csh
hoặc fish
ví dụ, bạn phải dùng đến env
.