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
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
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
Tôi đã thêm một ghi chú về 'printenv'. Hy vọng nó là OK, @heemayl –
@AaronMcDaid Cảm ơn, đã xóa dự phòng 'env'. – heemayl
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
này hoạt động quá, với dấu chấm phẩy.
NAME=sam; echo $NAME
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.
Để 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"
là $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
:
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:
NAME
(chỉ) chứ không phải là một môi trường biến
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 đó).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ủ.
dash
và ksh
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.
'NAME = sam echo whatever' không thay đổi giá trị của' NAME' trong trình bao. – rici