Tại sao kịch bản của tôi có tên là Kill killl, thất bại, nhưng sau khi đổi tên hoạt động hoàn hảo?


12

Kịch bản trong câu hỏi chấm dứt quá trình mới nhất trên cổng localhost 8080 của tôi.

#!/bin/bash
x=$(lsof -i:8080 | tail -1 | awk '{print $2}')
kill -9 $x

Nó không hoạt động, nếu kịch bản được đặt tên là 'killl' (hiểu không? Kill mới nhất?). Nó đã cho tôi một lời nhắc để cmdsubst> Đổi tên tập lệnh thành 'asdf', mọi thứ đều hoạt động. Có một lời giải thích cho hành vi này? Tôi đang sử dụng MacOS El Capitán.


5
Bạn có chức năng khác, bí danh, tiện ích hoặc lệnh khác được gọi killlkhông?
Kusalananda

9
Đừng làm cho những cái tên mơ hồ. killlcó thể bị hiểu sai là đánh vần sai kill. Tốt hơn là nên rõ ràng và mô tả nhiều hơn: kill_latesthoặc kill_last.
cezar

6
Đầu ra của type killlshell mà bạn đã cố gắng khởi động nó là gì?
Hauke ​​Laging

Câu trả lời:


27

cmdsubst>là dấu nhắc thứ cấp được in bởi zshshell khi nó chờ kết thúc lệnh thay thế được nhập.

Nếu bạn nhận được lời nhắc đó sau khi vừa nhập killl<Return>, thì lời giải thích hợp lý duy nhất là bạn có một bí danh (là một dạng mở rộng macro chuỗi) để killlmở rộng thành thứ có chứa $(...)thay thế lệnh bị lỗi, như:

$ alias 'killl=echo $(lsof -ti'
$ killl :22
cmdsubst>

Trường hợp zshđang yêu cầu bạn đóng $(...)lệnh thay thế đó.

Một vài lưu ý nữa:

  • đầu ra của lsofđược sắp xếp theo pid. số pid được bọc, một pid lớn hơn không đảm bảo rằng quá trình được bắt đầu sau đó.
  • -i:8080 sẽ báo cáo các ổ cắm TCP hoặc UDP có cổng 8080 làm cổng nguồn hoặc cổng đích, cho dù đó là ổ cắm nghe, chấp nhận hoặc kết nối.
  • Nếu bạn chỉ muốn lấy pid, bạn có thể sử dụng -ttùy chọn lsof:lsof -ti:8080 | tail -n2
  • kill -9kill -s KILL, sẽ gửi một tín hiệu rằng ứng dụng không thể hành động để thoát ra một cách duyên dáng. Nó chỉ nên được sử dụng như là một phương sách cuối cùng.

Để loại bỏ quá trình bắt đầu gần đây nhất có ràng buộc ổ cắm (một trong hai) trên cổng 8080, bạn có thể làm:

#! /bin/sh -
unset IFS
pids=$(lsof -ti:8080) &&
  LC_ALL=C ps -o pid=,lstart= -p $pids |
  LC_ALL=C sort -k6,6n -k4,4M -k3,3n -k5,5 -k1,1n |
  awk 'END{system("kill " $1)}'

(giả sử GNU sort(như được tìm thấy trên macOS) và một pstriển khai hỗ trợ lstartcột (như macOS 'và Procps-ng, mặc dù mã sẽ phải được cập nhật cho Procps-ng trong đó các trường tháng và ngày được hoán đổi)


1

Nó đã cho tôi một lời nhắc cho cmdsubst>

Bởi vì khi bạn gõ lệnh, bạn không gõ

giết
bạn đã gõ

giết chết $ (
hoặc tương tự. Điều này không có gì để làm với tên của kịch bản, hoặc thậm chí đó là kịch bản ở nơi đầu tiên. Bạn có thể đã đạt được hiệu quả tương tự với lệnh hoàn toàn không tồn tại:

Zeick $ (
Trình phân tích cú pháp của shell đã mong đợi nhiều đầu vào hơn để hoàn thành lệnh hoàn thành một phần duy nhất. Suy nghĩ của bạn về tên kịch bản là một cá trích đỏ hoàn chỉnh.


6
Đó là một giả định khá lớn để nói rằng anh ta gõ killl $(vì một số lý do, và rất khó có khả năng anh ta đã làm như vậy. Câu trả lời của Stéphane Chazelas rất có thể là trường hợp.
Herohtar

1
Nếu nó thực sự là do một lỗi đánh máy, thì `có nhiều khả năng hơn $(.
Emil Jeřábek hỗ trợ Monica

2
Không, Emil Jeřábek; `hoàn toàn không có khả năng vì nó không đưa ra cùng một dấu nhắc . Thử nó. Không, Herhtar; Đó không phải là một giả định khi gõ hoặc tương tựcách để có được dấu nhắc đó . Đó là một khoản khấu trừ.
JdeBP

1
Bạn khẳng định rằng OP "không gõ killl", như Stéphane Chazelas giải thích, hoàn toàn có khả năng OP đã thực sự gõ killl. Vì vậy, tôi đã đánh giá thấp câu trả lời của bạn là sai.
Kevin
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.