Mengapa skrip saya yang bernama "killl" gagal, tetapi setelah penggantian nama berfungsi dengan baik?


12

Script yang dipermasalahkan mengakhiri proses terbaru pada localhost port 8080 saya.

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

Itu tidak bekerja, jika skrip itu bernama 'killl' (mengerti? Kill Latest?). Itu memberi saya prompt untuk cmdsubst> Mengganti nama skrip ke 'asdf', semuanya berfungsi. Apakah ada penjelasan untuk perilaku ini? Saya menggunakan MacOS El Capitán.


5
Apakah Anda memiliki fungsi lain, alias, utilitas atau perintah lain yang dipanggil killl?
Kusalananda

9
Jangan membuat nama-nama itu ambigu. killldapat disalahartikan sebagai salah dieja kill. Lebih baik eksplisit dan lebih deskriptif: kill_latestatau kill_last.
cezar

6
Apa output dari type killldalam shell di mana Anda mencoba memulainya?
Hauke ​​Laging

Jawaban:


27

cmdsubst>adalah prompt sekunder yang dicetak oleh zshshell ketika menunggu akhir dari substitusi perintah yang dimasukkan.

Jika Anda mendapatkan prompt itu setelah hanya memasukkan killl<Return>, maka satu-satunya penjelasan yang masuk akal adalah bahwa Anda memiliki alias (yang merupakan beberapa bentuk ekspansi makro string) untuk killlyang memperluas ke sesuatu yang berisi $(...)substitusi perintah yang tidak ditentukan , seperti:

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

Di mana zshmeminta Anda untuk menutup $(...)substitusi perintah itu.

Beberapa catatan lagi:

  • output lsofdiurutkan berdasarkan pid. nomor pid dibungkus, pid yang lebih besar bukan jaminan bahwa proses itu dimulai nanti.
  • -i:8080 akan melaporkan soket TCP atau UDP yang memiliki port 8080 sebagai port sumber atau tujuan, baik itu soket yang mendengarkan, menerima, atau menghubungkan.
  • Jika Anda ingin mendapatkan pid saja, Anda dapat menggunakan -topsi lsof:lsof -ti:8080 | tail -n2
  • kill -9adalah kill -s KILL, yang mengirimkan sinyal bahwa aplikasi tidak dapat bertindak untuk keluar dengan anggun. Seharusnya hanya digunakan sebagai pilihan terakhir.

Untuk membunuh proses yang paling baru dimulai yang memiliki soket terikat (di kedua ujungnya) pada port 8080, Anda dapat melakukan:

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

(mengasumsikan GNU sort(seperti yang ditemukan pada macOS) dan psimplementasi yang mendukung lstartkolom (seperti macOS 'dan procps-ng, meskipun kode harus diperbarui untuk procps-ng di mana bidang bulan dan hari ditukar)).


1

Itu memberi saya prompt untuk cmdsubst>

Karena ketika Anda mengetik perintah, Anda tidak mengetik

killl
Anda mengetik

killl $ (
atau serupa. Ini tidak ada hubungannya dengan nama naskah, atau bahkan itu adalah naskah di tempat pertama. Anda bisa mencapai efek yang sama dengan perintah yang sama sekali tidak ada:

Zeick $ (
Pengurai shell mengharapkan lebih banyak input untuk menyelesaikan satu-satunya perintah yang sebagian lengkap. Pemikiran Anda tentang nama skrip adalah herring merah lengkap.


6
Itu asumsi yang cukup besar untuk mengatakan bahwa dia mengetik killl $(karena suatu alasan, dan sangat tidak mungkin dia melakukannya. Jawaban Stéphane Chazelas lebih mungkin terjadi.
Herohtar

1
Jika memang karena kesalahan ketik, maka `lebih mungkin daripada $(.
Emil Jeřábek 3.0

2
Tidak, Emil Jeřábek; `tidak mungkin sama sekali karena tidak memberikan prompt yang sama . Cobalah. Tidak, Herhtar; itu bukan asumsi ketika mengetik itu atau serupa adalah cara untuk mendapatkan prompt itu . Itu adalah deduksi.
JdeBP

1
Anda menyatakan bahwa OP "tidak mengetik killl," ketika seperti yang dijelaskan oleh Stéphane Chazelas, sangat mungkin OP memang mengetik killl. Karenanya, saya salah menganggap jawaban Anda salah.
Kevin
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.