Vấn đề, được xem lại
Thành thật mà nói, hướng dẫn sử dụng là khó hiểu về điểm này. Các thủ GNU Bash nói:
Môi trường cho bất kỳ lệnh hoặc chức năng đơn giản nào [lưu ý rằng điều này không bao gồm nội trang] có thể được tăng cường tạm thời bằng cách thêm tiền tố cho nó với các phép gán tham số, như được mô tả trong Tham số Shell. Các câu lệnh gán này chỉ ảnh hưởng đến môi trường được thấy bởi lệnh đó.
Nếu bạn thực sự phân tích cú pháp câu, điều nó nói là môi trường cho lệnh / hàm được sửa đổi, nhưng không phải là môi trường cho tiến trình mẹ. Vì vậy, điều này sẽ hoạt động:
$ TESTVAR=bbb env | fgrep TESTVAR
TESTVAR=bbb
bởi vì môi trường cho lệnh env đã được sửa đổi trước khi nó được thực thi. Tuy nhiên, điều này sẽ không hoạt động:
$ set -x; TESTVAR=bbb echo aaa $TESTVAR ccc
+ TESTVAR=bbb
+ echo aaa ccc
aaa ccc
vì khi mở rộng tham số được thực hiện bởi shell.
Các bước thông dịch viên
Một phần khác của vấn đề là Bash xác định các bước sau cho trình thông dịch của nó:
- Đọc đầu vào của nó từ một tệp (xem Tập lệnh Shell), từ một chuỗi được cung cấp dưới dạng đối số cho tùy chọn gọi -c (xem Dấu gạch ngang mời) hoặc từ thiết bị đầu cuối của người dùng.
- Ngắt đầu vào thành các từ và toán tử, tuân theo các quy tắc trích dẫn được mô tả trong Trích dẫn. Các mã thông báo này được phân tách bằng ký tự siêu. Mở rộng bí danh được thực hiện theo bước này (xem Bí danh).
- Phân tích cú pháp mã thông báo thành các lệnh đơn giản và phức hợp (xem Lệnh Shell).
- Thực hiện các mở rộng shell khác nhau (xem Mở rộng Shell), chia các mã thông báo được mở rộng thành danh sách các tên tệp (xem Mở rộng Tên tệp) và các lệnh và đối số.
- Thực hiện mọi chuyển hướng cần thiết (xem Chuyển hướng) và xóa các toán tử chuyển hướng và toán hạng của chúng khỏi danh sách đối số.
- Thực thi lệnh (xem Thực thi lệnh).
- Tùy chọn đợi lệnh hoàn thành và thu thập trạng thái thoát của nó (xem Trạng thái thoát).
Điều đang xảy ra ở đây là các nội trang không có được môi trường thực thi của riêng chúng, vì vậy chúng không bao giờ thấy môi trường được sửa đổi. Bên cạnh đó, các lệnh đơn giản (ví dụ như / bin / echo) làm được một ennvironment sửa đổi (đó là lý do ví dụ env làm việc) nhưng việc mở rộng vỏ đang diễn ra trong hiện tại môi trường trong bước # 4.
Nói cách khác, bạn không chuyển 'aaa $ TESTVAR ccc' tới / bin / echo; bạn đang chuyển chuỗi nội suy (như được mở rộng trong môi trường hiện tại) đến / bin / echo. Trong trường hợp này, vì môi trường hiện tại không có TESTVAR , bạn chỉ cần chuyển 'aaa ccc' vào lệnh.
Tóm lược
Tài liệu có thể rõ ràng hơn rất nhiều. Điều tốt là có Stack Overflow!
Xem thêm
http://www.gnu.org/software/bash/manual/bashref.html#Command-Execution-Enosystem