ทำไมสคริปต์ของฉันชื่อ“ killl” ล้มเหลว แต่หลังจากการเปลี่ยนชื่อทำงานได้อย่างสมบูรณ์


12

สคริปต์ที่มีปัญหายุติกระบวนการล่าสุดในพอร์ต localhost ของฉัน 8080

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

มันใช้งานไม่ได้ถ้าสคริปต์ชื่อ 'killl' (หาได้หรือไม่ Kill ล่าสุด?) มันให้ฉันพร้อมท์สำหรับการcmdsubst> เปลี่ยนชื่อสคริปต์เป็น 'asdf' ทุกอย่างทำงานได้ มีคำอธิบายสำหรับพฤติกรรมนี้หรือไม่? ฉันใช้ MacOS El Capitán


5
คุณมีฟังก์ชั่น, นามแฝง, ยูทิลิตี้หรือคำสั่งอื่นที่เรียกว่าkilll?
Kusalananda

9
อย่าตั้งชื่อให้คลุมเครือ สามารถถูกตีความผิดสะกดผิดkilll killจะดีกว่าที่จะเป็นที่ชัดเจนและอธิบายเพิ่มเติม: หรือkill_latest kill_last
cezar

6
เอาต์พุตของtype killlเชลล์ในตำแหน่งที่คุณพยายามเริ่มต้นคืออะไร?
Hauke ​​Laging

คำตอบ:


27

cmdsubst>เป็นพรอมต์รองที่พิมพ์โดยzshเชลล์เมื่อรอการสิ้นสุดของการทดแทนคำสั่งที่ถูกป้อน

หากคุณได้รับพรอมต์นั้นหลังจากเพิ่งป้อนkilll<Return>คำอธิบายที่สมเหตุสมผลเพียงอย่างเดียวคือคุณมีนามแฝง (ซึ่งเป็นรูปแบบหนึ่งของการขยายแมโครสตริง) สำหรับkilllสิ่งนั้นจะขยายไปสู่บางสิ่งที่มีการ$(...)ทดแทนคำสั่งที่ไม่ถูกทำลายเช่น:

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

การzshขอให้คุณปิดการ$(...)แทนที่คำสั่งนั้นอยู่ที่ไหน

หมายเหตุเพิ่มเติม:

  • ผลลัพธ์ของlsofถูกเรียงลำดับตาม pid หมายเลข pid ถูกห่อไว้ pid ที่ใหญ่กว่านั้นไม่ได้รับประกันว่ากระบวนการจะเริ่มในภายหลัง
  • -i:8080 จะรายงานซ็อกเก็ต TCP หรือ UDP ที่มีพอร์ต 8080 เป็นพอร์ตต้นทางหรือพอร์ตปลายทางไม่ว่าจะเป็นซ็อกเก็ตการฟังการยอมรับหรือการเชื่อมต่อ
  • หากคุณต้องการรับ pid เท่านั้นคุณสามารถใช้-tตัวเลือกlsof:lsof -ti:8080 | tail -n2
  • kill -9คือkill -s KILLซึ่งจะส่งสัญญาณว่าแอปพลิเคชันไม่สามารถดำเนินการเพื่อออกอย่างสง่างาม มันควรจะใช้เป็นทางเลือกสุดท้าย

หากต้องการฆ่ากระบวนการที่เพิ่งเริ่มต้นซึ่งมีซ็อกเก็ตถูกผูกไว้ (ปลายทั้งสองด้าน) ที่พอร์ต 8080 คุณสามารถทำได้:

#! /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)}'

(ถือว่า GNU sort(เท่าที่พบใน macOS) และการpsใช้งานที่สนับสนุนlstartคอลัมน์ (เช่น macOS 'และ procps-ng ของแม้ว่ารหัสจะต้องมีการปรับปรุงสำหรับ procps-ng ที่มีการสลับฟิลด์เดือนและวัน))


1

มันทำให้ฉันพร้อมรับคำ cmdsubst>

เพราะเมื่อคุณพิมพ์คำสั่งคุณไม่ได้พิมพ์

killl
คุณพิมพ์

killl $ (
หรือคล้ายกัน นี่ไม่ใช่สิ่งที่เกี่ยวข้องกับชื่อของสคริปต์หรือแม้แต่ในตอนแรก คุณสามารถใช้เอฟเฟกต์เดียวกันได้ด้วยคำสั่งที่ไม่มีอยู่ทั้งหมด:

Zeick $ (
ตัวแยกวิเคราะห์ของเชลล์ต้องการอินพุตมากขึ้นเพื่อดำเนินการคำสั่งที่สมบูรณ์เพียงบางส่วนให้สมบูรณ์ ความคิดของคุณเกี่ยวกับชื่อสคริปต์คือปลาเฮอริ่งแดงสมบูรณ์


6
นั่นเป็นข้อสันนิษฐานที่ค่อนข้างใหญ่ที่จะบอกว่าเขาพิมพ์killl $(ด้วยเหตุผลบางอย่างและไม่น่าเป็นไปได้มากที่เขาจะทำเช่นนั้น คำตอบของStéphane Chazelas มีแนวโน้มมากขึ้น
Herohtar

1
ถ้ามันเป็นความจริงเนื่องจากการพิมพ์ผิดแล้วเป็นไปได้มากกว่า` $(
Emil Jeřábek

2
ไม่เอมิลJeřábek; `ไม่ได้มีโอกาสที่ทุกคนตั้งแต่มันไม่ได้ให้พรอมต์เดียวกัน ลองมัน. ไม่ Herhtar; ไม่ใช่ข้อสันนิษฐานเมื่อพิมพ์สิ่งนั้นหรือคล้ายกันคือวิธีรับพรอมต์นั้น มันคือการหัก
JdeBP

1
คุณยืนยันว่า OP "ไม่ได้พิมพ์killl" เมื่อStéphane Chazelas อธิบายว่ามันเป็นไปได้ทั้งหมดที่ OP ได้พิมพ์จริงkilllๆ ดังนั้นฉันได้ลดคำตอบของคุณผิด
เควิน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.