2016-10-14 29 views
12

Làm cách nào để in biến môi trường vừa được thiết lập?Làm thế nào để in/echo biến môi trường?

NAME=sam echo "$NAME" # empty 

Bạn có thể xem tại đây bằng cách sử dụng eval hoạt động. Đây có phải là cách?

NAME=sam eval 'echo $NAME' # => sam 
+2

'NAME = sam echo whatever' không thay đổi giá trị của' NAME' trong trình bao. – rici

Trả lời

16

Những cần phải đi như các lệnh khác nhau ví dụ:

NAME=sam; echo "$NAME" 
NAME=sam && echo "$NAME" 

Việc mở rộng $NAME để chuỗi rỗng được thực hiện bởi vỏ trước đó, trước khi chạy echo, vì vậy vào thời điểm đó biến NAME được chuyển cho môi trường lệnh của echo, việc mở rộng đã được thực hiện (thành chuỗi rỗng).

Để có được kết quả tương tự trong một lệnh:

NAME=sam printenv NAME 
+0

Tôi đã thêm một ghi chú về 'printenv'. Hy vọng nó là OK, @heemayl –

+0

@AaronMcDaid Cảm ơn, đã xóa dự phòng 'env'. – heemayl

+1

Lưu ý rằng chỉ lệnh 'printenv' dựa trên duy trì ngữ nghĩa của lệnh OP: xác định' NAME' là biến môi trường _command-scoped_, chỉ lệnh được gọi và các tiến trình con của nó thấy, nhưng không có lệnh shell tiếp theo. Các lệnh khác làm điều gì đó rất khác: chúng định nghĩa 'NAME' như một biến chỉ _until-the-current-shell-exits shell-only_, tất cả các lệnh _shell_ tiếp theo sẽ thấy, nhưng _no các tiện ích bên ngoài_. – mklement0

2

này hoạt động quá, với dấu chấm phẩy.

NAME=sam; echo $NAME

2

Cú pháp

variable=value command 

thường được sử dụng để thiết lập một biến môi trường cho một quá trình cụ thể. Tuy nhiên, bạn phải hiểu quy trình nào nhận được biến nào và ai diễn giải nó. Ví dụ: sử dụng hai vỏ:

a=5 
# variable expansion by the current shell: 
a=3 bash -c "echo $a" 
# variable expansion by the second shell: 
a=3 bash -c 'echo $a' 

Kết quả sẽ là 5 cho tiếng vang đầu tiên và 3 cho giây thứ hai.

2

Để mang lại câu trả lời hiện cùng với một giải thích quan trọng:

Như đã trình bày, vấn đề với NAME=sam echo "$NAME"$NAME được mở rộng bằng vỏ hiện trước phân NAME=sam có hiệu lực.

Giải pháp mà bảo toàn ngữ nghĩa gốc (của (không hiệu quả) cố gắng giải pháp NAME=sam echo "$NAME"):

Sử dụng một trong hai eval[1] (như trong câu hỏi chính nó), hoặc printenv (như bổ sung bởi Aaron McDaid để heemayl's answer), hoặc bash -c (từ Ljm Dullaart's answer), thứ tự giảm dần hiệu quả:

NAME=sam eval 'echo "$NAME"' # use `eval` only if you fully control the command string 
NAME=sam printenv NAME 
NAME=sam bash -c 'echo "$NAME"' 

printenv không phải là một tiện ích POSIX, nhưng nó có sẵn trên cả Linux và macOS/BSD.

gì phong cách này gọi (<var>=<name> cmd ...) làm là xác định NAME:

  • như một môi trường biến
  • đó là chỉ định nghĩa cho các lệnh được gọi.

Nói cách khác: NAME chỉ tồn tại cho lệnh được gọi, và không có tác dụng trên vỏ hiện (nếu không có biến có tên NAME tồn tại trước, sẽ có không sau; một preexisting NAME cốt biến không đổi).

POSIX xác định các quy tắc cho loại yêu cầu này trong chương Command Search and Execution.


Các giải pháp sau đây làm việc rất khác nhau (từ heemayl's answer):

NAME=sam; echo "$NAME" 
NAME=sam && echo "$NAME" 

Trong khi họ sản xuất cùng đầu ra, họ thay vì xác định:

  • một vỏ biến số NAME (chỉ) chứ không phải là một môi trường biến
    • nếu echo là một lệnh mà dựa vào môi trường biến NAME, nó sẽ không được xác định (hoặc có khả năng định nghĩa khác nhau từ trước đó).
  • rằng sống trên sau lệnh.

Lưu ý rằng tất cả các biến môi trường cũng được tiếp xúc như là một biến vỏ, nhưng ngược lại là không đúng sự thật: các biến shell chỉ hiển thị cho vỏ hiện tại và subshells của nó, nhưng không để tiến trình con, chẳng hạn như các tiện ích bên ngoài và các tập lệnh (không có nguồn gốc) (trừ khi chúng được đánh dấu là biến môi trường với export hoặc declare -x).


[1] Về mặt kỹ thuật, bash là vi phạm POSIX đây (như là zsh): Kể từ khi eval là một đặc biệt vỏ tích hợp, trước đó NAME=sam phân công nên gây ra các biến $NAME để duy trì trong phạm vi sau khi lệnh kết thúc, nhưng đó không phải là những gì sẽ xảy ra.
Tuy nhiên, khi bạn chạy bash ở chế độ tương thích POSIX, nó là tuân thủ.
dashksh luôn tuân thủ.
Các quy tắc chính xác rất phức tạp và một số khía cạnh còn lại để triển khai để quyết định; một lần nữa, xem Command Search and Execution.

Các vấn đề liên quan