Sử dụng lệnh hệ thống thay vì dựng sẵn Bash mà không chỉ định đường dẫn đầy đủ


17

Tôi sử dụng Bash làm lớp vỏ tương tác của mình và tôi đã tự hỏi liệu có cách nào dễ dàng để Bash chạy một lệnh hệ thống thay vì lệnh dựng sẵn shell trong trường hợp cả hai đều có cùng tên.

Ví dụ: sử dụng hệ thống kill(từ util-linux) để in id quá trình (pid) của (các) tiến trình được đặt tên thay vì gửi tín hiệu:

$ /bin/kill -p httpd
2617
...

Không chỉ định đường dẫn đầy đủ của lệnh hệ thống, hàm dựng sẵn Bash được sử dụng thay cho lệnh hệ thống. Nội dung killkhông có -ptùy chọn nên lệnh không thành công:

$ kill -p httpd
bash: kill: p: invalid signal specification

Tôi đã thử các câu trả lời được liệt kê trong Make bash sử dụng lệnh `time` bên ngoài thay vì shell tích hợp nhưng hầu hết chúng chỉ hoạt động vì timethực sự là một từ khóa shell - không phải là shell dựng sẵn .

Khác với việc tạm thời vô hiệu hóa tích hợp Bash enable -n kill, giải pháp tốt nhất tôi thấy cho đến nay là sử dụng:

$(which kill) -p httpd

Có cách nào khác dễ dàng hơn (liên quan đến việc gõ ít hơn) để thực thi lệnh bên ngoài thay vì shell dựng sẵn không?

Lưu ý rằng đó killchỉ là một ví dụ và tôi muốn một giải pháp tổng quát tương tự như cách tiền tố với commandnội dung ngăn chặn các hàm có cùng tên với một lệnh bên ngoài được chạy. Trong hầu hết các trường hợp, tôi thường thích sử dụng phiên bản dựng sẵn vì nó giúp tiết kiệm một quy trình mới và đôi khi nội dung đó có các tính năng mà lệnh bên ngoài không có.


Kèm theo which killbackticks (không thể đưa chúng vào bình luận) ngắn hơn một chút .
abligh

@ableigh Điểm tốt. Tôi đã dành nhiều năm để rèn luyện bản thân để sử dụng cú pháp er "mới" để thay thế lệnh. :)
Anthony G - công lý cho Monica

@ableigh: FYI, bạn có thể đưa `backticks` vào bình luận bằng cách đặt trước chúng bằng dấu gạch chéo ngược (\). Nhưng có những lý do để gắn bó $(…)- xem cái này , cái nàycái này .
G-Man nói 'Phục hồi Monica'

Câu trả lời:


20

Giả sử envlà trong con đường của bạn:

env kill -p http

envchạy tệp thực thi được đặt tên bởi đối số đầu tiên của nó trong môi trường được sửa đổi (có thể); như vậy, nó không biết hoặc làm việc với các lệnh tích hợp shell.

Điều này tạo ra một số điều khiển công việc shell, nhưng không dựa vào lệnh bên ngoài:

exec kill -p bash &

execyêu cầu một tệp thực thi để thay thế trình bao hiện tại, do đó không sử dụng bất kỳ trình dựng sẵn nào. Công việc được chạy trong nền để bạn thay thế vỏ nền rẽ nhánh, không phải vỏ hiện tại của bạn.


2
envRõ ràng là câu trả lời đúng IMHO.
abligh

@ableigh: Bạn đã bình luận đúng trong câu trả lời đã bị xóa của tôi. command -p cmdgọi lệnh bên ngoài zsh, không bash.
cuonglm

6
(exec kill -p http)khiến công việc thay thế một vỏ phụ thay vì vỏ hiện tại của bạn và bạn không phải đối phó với hành trình kiểm soát công việc.
Michael Hoffman

1
@AnthonyGeoghegan Thật vậy, nhưng envcũng không biết về các nội dung vỏ, vì nó không phải là một vỏ. Bạn sẽ nhận được hiệu ứng tương tự với nicehoặc xargshoặc bất kỳ chương trình nào khác như thế.
dùng253751

1

Cách đơn giản nhất để làm những gì bạn muốn có thể là đặt dòng

alias kill="/bin/kill"

vào ~/.bashrctập tin của bạn . Sau đó, mỗi lần đăng nhập / gọi bash mới sẽ diễn giải "kill" là /bin/kill.


Tôi đã nghĩ về một bí danh và đó là một trong những giải pháp được liệt kê trong câu hỏi tôi liên kết với nhưng tôi hy vọng một giải pháp tổng quát hơn (tương tự như commandgiải pháp) thay vì tạo một bí danh riêng cho mỗi lệnh bóng tối của Nott. Bây giờ tôi đã chỉnh sửa câu hỏi của mình để làm cho câu hỏi này rõ ràng và rõ ràng hơn. Trong hầu hết các trường hợp, tôi thường thích sử dụng phiên bản dựng sẵn vì các quy trình có thể được chỉ định bởi ID công việc. Dẫu sao cũng xin cảm ơn.
Anthony G - công lý cho Monica

1

Nếu bạn biết một giải pháp yêu cầu một số thao tác gõ và bạn muốn một giải pháp yêu cầu ít gõ hơn, hãy xây dựng nó:

runFile() { local cmd="$1"; shift; cmd="$(which "$cmd")" && "$cmd" "$@"; }

Viết tắt những thứ thường mất một số nỗ lực là những gì máy tính vượt trội.


1
Đó là một điểm chung tốt vì vậy tôi sẽ nêu lên câu trả lời của bạn. Trong vài năm qua, tôi đã xây dựng một bộ sưu tập các bí danh, chức năng và tập lệnh cho các hệ thống mà tôi thường xuyên sử dụng. Tuy nhiên, tôi thích sử dụng các giải pháp không tùy chỉnh khi có thể vì đôi khi tôi phải làm việc trên các bản cài đặt hoặc máy chủ mới mà tôi chưa thiết lập. Cảm ơn.
Anthony G - công lý cho Monica

1

Trong trường hợp rất cụ thể này, lệnh pgreplà một kết hợp chính xác cho nhu cầu.

Trong một ý nghĩa chung, một chức năng hoạt động. Từ "lệnh tập tin":

fcmd(){ local a=$1; shift; $(which "$a") "$@"; }

gọi như

fcmd kill -p httpd

Nhưng nếu bạn cần gõ ít hơn, không có cách nào ngắn hơn bí danh tốt.

Từ khái niệm "danh sách pid" (lp):

alias lp='/bin/kill -p'

sau đó, chỉ cần gõ:

lp httpd

0

(Trong zsh) Bạn có thể thêm tiền tố vào bất kỳ tên lệnh nào có dấu = để lấy phiên bản hệ thống thay vì dựng sẵn. Đây cũng là một cách thuận tiện để tránh bất kỳ bí danh nào làm rối tung một kịch bản cụ thể.

$ =kill -p httpd

1
Tôi đã thử điều đó với Bash phiên bản 4.3.30 và nó không hoạt động. Tôi chưa bao giờ thấy cú pháp như vậy trước đây; bạn có thể thêm một liên kết đến nơi tính năng này được ghi lại không? Tôi thường tiền tố một bí danh với dấu gạch chéo ngược để chạy phiên bản không bí danh của lệnh.
Anthony G - công lý cho Monica

@Anthony có lẽ đây là một zshđiều duy nhất. Tôi sử dụng nó thường xuyên nhưng tôi sẽ kiểm tra bashtừ máy tính vào ngày mai.
Caleb

Tôi nghi ngờ nó có thể là một cái vỏ mà tôi không quen thuộc (tôi chỉ quen với bash, dash và csh). Có một câu trả lời khác (kể từ khi bị xóa) chỉ hoạt động zsh. Trong khi tôi gắn thẻ câu hỏi này bashvà sử dụng nó trong tiêu đề, bạn nên giữ câu trả lời này vì người dùng zsh vẫn sẽ thấy nó hữu ích.
Anthony G - công lý cho Monica

-1

Bạn có thể gửi một bugreport vào killtrang chủ của mình và hỏi tại sao điều này bao gồm các tùy chọn không chuẩn được lấy từ pkillvà sử dụng pkillbất cứ khi nào bạn muốn để có được các tính năng từpkill.

Nếu bạn gọi:

pkill httpd

bạn tránh những vấn đề bạn mô tả

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.