Chạy một tệp thực thi trong PATH có cùng tên với một hàm hiện có


16

Đôi khi tôi định nghĩa một hàm làm mờ một tệp thực thi và điều chỉnh các đối số hoặc đầu ra của nó. Vì vậy, hàm có cùng tên với tệp thực thi và tôi cần một cách để chạy tệp thực thi từ hàm mà không gọi hàm đệ quy. Ví dụ: để tự động chạy đầu ra fossil diffthông qua colordiffless -Rtôi sử dụng:

function fossil () {
    local EX=$(which fossil)
    if [ -z "$EX" ] ; then
        echo "Unable to find 'fossil' executable." >&2
        return 1
    fi
    if [ -t 1 ] && [ "$1" == "diff" ] ; then
        "$EX" "$@" | colordiff | less -R
        return
    fi
    "$EX" "$@"
}

Nếu tôi chắc chắn về vị trí thực thi, tôi có thể chỉ cần gõ /usr/bin/fossil. Bash nhận ra điều đó /có nghĩa là lệnh đó là một lệnh thực thi, không phải là hàm. Nhưng vì tôi không biết chính xác vị trí, tôi phải dùng đến cách gọi whichvà kiểm tra kết quả. đó có phải là cách dễ hơn?


1
Bạn nói, Bash Bash nhận ra điều đó /có nghĩa là lệnh là một lệnh thực thi, không phải là một chức năng. Nói một cách nghiêm túc, điều đó không đúng. Trong những gì tôi tin là một quyết định thiết kế khủng khiếp (và không có giấy tờ), bash cho phép các tên hàm chứa dấu gạch chéo. Các dấu gạch chéo chỉ đơn giản /usr/bin/fossillà một chuỗi khác với fossil, vì vậy, khi bạn nói /usr/bin/fossil, nó không cố chạy fossilhàm.
G-Man nói 'Phục hồi Monica'

Câu trả lời:


19

Sử dụng commandvỏ dựng sẵn:

bash-4.2$ function date() { echo 'at the end of days...'; }

bash-4.2$ date
at the end of days...

bash-4.2$ command date
Mon Jan 21 16:24:33 EET 2013

bash-4.2$ help command
command: command [-pVv] command [arg ...]
    Execute a simple command or display information about commands.

    Runs COMMAND with ARGS suppressing  shell function lookup, or display
    information about the specified COMMANDs.  Can be used to invoke commands
    on disk when a function with the same name exists.

2
Thêm một lựa chọn là thoát lệnh \date.
jordanm

4
@jordanm, chỉ hoạt động cho bí danh. Câu hỏi là về chức năng. pastebin.com/TgkHQwbb
manatwork

3

Trong các tập lệnh, #!dòng thường sử dụng /bin/env bashđể chạy lệnh bash dựa trên đường dẫn. (Nó có thể khác nhau đối với một số tiện ích). Điều này cũng sẽ làm việc ở đây ...

(Cách commandthay thế cũng sẽ hoạt động, nhưng có thể phụ thuộc vào lớp vỏ cụ thể) (Nó hoạt động trên Bourne Shell trên Solaris, nhưng nó thực sự chạy /bin/commandtrong trường hợp đó, đó là lớp vỏ tích hợp trên Bash)

Cả hai /bin/command/bin/envđược liệt kê trong SUS, vì vậy tất cả các triển khai tuân thủ nên có nó.


Cảm ơn đã chỉ ra env. Tôi đã nghi ngờ câu trả lời nào nên chấp nhận, nhưng vì câu hỏi là về bash , tích hợp của nó commandlà giải pháp tốt nhất.
Petr Pudlák

1
Trên Linux của tôi không có commandthực thi, nhưng commandcũng làm việc trong dash, kshzsh. Vì vậy, tôi cho rằng nó là một vỏ dựng sẵn không chỉ trong bash. pastebin.com/fi3gyNse
manatwork

Nó không phải là bản dựng trên Solaris 10 Bourne (Điều đó cũng có sẵn dưới dạng gia truyền). Ưu điểm của một tệp thực thi với một đường dẫn đã biết là nó không thể bị ghi đè bởi một hàm.
Gert van den Berg

(Việc không có / bin / lệnh có thể giải thích tại sao các tập lệnh sử dụng /bin/envsau hàm băm nếu chúng không muốn mã hóa đường dẫn shell)
Gert van den Berg

3

Câu trả lời của Gert khiến tôi nhận ra rằng người ta cũng có thể sử dụng nicecho mục đích này (tôi thực sự đã có nó trong một trong các kịch bản của mình mà không nhận ra nó):

$ function date() { echo 'at the end of days...'; }
$ date
at the end of days...
$ nice -n0 date
Mon Jan 21 16:45:21 CET 2013

Nó kém thanh lịch hơn các câu trả lời khác, nhưng trong một số trường hợp, nó có thể là một lựa chọn hữu ích.


Bạn có thể muốn mở rộng điều này để bao gồm một thay thế tương tự : `which date`.
Eliah Kagan

1
@EliahKagan Vấn đề với `which something`là nếu không có sự somethingthực thi, những điều đáng tiếc có thể xảy ra. Ví dụ nếu echothiếu thì `which echo` /bin/rm preciousFilelàm một cái gì đó rất khác so với dự định.
Petr Pudlák
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.