Làm thế nào để gọi một shell được tích hợp rõ ràng?


13

Tôi muốn tùy chỉnh chức năng của cdlệnh theo nhu cầu của tôi.

Tôi đã định nghĩa hàm sau - function cd () { cd "$@" && pushd "$@"; }

Mục đích của chức năng này là tự động đẩy thư mục lên ngăn xếp để nó giúp tôi tiết kiệm công sức để gõ thủ công pushd .mỗi lần.

Tuy nhiên, hàm trên là một hàm đệ quy vô hạn, vì lệnh gọi cdđược hiểu là chính hàm đó chứ không phải là hàm tích cdhợp.

Làm thế nào để tôi tham chiếu tích cdhợp trong chức năng này?

Tôi biết rằng bí danh có thể được thoát bằng cách sử dụng \. Cách để thoát các chức năng hoặc tham chiếu được xây dựng theo cách rõ ràng hơn là gì?

Lưu ý: Tôi không muốn đổi tên chức năng của mình thành bất kỳ điều gì khác.


3
Tại sao không chỉ alias cd=pushd? Bạn mong đợi điều gì sẽ xảy ra khi bạn cd vào thứ gì đó không phải là một đường dẫn tuyệt đối (ví dụ cd ../:)?
Patrick

@Patrick pushdkhông hỗ trợ -P. Nhưng bạn đã đúng, như thể hiện trong câu hỏi có function cdvẻ hơi sai, vì nó đã thay đổi thư mục hai lần.
Tino

Câu trả lời:


5

Hàm commanddựng sẵn buộc một tên lệnh được hiểu là một lệnh tích hợp hoặc bên ngoài (bỏ qua bí danh và tra cứu hàm). Nó có sẵn trong tất cả các vỏ POSIX bao gồm cả bash.

cd () { command cd "$@" && pushd "$@"; }

(Lưu ý rằng ví dụ này là một ví dụ tồi: nó không hoạt động với các đường dẫn tương đối và bạn cũng có thể chỉ cần gõ pushdở vị trí đầu tiên.)

Trong bash và zsh (nhưng không phải ksh), bạn có thể sử dụng builtinđể buộc một tên lệnh được hiểu là một nội trang, không bao gồm bí danh, hàm và các lệnh bên ngoài.


16

Bash có một lệnh (dựng sẵn) builtin, thực hiện chính xác những gì bạn cần. Thay thế cdbằng builtin cdtrong chức năng của bạn sẽ sửa chữa đệ quy.


1

Tôi nghi ngờ khi bạn nói rằng bạn "không muốn đổi tên chức năng của mình thành bất kỳ điều gì khác", bạn có nghĩa là bạn muốn có thể gọi chức năng của mình bằng cùng tên với lệnh ban đầu.

Vì vậy, một cách khác để làm điều này cũng hoạt động đối với những thứ không được tích hợp sẵn, là đặt tên cho chức năng của bạn một cái gì đó khác, sau đó xác định bí danh cho lệnh được bọc. Điều này hoạt động vì bí danh không tồn tại trong ngữ cảnh thực thi chức năng của bạn.

Ví dụ Wrapper.sh:

#!/bin/bash
function my_wrapper() { wrapped_program $@ && dostuff }

Và trong, ví dụ: .bash_aliases:

source /path/to/wrapper.sh
alias wrapped_program="my_wrapper"

Nhưng điều này là khá hacky. Sử dụng commandlà tốt hơn khi có thể.


-1

Để làm việc với các đường dẫn tương đối, cần có những điều sau đây:

function cd { 
   dir="$(realpath "$@")"
   command cd "$dir"
   pushd "$dir"
}

Điều này giả định rằng bạn đang ở trên một bản phân phối Linux đủ hiện đại có chứa tiện ích 'realpath'. (Chẳng hạn như RHEL 6). Nếu Perl khả dụng, 'realpath' có thể được mô phỏng bằng cách sử dụng:

! realpath $(pwd) > /dev/null 2>&1  && function realpath {
    perl -e "use Cwd realpath; print realpath(\"$1\") . \"\\n\";"
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.