Tôi quan tâm đến việc thiết lập các biến môi trường của một thể hiện shell từ một thể hiện khác. Vì vậy, tôi quyết định thực hiện một số nghiên cứu. Sau khi đọc một số các câu hỏi về này tôi đã quyết định để kiểm tra nó ra.
Tôi sinh ra hai vỏ A và B (PID 420), cả hai đều chạy zsh
. Từ vỏ AI chạy như sau.
sudo gdb -p 420
(gdb) call setenv("FOO", "bar", 1)
(gdb) detach
Từ shell B khi tôi chạy, env
tôi có thể thấy biến FOO thực sự được đặt với giá trị của thanh. Điều này khiến tôi nghĩ rằng FOO đã được khởi tạo thành công trong môi trường shell B. Tuy nhiên, nếu tôi cố in FOO, tôi nhận được một dòng trống có nghĩa là nó không được đặt. Đối với tôi, nó cảm thấy như có một mâu thuẫn ở đây.
Điều này đã được thử nghiệm trên cả hệ thống Arch GNU / Linux của riêng tôi và máy ảo Ubuntu. Tôi cũng đã thử nghiệm này trên bash
nơi biến thậm chí không hiển thị trong env. Điều này mặc dù làm tôi thất vọng, có ý nghĩa nếu cái vỏ lưu trữ một bản sao của môi trường của nó tại thời điểm sinh sản và chỉ sử dụng nó (được đề xuất trong một trong những câu hỏi được liên kết). Điều này vẫn không trả lời tại sao zsh
có thể nhìn thấy biến.
Tại sao đầu ra của echo $FOO
sản phẩm nào?
BIÊN TẬP
Sau khi nhập ý kiến, tôi quyết định thử nghiệm thêm một chút. Các kết quả có thể được nhìn thấy trong các bảng dưới đây. Trong cột đầu tiên là vỏ mà FOO
biến được đưa vào. Hàng đầu tiên chứa lệnh có đầu ra có thể được nhìn thấy bên dưới nó. Biến FOO
được tiêm bằng cách sử dụng : sudo gdb -p 420 -batch -ex 'call setenv("FOO", "bar", 1)'
. Các lệnh cụ thể cho zsh: zsh -c '...'
cũng được kiểm tra bằng bash. Kết quả giống hệt nhau, đầu ra của chúng bị bỏ qua cho ngắn gọn.
Arch GNU / Linux, zsh 5.3.1, bash 4.4.12 (1)
| | env | grep FOO | echo $FOO | zsh -c 'env | grep FOO' | zsh -c 'echo $FOO' | After export FOO |
|------|------------------|-----------|---------------------------|----------------------|-----------------------------------|
| zsh | FOO=bar | | FOO=bar | bar | No Change |
| bash | | bar | | | Value of FOO visible in all tests |
Ubuntu 16.04.2 LTS, zsh 5.1.1, bash 4.3.48 (1)
| | env | grep FOO | echo $FOO | zsh -c 'env | grep FOO' | zsh -c 'echo $FOO' | After export FOO |
|------|------------------|-----------|---------------------------|----------------------|-----------------------------------|
| zsh | FOO=bar | | FOO=bar | bar | No Change |
| bash | | bar | | | Value of FOO visible in all tests |
Ở trên dường như ngụ ý rằng các kết quả là bất khả tri phân phối. Điều này không cho tôi biết nhiều hơn zsh
và bash
xử lý cài đặt các biến khác nhau. Hơn nữa, export FOO
có hành vi rất khác nhau trong bối cảnh này tùy thuộc vào vỏ. Hy vọng rằng những bài kiểm tra này có thể làm cho một cái gì đó rõ ràng cho người khác.
env
) sẽ thấy môi trường được sửa đổi.
zsh
trong GDB không làm cho nó hiển thị dưới dạng biến shell nhưng lại khiến nó được truyền cho các tiến trình con (như bạn đã quan sát), trong khi thiết lập một cho bash
nó làm cho nó hiển thị dưới dạng biến shell nhưng không khiến nó được truyền cho các tiến trình con! Dường như zsh và bash sử dụng các chiến lược khác nhau để quản lý các biến, với zsh theo dõi các biến không thuộc môi trường và bash lưu trữ mọi thứ trong môi trường của nó mà nó vệ sinh khi khởi chạy một đứa trẻ (không phải là con).
export FOO
vào bash
?
zsh -c 'echo $FOO'
(sử dụng dấu ngoặc đơn!) Thay vào đó? Bạn có thể nhìn thấy nó sau đó?