Khi tôi đọc câu hỏi của bạn, suy nghĩ đầu tiên của tôi là $SHLVL
. Sau đó, tôi thấy rằng bạn muốn đếm vim
cấp độ
ngoài cấp độ vỏ. Một cách đơn giản để làm điều này là xác định hàm shell:
vim() { ( ((SHLVL++)); command vim "$@");}
Điều này sẽ tự động và âm thầm tăng lên SHLVL
mỗi khi bạn gõ một vim
lệnh. Bạn sẽ cần phải làm điều này cho từng biến thể của vi
/ vim
mà bạn từng sử dụng; ví dụ,
vi() { ( ((SHLVL++)); command vi "$@");}
view() { ( ((SHLVL++)); command view "$@");}
Tập hợp dấu ngoặc đơn bên ngoài tạo ra một lớp con, do đó, thay đổi thủ công trong giá trị của SHLVL
không làm nhiễm bẩn môi trường vỏ (cha mẹ) hiện tại. Tất nhiên command
từ khóa là có để ngăn các hàm tự gọi (điều này sẽ dẫn đến một vòng lặp đệ quy vô hạn). Và tất nhiên bạn nên đặt các định nghĩa này vào .bashrc
tệp khởi tạo shell của bạn hoặc khác.
Có một chút không hiệu quả ở trên. Trong một số shell (bash là một), nếu bạn nói
( Cmd 1 ; cmd 2 ; ... ; cmd n )
trong đó là một chương trình thực thi bên ngoài (nghĩa là không phải là lệnh tích hợp), shell giữ một quá trình bổ sung nằm xung quanh, chỉ để chờ kết thúc. Điều này (được cho là) không cần thiết; những lợi thế và bất lợi đang tranh cãi. Nếu bạn không phiền khi buộc một chút bộ nhớ và khe quá trình (và để xem thêm một quy trình shell hơn bạn cần khi bạn thực hiện a ), thì hãy làm như trên và chuyển sang phần tiếp theo. Ditto nếu bạn đang sử dụng một vỏ không giữ quá trình thêm nằm xung quanh. Nhưng, nếu bạn muốn tránh quá trình bổ sung, điều đầu tiên cần thử làcmdn
cmdn
ps
vim() { ( ((SHLVL++)); exec vim "$@");}
Các exec
lệnh ở đó để ngăn chặn quá trình shell thêm từ kéo dài.
Nhưng, có một vấn đề. Cách xử lý của shell SHLVL
có phần trực quan: Khi shell khởi động, nó sẽ kiểm tra xem đã SHLVL
được đặt chưa. Nếu nó không được đặt (hoặc được đặt thành một số khác với một số), shell sẽ đặt nó thành 1. Nếu nó được đặt (thành một số), shell sẽ thêm 1 vào nó.
Nhưng, theo logic này, nếu bạn nói exec sh
, bạn SHLVL
nên đi lên. Nhưng đó là điều không mong muốn, bởi vì mức độ vỏ thực sự của bạn đã không tăng lên. Shell xử lý việc này bằng cách trừ đi một từ SHLVL
khi bạn thực hiện exec
:
$ echo "$SHLVL"
1
$ set | grep SHLVL
SHLVL=1
$ env | grep SHLVL
SHLVL=1
$ (env | grep SHLVL)
SHLVL=1
$ (env) | grep SHLVL
SHLVL=1
$ (exec env) | grep SHLVL
SHLVL=0
Vì thế
vim() { ( ((SHLVL++)); exec vim "$@");}
là nước rửa; nó SHLVL
chỉ tăng để giảm nó một lần nữa. Bạn cũng có thể chỉ nói vim
, mà không có lợi ích của một chức năng.
Lưu ý:
Theo Stéphane Chazelas (người biết tất cả mọi thứ) , một số vỏ đủ thông minh để không làm điều này nếu exec
nó nằm trong một vỏ con.
Để khắc phục điều này, bạn sẽ làm
vim() { ( ((SHLVL+=2)); exec vim "$@");}
Sau đó, tôi thấy rằng bạn muốn đếm vim
cấp độ
độc lập với cấp độ vỏ. Vâng, thủ thuật chính xác tương tự hoạt động (tốt, với một sửa đổi nhỏ):
vim() { ( ((SHLVL++, VILVL++)); export VILVL; exec vim "$@");}
(và vân vân cho vi
, view
vv) Các export
là cần thiết vì VILVL
không được định nghĩa như là một biến môi trường bằng cách mặc định. Nhưng nó không cần phải là một phần của chức năng; bạn chỉ có thể nói export VILVL
như một lệnh riêng biệt (trong của bạn .bashrc
). Và, như đã thảo luận ở trên, nếu quy trình bổ sung không phải là vấn đề đối với bạn, bạn có thể thực hiện command vim
thay vì exec vim
và để SHLVL
yên:
vim() { ( ((VILVL++)); command vim "$@");}
Sở thích cá nhân:
Bạn có thể muốn đổi tên VILVL
thành một cái gì đó như VIM_LEVEL
. Khi tôi nhìn vào đỉnh điểm VILVL
, mắt tôi đau nhói; họ không thể biết đó là lỗi chính tả của vinyl vinyl hay một chữ số La Mã không đúng.
Nếu bạn đang sử dụng trình bao không hỗ trợ SHLVL
(ví dụ: dấu gạch ngang), bạn có thể tự thực hiện nó miễn là trình bao thực hiện tệp khởi động. Chỉ cần làm một cái gì đó như
if [ "$SHELL_LEVEL" = "" ]
then
SHELL_LEVEL=1
else
SHELL_LEVEL=$(expr "$SHELL_LEVEL" + 1)
fi
export SHELL_LEVEL
trong .profile
tập tin của bạn hoặc áp dụng. (Bạn có thể không nên sử dụng tên này SHLVL
, vì điều đó sẽ gây ra sự hỗn loạn nếu bạn bắt đầu sử dụng shell hỗ trợ SHLVL
.)
Các câu trả lời khác đã giải quyết vấn đề nhúng (các) giá trị biến môi trường vào dấu nhắc shell của bạn, vì vậy tôi sẽ không lặp lại điều đó, đặc biệt là bạn nói rằng bạn đã biết cách thực hiện.
$SHLVL
biến (được duy trì bởi một số shell) những gì bạn đang tìm kiếm?