Làm cách nào để đặt biến môi trường chỉ trong thời lượng của tập lệnh?


127

Trên Linux (Ubuntu 11.04) trong bash, có thể tạm thời đặt một biến môi trường sẽ chỉ khác với biến thông thường trong thời lượng của tập lệnh không? Ví dụ: trong tập lệnh shell, tạo một ứng dụng lưu vào HOME di động bằng cách tạm thời đặt HOME vào một thư mục trong thư mục làm việc hiện tại, sau đó khởi chạy ứng dụng.


5
Sẽ khó hơn nếu bạn muốn cài đặt kéo dài quá thời lượng của tập lệnh
Nemo

Câu trả lời:


119
VAR1=value1 VAR2=value2 myScript args ...

2
Tôi đã làm điều này bản thân nhiều lần để chạy vblank_mode=0 glxgears. Nó hoạt động, nhưng nó cũng cho biết vblank_mode=0: command not foundsau khi chạy, trong khi việc chuẩn bị trước envkhông gây ra điều này. [thử nghiệm ...] Rõ ràng zsh không thích nó (nhưng vẫn sử dụng chính xác), nhưng bash vẫn ổn với nó. Tôi đoán tôi sẽ đi theo envphương pháp từ bây giờ.
Chinoto Vokro

2
với các kịch bản nó hoạt động nhưng làm thế nào về VAR1="hello" echo $VAR1không trả lại bất cứ điều gì?
Zibri

2
@Zibri là về việc mở rộng đang diễn ra. Có lẽ bạn có thể làm một cái gì đó như thế:VAR1="hello" bash -c 'echo $VAR1'
cybergrind

Upvote cho thấy rằng điều này là có thể ngay cả đối với nhiều biến môi trường.
Binarus

70
env VAR=value myScript args ...

18
HoặcVAR=value myScript args ...
Rockallite

9
1. Làm thế nào PATH=$PATH:XYZ echo $PATH | grep XYZmà không có bất kỳ đầu ra mặc dù? 2. Sự khác biệt giữa sử dụng và không sử dụng là envgì?
qubodup

18
bởi vì shell mở rộng biến PATH trước khi thực hiện lệnh echo. Bạn cần trì hoãn việc mở rộng đó. Một cách: PATH=$PATH:XYZ sh -c 'echo $PATH' | grep XYZ- các trích dẫn duy nhất là chìa khóa ở đây
glenn jackman

14
Sự khác biệt giữa sử dụng envvà không sử dụng nó là gì?
Mohammed Noureldin

Điều này dường như không hoạt động trong một oneliner nhưIFS=$'\n' for l in lines; do ... done
drevicko

31

Chỉ cần đặt

export HOME=/blah/whatever

tại điểm trong kịch bản mà bạn muốn thay đổi xảy ra. Vì mỗi quá trình có tập hợp các biến môi trường riêng, định nghĩa này sẽ tự động chấm dứt có bất kỳ ý nghĩa nào khi tập lệnh kết thúc (và với nó là trường hợp bash có môi trường thay đổi).


11
Điều đó gây hiểu lầm. exportsẽ chuyển biến cho các lớp con, nhưng nó không điều khiển shell cha. Nếu bạn đang viết một tập lệnh bắt đầu bằng "#! / Bin / sh" hoặc tương tự, BẤT K biến biến nào bạn đặt sẽ biến mất khi tập lệnh thoát.
litlancer

1
@brightlancer, điều đó đúng nhưng không có vẻ mâu thuẫn với bất cứ điều gì tôi đã viết. (Ngoại trừ khả năng tập lệnh có thể bắt đầu một quá trình nền, nhưng tôi nghĩ rằng điều đó vượt quá mức độ tinh vi của OP và sẽ chỉ gây nhầm lẫn).
hmakholm còn lại của Monica

5
Việc xuất khẩu là không cần thiết. Ngoài ra, câu trả lời của bạn chỉ hoạt động nếu tập lệnh của anh ta gọi trình thông dịch (#! / Bin / sh hoặc tương tự). Nếu "kịch bản" của anh ấy không có, thì những gì bạn vừa nói với anh ấy sẽ tiếp tục vượt quá cuối kịch bản của anh ấy. Đó là lý do tại sao tôi nói câu trả lời của bạn sai lệch - nó có thể đúng, có thể không, nhưng chắc chắn nó có một phần không cần thiết và khó hiểu bởi vì nó có thể khiến ai đó nghĩ rằng "xuất khẩu" là yếu tố cần thiết mà anh ta đang tìm kiếm.
litlancer

7
@brightlancer: Việc xuất là cần thiết nếu tập lệnh của OP gọi các tập lệnh con mà chúng phụ thuộc vào $ HOME và tôi không dám cho rằng đó không phải là trường hợp. Hơn nữa, bash sẽ sinh ra một lớp con để chạy tập lệnh ngay cả khi tập lệnh không có dòng shebang mà chỉ là một tệp văn bản với tập bit thực thi. Hãy thử nó - các phép gán biến trong tập lệnh không hiển thị trong trình bao bạn gọi nó từ đó. Chỉ khi bạn rõ ràng sourcetập lệnh mà nó sẽ được thực thi bởi cùng một shell mà bạn nhập lệnh vào.
hmakholm còn lại của Monica

4
@brightlancer: Việc xuất là cần thiết nếu anh ta muốn $HOMEđược kế thừa bởi bất kỳ lệnh nào được thực thi từ tập lệnh. Và nếu anh ta không làm như vậy, và thiết lập $HOMEchỉ là vì lợi ích của chính kịch bản, thì có lẽ anh ta nên sửa đổi kịch bản để nó đề cập đến một cái gì đó khác hơn $HOME.
Keith Thompson
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.