Dưới đây là một số cách giải quyết:
$ comm -3 <(declare | sort) <(declare -f | sort)
phá vỡ:
declare
in mọi biến được xác định (xuất hoặc không) và hàm.
declare -f
chỉ in các chức năng.
comm -3
sẽ loại bỏ tất cả các dòng chung cho cả hai. Trong thực tế, điều này sẽ loại bỏ các chức năng, chỉ để lại các biến.
Để chỉ in các biến không được xuất:
$ comm -3 <(comm -3 <(declare | sort) <(declare -f | sort)) <(env | sort)
Một cách giải quyết khác:
$ declare -p
Điều này sẽ chỉ in các biến, nhưng với một số thuộc tính xấu.
declare -- BASH="/bin/bash"
declare -ir BASHPID=""
declare -A BASH_ALIASES='()'
declare -a BASH_ARGC='()'
...
Bạn có thể cắt các thuộc tính bằng cách sử dụng ... cắt:
$ declare -p | cut -d " " -f 3
Một nhược điểm là giá trị của IFS được diễn giải thay vì hiển thị.
so sánh:
$ comm -3 <(declare | sort) <(declare -f | sort)
...
IFS=$' \t\n'
...
$ declare -p | cut -d " " -f 3
...
IFS="
"
...
Điều này làm cho nó khá khó để sử dụng đầu ra đó để xử lý thêm, vì nó đơn độc "
trong một dòng. Có lẽ một số IFS-fu có thể được thực hiện để ngăn chặn điều này.
Một cách giải quyết khác, sử dụng compgen
:
$ compgen -v
Nội dung bash compgen
có nghĩa là được sử dụng trong các kịch bản hoàn thành. Để kết thúc này, compgen -v
liệt kê tất cả các biến được xác định. Nhược điểm: nó chỉ liệt kê các tên biến, không phải các giá trị.
Đây là một hack để liệt kê các giá trị.
$ compgen -v | while read var; do printf "%s=%q\n" "$var" "${!var}"; done
Ưu điểm: nó là một giải pháp bash tinh khiết. Nhược điểm: một số giá trị bị rối vì giải thích thông qua printf
. Ngoài ra, lớp con từ đường ống và / hoặc vòng lặp thêm một số biến phụ.