Để env hay không env


32

Sự khác biệt giữa các lệnh là gì

$ env FOO=bar baz

$ FOO=bar baz

Có ảnh hưởng gì không env?


4
Sắp xếp một câu hỏi phụ, nhưng chính tính năng đó được gọi là gì khi bạn đặt biến môi trường cho một tiểu ban như vậy? Tôi đã luôn gặp khó khăn trong việc tìm kiếm thông tin về điều này bởi vì tôi không biết nó được gọi là gì.
John Cromartie

1
@JohnCromartie, bạn nên hỏi như một câu hỏi.
cjm

1
Đối với bash, đó là tài liệu ở đây: gnu.org/software/bash/manual/...
glenn Jackman

2
@JohnCromartie Đây là một thành phần tùy chọn của mọi lệnh shell, vì vậy nó nằm trong phần "Lệnh đơn giản" trong hầu hết các hướng dẫn sử dụng shell. Đối với POSIX, đó sẽ là ở đây . glenn đã liên kết phần tương tự từ hướng dẫn bash cho bạn rồi.
jw013

Đặt một biến không tồn tại thông qua một bài tập sẽ tạo ra một biến shell. Đặt nó thông qua ENV hoặc xuất biến sẽ đẩy biến vào môi trường thực thi của shell. Thay đổi giá trị của một biến hiện có sẽ cập nhật giá trị môi trường thực thi nếu tồn tại, nếu không thì thay đổi nó trong các biến nội bộ shell.
Johan

Câu trả lời:


26

Chúng tương đương về chức năng.

Sự khác biệt chính là env FOO=bar bazliên quan đến việc gọi một quá trình trung gian giữa vỏ và baz, trong đó như với FOO=bar bazvỏ trực tiếp gọi baz.
Vì vậy, trong vấn đề đó, FOO=bar bazđược ưa thích.

Các tình huống duy nhất tôi thấy mình sử dụng env FOO=barlà khi tôi phải truyền một lệnh cho một lệnh khác.
Như một ví dụ cụ thể, giả sử tôi có một tập lệnh bao bọc thực hiện một số sửa đổi của môi trường và sau đó gọi execlệnh được truyền cho nó, chẳng hạn như:

#!/bin/bash
FOO=bob
some stuff
exec "$@"

Nếu bạn thực hiện nó như là myscript FOO=bar baz, execsẽ ném một lỗi exec FOO=bar bazlà không hợp lệ.
Thay vào đó, bạn gọi nó là myscript env FOO=bar bazđược thực thi exec env FOO=bar bazvà hoàn toàn hợp lệ.


1
Bạn có thể làm FOO=bar exec bazmặc dù, vì vậy bạn không cần envở điểm cuối cùng của bạn.
Stéphane Chazelas

Khi bạn execmột cái gì đó, nó sử dụng môi trường hiện tại của bạn?
glenn jackman

1
Ditto @StephaneChazelas và bạn cũng có thể sudo FOO=bar bazchuyển các biến môi trường mà không cần env.
Mike Miller

1
@StephaneChazelas chỉ hoạt động nếu tôi muốn đưa FOO=barvào tập lệnh. Nếu FOOkhông phải lúc nào cũng vậy bar, tôi không muốn mã hóa nó, và thay vào đó hãy chuyển nó vào.
Patrick

@glennjackman có, miễn là các biến được xuất hoặc chuyển trước exec, chẳng hạn như FOO=bar exec baz.
Patrick

14

Trong ví dụ cụ thể này, không có sự khác biệt hiệu quả, giả sử vỏ của bạn là vỏ tương thích POSIX và giả sử bazlà vỏ có thể thực thi và không phải là vỏ dựng sẵn.

Ví dụ , nếu vỏ của bạn không phải là vỏ tương thích POSIX, cshhoặc tcshcú pháp

FOO=bar baz

không hoạt động và không có cú pháp shell tương đương. Đối với các shell đó, envlệnh là cách duy nhất để ghi đè hoặc chèn các biến môi trường cho một lệnh.

Nếu bazlà shell dựng sẵn, giả sử fc, chẳng hạn, envsẽ không cho kết quả tương tự, vì envđang thực hiện một quy trình mới thay vì được chạy trực tiếp bởi shell lệnh. Hơn nữa, không có fckhả năng thực thi, nó chỉ có thể được chạy dưới dạng shell dựng vì cách nó tương tác với môi trường shell, và vì vậy envsẽ không bao giờ hoạt động với một nội dung như vậy fc.

Ngoài ra, envcung cấp -itùy chọn, cho phép bạn bắt đầu một lệnh trong môi trường trống chỉ với một bộ biến môi trường được chỉ định. Vì vậy, envcó thể rất hữu ích để bắt đầu các quy trình trong môi trường vệ sinh, ví dụ

env -i HOME=/tmp/homedir "PATH=`getconf PATH`" "TERM=$TERM" FOO=bar baz

Khi tôi sử dụng tcshtôi sẽ viết (setenv FOO bar; baz)để có được chức năng tương đương.
Barmar

6

Ngoài những gì đã được nói

VAR=value cmd args > redirs

là một tính năng shell (Bourne / POSIX), bạn bị giới hạn trong tên của các biến môi trường mà bạn chuyển đến cmd. Chúng phải là tên biến shell hợp lệ và không được là biến chỉ đọc hoặc biến đặc biệt đối với shell.

Chẳng hạn, bạn không thể làm:

1=foo cmd

Hoặc là

+++=bar cmd

bash không cho phép bạn làm:

SHELLOPTS=xtrace cmd

Trong khi bạn có thể làm:

env 1=foo cmd
env +++=bar cmd
env '=baz' cmd

(không phải là bạn muốn hoặc nên muốn làm điều đó). Hoặc là:

env SHELLOPTS=xtrace cmd

(Đôi khi tôi cần phải làm điều đó).

Lưu ý rằng với envbạn vẫn không thể vượt qua chuỗi biến môi trường không chứa =(không phải là bạn muốn làm điều đó).


2

Một cách sử dụng envlà cho phép $PATHtìm kiếm các tệp thực thi trong các dòng shebang (vì envxem xét $PATHkhi tìm kiếm tệp thực thi). Điều này rất hữu ích nếu tệp thực thi bạn muốn gọi có thể ở các vị trí khác nhau trên các máy khác nhau. Ví dụ,

#!/usr/bin/env perl

trong dòng đầu tiên của tập lệnh có tập bit thực thi sẽ thực thi tập lệnh này với Perl bất kể nó được cài đặt /usr/bin/perltrong /usr/local/bin/perlhoặc ở một nơi hoàn toàn khác, miễn là thư mục nằm trong đường dẫn.

Tất nhiên, tìm kiếm đường dẫn đi kèm với rủi ro gia tăng, nhưng sau đó, rủi ro không lớn hơn nếu bạn đã viết rõ ràng perl yourscript.pl, điều này cũng tìm kiếm perl trong đường dẫn tìm kiếm.


2

Một lần khác khi envthực sự hữu ích là nếu bạn muốn kiểm soát hoàn toàn môi trường. Tôi chạy một chương trình máy chủ (Informix, trong trường hợp bạn không thể đoán) có môi trường mà tôi muốn kiểm soát hoàn toàn. Tôi chạy nó bằng cách sử dụng envở cuối tập lệnh, đặt một loạt các biến thành các giá trị chính xác:

env -i HOME="$IXD" \
       INFORMIXDIR="$IXD" \
       INFORMIXSERVER="$IXS" \
       ${IXC:+INFORMIXCONCSMCFG="$IXC"} \
       ${IXH:+INFORMIXSQLHOSTS="$IXH"} \
       IFX_LISTEN_TIMEOUT=3 \
       ONCONFIG="onconfig.$IXS" \
       PATH="/bin:/usr/bin:$IXD/bin" \
       SHELL=/bin/ksh \
       TZ=UTC0 \
    $ONINIT "$@"

Các -itùy chọn hạ gục các môi trường hiện tại. Các VAR=valuetùy chọn tiếp theo đặt các biến môi trường mà tôi muốn đặt; tên của chương trình nằm trong $ONINITvà bất kỳ đối số dòng lệnh nào được truyền qua nguyên văn với "$@".

Cấu ${IXH:+INFORMIXSQLHOSTS="$IXH"}trúc chỉ chuyển INFORMIXSQLHOSTS="$IXH"đến envnếu $IXHđược đặt thành giá trị không trống.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.