【查询命令所属软件包】

rpm -qf /usr/bin/killall

psmisc-22.20-15.el7.x86_64

rpm -qf /usr/bin/kill

util-linux-2.23.2-65.el7_9.1.x86_64

【命令参数】

killall kill

-e,--exact          require exact match for very long names

-I,--ignore-case    case insensitive process name match

-g,--process-group  kill process group instead of process

-y,--younger-than   kill processes younger than TIME

-o,--older-than     kill processes older than TIME

-i,--interactive    ask for confirmation before killing

-l,--list           list all known signal names

-q,--quiet          don't print complaints

-r,--regexp         interpret NAME as an extended regular expression

-s,--signal SIGNAL  send this signal instead of SIGTERM

-u,--user USER      kill only process(es) running as USER

-v,--verbose        report if the signal was successfully sent

-V,--version        display version information

-w,--wait           wait for processes to die

-Z,--context REGEXP kill only process(es) having context

(must precede other arguments)

--

【源码】

kill GitHub - util-linux/util-linux at v2.23.2

killall https://gitlab.com/psmisc/psmisc/-/tree/v22.20

killall 代码实现关键点:kill 调用,正则表达式匹配、虚拟目录(/proc/)枚举进程

/** killall.c - kill processes by name or list PIDs** Copyright (C) 1993-2002 Werner Almesberger* Copyright (C) 2002-2012 Craig Small** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation; either version 2 of the License, or* (at your option) any later version.**  This program is distributed in the hope that it will be useful,*  but WITHOUT ANY WARRANTY; without even the implied warranty of*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the*  GNU General Public License for more details.**  You should have received a copy of the GNU General Public License*  along with this program; if not, write to the Free Software*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif#ifdef HAVE_CONFIG_H
#include <config.h>
#endif#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <getopt.h>
#include <pwd.h>
#include <regex.h>
#include <ctype.h>
#include <assert.h>#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#endif /*WITH_SELINUX*/#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif /* HAVE_LOCALE_H */#include "i18n.h"
#include "comm.h"
#include "signals.h"#define PROC_BASE "/proc"
#define MAX_NAMES (int)(sizeof(unsigned long)*8)#define TSECOND "s"
#define TMINUTE "m"
#define THOUR   "h"
#define TDAY    "d"
#define TWEEK   "w"
#define TMONTH  "M"
#define TYEAR   "y"#define TMAX_SECOND 31536000
#define TMAX_MINUTE 525600
#define TMAX_HOUR   8760
#define TMAX_DAY    365
#define TMAX_WEEK   48
#define TMAX_MONTH  12
#define TMAX_YEAR   1       #define ER_REGFAIL -1
#define ER_NOMEM   -2
#define ER_UNKWN   -3
#define ER_OOFRA   -4static int verbose = 0, exact = 0, interactive = 0, reg = 0,quiet = 0, wait_until_dead = 0, process_group = 0,ignore_case = 0;
static long younger_than = 0, older_than = 0;static int
ask (char *name, pid_t pid, const int signal)
{int res;size_t len;char *line;line = NULL;len = 0;do {if (signal == SIGTERM)printf (_("Kill %s(%s%d) ? (y/N) "), name, process_group ? "pgid " : "",pid);elseprintf (_("Signal %s(%s%d) ? (y/N) "), name, process_group ? "pgid " : "",pid);fflush (stdout);if (getline (&line, &len, stdin) < 0)return 0;/* Check for default */if (line[0] == '\n') {free(line);return 0;}res = rpmatch(line);if (res >= 0) {free(line);return res;}} while(1);/* Never should get here */
}static double
uptime()
{char * savelocale;char buf[2048];FILE* file;if (!(file=fopen( PROC_BASE "/uptime", "r"))) {fprintf(stderr, "killall: error opening uptime file\n"); exit(1);}savelocale = setlocale(LC_NUMERIC, NULL);setlocale(LC_NUMERIC,"C");if (fscanf(file, "%2047s", buf) == EOF) perror("uptime");fclose(file);setlocale(LC_NUMERIC,savelocale);return atof(buf);
}/* process age from jiffies to seconds via uptime */
static double process_age(const unsigned long long jf)
{double age;double sc_clk_tck = sysconf(_SC_CLK_TCK);assert(sc_clk_tck > 0);age = uptime() - jf / sc_clk_tck;if (age < 0L)return 0L;return age;
}/* returns requested time interval in seconds, negative indicates error has occurred*/
static long
parse_time_units(const char* age)
{char *unit;long num;num = strtol(age,&unit,10);if (age == unit) /* no digits found */return -1;if (unit[0] == '\0') /* no units found */return -1;switch(unit[0]) {case 's':return num;case 'm':return (num * 60);case 'h':return (num * 60 * 60);case 'd':return (num * 60 * 60 * 24);case 'w':return (num * 60 * 60 * 24 * 7);case 'M':return (num * 60 * 60 * 24 * 7 * 4);case 'y':return (num * 60 * 60 * 24 * 7 * 4 * 12);}return -1;
}static int
match_process_uid(pid_t pid, uid_t uid)
{char buf[128];uid_t puid;FILE *f;int re = -1;snprintf (buf, sizeof buf, PROC_BASE "/%d/status", pid);if (!(f = fopen (buf, "r")))return 0;while (fgets(buf, sizeof buf, f)){if (sscanf (buf, "Uid:\t%d", &puid)){re = uid==puid;break;}}fclose(f);if (re==-1){fprintf(stderr, _("killall: Cannot get UID from process status\n"));exit(1);}return re;
}static regex_t *
build_regexp_list(int names, char **namelist)
{int i;regex_t *reglist;int flag = REG_EXTENDED|REG_NOSUB;if (!(reglist = malloc (sizeof (regex_t) * names))){perror ("malloc");exit (1);}if (ignore_case)flag |= REG_ICASE;for (i = 0; i < names; i++){if (regcomp(&reglist[i], namelist[i], flag) != 0) {fprintf(stderr, _("killall: Bad regular expression: %s\n"), namelist[i]);exit (1);}}return reglist;
}#ifdef WITH_SELINUX
static int
kill_all(int signal, int names, char **namelist, struct passwd *pwent, regex_t *scontext )
#else  /*WITH_SELINUX*/
static int
kill_all (int signal, int names, char **namelist, struct passwd *pwent)
#endif /*WITH_SELINUX*/
{DIR *dir;struct dirent *de;FILE *file;struct stat st, sts[MAX_NAMES];int *name_len = NULL;char *path, comm[COMM_LEN];char *command_buf;char *command;pid_t *pid_table, pid, self, *pid_killed;pid_t *pgids;int i, j, okay, length, got_long, error;int pids, max_pids, pids_killed;unsigned long found;regex_t *reglist = NULL;;
#ifdef WITH_SELINUXsecurity_context_t lcontext=NULL;
#endif /*WITH_SELINUX*/if (names && reg) reglist = build_regexp_list(names, namelist);else if (names){if (!(name_len = malloc (sizeof (int) * names))){perror ("malloc");exit (1);}for (i = 0; i < names; i++) {if (!strchr (namelist[i], '/')){sts[i].st_dev = 0;name_len[i] = strlen (namelist[i]);}else if (stat (namelist[i], &sts[i]) < 0){perror (namelist[i]);exit (1);}}} self = getpid ();found = 0;if (!(dir = opendir (PROC_BASE))){perror (PROC_BASE);exit (1);}max_pids = 256;pid_table = malloc (max_pids * sizeof (pid_t));if (!pid_table){perror ("malloc");exit (1);}pids = 0;while ( (de = readdir (dir)) != NULL){if (!(pid = (pid_t) atoi (de->d_name)) || pid == self)continue;if (pids == max_pids){if (!(pid_table = realloc (pid_table, 2 * pids * sizeof (pid_t)))){perror ("realloc");exit (1);}max_pids *= 2;}pid_table[pids++] = pid;}(void) closedir (dir);pids_killed = 0;pid_killed = malloc (max_pids * sizeof (pid_t));if (!pid_killed){perror ("malloc");exit (1);}if (!process_group)pgids = NULL;        /* silence gcc */else{pgids = calloc (pids, sizeof (pid_t));if (!pgids){perror ("malloc");exit (1);}}for (i = 0; i < pids; i++){pid_t id;int found_name = -1;double process_age_sec = 0;/* match by UID */if (pwent && match_process_uid(pid_table[i], pwent->pw_uid)==0)continue;
#ifdef WITH_SELINUX/* match by SELinux context */if (scontext) {if (getpidcon(pid_table[i], &lcontext) < 0)continue;if (regexec(scontext, lcontext, 0, NULL, 0) != 0) {freecon(lcontext);continue;}freecon(lcontext);}
#endif /*WITH_SELINUX*//* load process name */if (asprintf (&path, PROC_BASE "/%d/stat", pid_table[i]) < 0)continue;if (!(file = fopen (path, "r"))) {free (path);continue;}free (path);okay = fscanf (file, "%*d (%15[^)]", comm) == 1;if (!okay) {fclose(file);continue;}if ( younger_than || older_than ) {rewind(file);unsigned long long proc_stt_jf = 0;okay = fscanf(file, "%*d %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %Lu", &proc_stt_jf) == 1;if (!okay) {fclose(file);continue;}process_age_sec = process_age(proc_stt_jf);}(void) fclose (file);got_long = 0;command = NULL;      /* make gcc happy */length = strlen (comm);if (length == COMM_LEN - 1){if (asprintf (&path, PROC_BASE "/%d/cmdline", pid_table[i]) < 0)continue;if (!(file = fopen (path, "r"))) {free (path);continue;}free (path);while (1) {/* look for actual command so we skip over initial "sh" if any */char *p;int cmd_size = 128;command_buf = (char *)malloc (cmd_size);if (!command_buf)exit (1);/* 'cmdline' has arguments separated by nulls */for (p=command_buf; ; p++) {int c;if (p == (command_buf + cmd_size)) {int cur_size = cmd_size;cmd_size *= 2;command_buf = (char *)realloc(command_buf, cmd_size);if (!command_buf)exit (1);p = command_buf + cur_size;}c = fgetc(file);if (c == EOF || c == '\0') {*p = '\0';break;} else {*p = c;}}if (strlen(command_buf) == 0) {okay = 0;break;}p = strrchr(command_buf,'/');p = p ? p+1 : command_buf;if (strncmp(p, comm, COMM_LEN-1) == 0) {okay = 1;command = p;break;}}(void) fclose(file);if (exact && !okay){if (verbose)fprintf (stderr, _("killall: skipping partial match %s(%d)\n"),comm, pid_table[i]);continue;}got_long = okay;}/* mach by process name */for (j = 0; j < names; j++){if (reg){if (regexec (&reglist[j], got_long ? command : comm, 0, NULL, 0) != 0)continue;}else /* non-regex */{if ( younger_than && process_age_sec && (process_age_sec > younger_than ) )continue;if ( older_than   && process_age_sec && (process_age_sec < older_than ) )continue;if (!sts[j].st_dev){if (length != COMM_LEN - 1 || name_len[j] < COMM_LEN - 1){if (ignore_case == 1){if (strcasecmp (namelist[j], comm))continue;}else{if (strcmp(namelist[j], comm))continue;}}else{if (ignore_case == 1){if (got_long ? strcasecmp (namelist[j], command) :strncasecmp (namelist[j], comm, COMM_LEN - 1))continue;}else{if (got_long ? strcmp (namelist[j], command) :strncmp (namelist[j], comm, COMM_LEN - 1))continue;}}}else{int ok = 1;if (asprintf (&path, PROC_BASE "/%d/exe", pid_table[i]) < 0)continue;if (stat (path, &st) < 0) ok = 0;else if (sts[j].st_dev != st.st_dev ||sts[j].st_ino != st.st_ino){/* maybe the binary has been modified and std[j].st_ino* is not reliable anymore. We need to compare paths.*/size_t len = strlen(namelist[j]);char *linkbuf = malloc(len + 1);if (!linkbuf ||readlink(path, linkbuf, len + 1) != len ||memcmp(namelist[j], linkbuf, len))ok = 0;free(linkbuf);}free(path);if (!ok)continue;}} /* non-regex */found_name = j;break;}  if (names && found_name==-1)continue;  /* match by process name faild *//* check for process group */if (!process_group)id = pid_table[i];else{int j;id = getpgid (pid_table[i]);pgids[i] = id;if (id < 0){fprintf (stderr, "killall: getpgid(%d): %s\n",pid_table[i], strerror (errno));}for (j = 0; j < i; j++)if (pgids[j] == id)break;if (j < i)continue;} if (interactive && !ask (comm, id, signal))continue;if (kill (process_group ? -id : id, signal) >= 0){if (verbose)fprintf (stderr, _("Killed %s(%s%d) with signal %d\n"), got_long ? command :comm, process_group ? "pgid " : "", id, signal);if (found_name >= 0)/* mark item of namelist */found |= 1 << found_name;pid_killed[pids_killed++] = id;}else if (errno != ESRCH || interactive)fprintf (stderr, "%s(%d): %s\n", got_long ? command :comm, id, strerror (errno));}if (!quiet)for (i = 0; i < names; i++)if (!(found & (1 << i)))fprintf (stderr, _("%s: no process found\n"), namelist[i]);if (names)/* killall returns a zero return code if at least one process has * been killed for each listed command. */error = found == ((1 << (names - 1)) | ((1 << (names - 1)) - 1)) ? 0 : 1;else/* in nameless mode killall returns a zero return code if at least * one process has killed */error = pids_killed ? 0 : 1;/** We scan all (supposedly) killed processes every second to detect dead* processes as soon as possible in order to limit problems of race with* PID re-use.*/while (pids_killed && wait_until_dead){for (i = 0; i < pids_killed;){if (kill (process_group ? -pid_killed[i] : pid_killed[i], 0) < 0 &&errno == ESRCH){pid_killed[i] = pid_killed[--pids_killed];continue;}i++;}sleep (1);     /* wait a bit longer */}return error;
}static void
usage (const char *msg)
{if (msg != NULL)fprintf(stderr, "%s\n", msg);
#ifdef WITH_SELINUXfprintf(stderr, _("Usage: killall [-Z CONTEXT] [-u USER] [ -eIgiqrvw ] [ -SIGNAL ] NAME...\n"));
#else  /*WITH_SELINUX*/fprintf(stderr, _("Usage: killall [OPTION]... [--] NAME...\n"));
#endif /*WITH_SELINUX*/fprintf(stderr, _("       killall -l, --list\n""       killall -V, --version\n\n""  -e,--exact          require exact match for very long names\n""  -I,--ignore-case    case insensitive process name match\n""  -g,--process-group  kill process group instead of process\n""  -y,--younger-than   kill processes younger than TIME\n""  -o,--older-than     kill processes older than TIME\n"           "  -i,--interactive    ask for confirmation before killing\n""  -l,--list           list all known signal names\n""  -q,--quiet          don't print complaints\n""  -r,--regexp         interpret NAME as an extended regular expression\n""  -s,--signal SIGNAL  send this signal instead of SIGTERM\n""  -u,--user USER      kill only process(es) running as USER\n""  -v,--verbose        report if the signal was successfully sent\n""  -V,--version        display version information\n""  -w,--wait           wait for processes to die\n"));
#ifdef WITH_SELINUXfprintf(stderr, _("  -Z,--context REGEXP kill only process(es) having context\n""                      (must precede other arguments)\n"));
#endif /*WITH_SELINUX*/fputc('\n', stderr);exit(1);
}void print_version()
{fprintf(stderr, "killall (PSmisc) %s\n", VERSION);fprintf(stderr, _("Copyright (C) 1993-2012 Werner Almesberger and Craig Small\n\n"));fprintf(stderr, _("PSmisc comes with ABSOLUTELY NO WARRANTY.\n""This is free software, and you are welcome to redistribute it under\n""the terms of the GNU General Public License.\n""For more information about these matters, see the files named COPYING.\n"));
}static int
have_proc_self_stat (void)
{char filename[128];struct stat isproc;pid_t pid = getpid();snprintf(filename, sizeof(filename), PROC_BASE"/%d/stat", (int) pid);return stat(filename, &isproc) == 0;
}int
main (int argc, char **argv)
{char *name;int sig_num;int optc;int myoptind;struct passwd *pwent = NULL;char yt[16];char ot[16];//int optsig = 0;struct option options[] = {{"exact", 0, NULL, 'e'},{"ignore-case", 0, NULL, 'I'},{"process-group", 0, NULL, 'g'},{"younger-than", 1, NULL, 'y'},{"older-than", 1, NULL, 'o'},{"interactive", 0, NULL, 'i'},{"list-signals", 0, NULL, 'l'},{"quiet", 0, NULL, 'q'},{"regexp", 0, NULL, 'r'},{"signal", 1, NULL, 's'},{"user", 1, NULL, 'u'},{"verbose", 0, NULL, 'v'},{"wait", 0, NULL, 'w'},
#ifdef WITH_SELINUX{"context", 1, NULL, 'Z'},
#endif /*WITH_SELINUX*/{"version", 0, NULL, 'V'},{0,0,0,0 }};/* Setup the i18n */
#ifdef ENABLE_NLSsetlocale(LC_ALL, "");bindtextdomain(PACKAGE, LOCALEDIR);textdomain(PACKAGE);
#endif
#ifdef WITH_SELINUXsecurity_context_t scontext = NULL;regex_t scontext_reg;if ( argc < 2 ) usage(NULL); /* do the obvious thing... */
#endif /*WITH_SELINUX*/name = strrchr (*argv, '/');if (name)name++;elsename = *argv;sig_num = SIGTERM;opterr = 0;
#ifdef WITH_SELINUXwhile ( (optc = getopt_long_only(argc,argv,"egy:o:ilqrs:u:vwZ:VI",options,NULL)) != -1) {
#elsewhile ( (optc = getopt_long_only(argc,argv,"egy:o:ilqrs:u:vwVI",options,NULL)) != -1) {
#endifswitch (optc) {case 'e':exact = 1;break;case 'g':process_group = 1;break;case 'y':strncpy(yt, optarg, 16);yt[15] = '\0';if ( 0 >= (younger_than = parse_time_units(yt) ) )usage(_("Invalid time format"));break;case 'o':strncpy(ot, optarg, 16);ot[15] = '\0';if ( 0 >= (older_than = parse_time_units(ot) ) )usage(_("Invalid time format"));break;case 'i':interactive = 1;break;case 'l':list_signals();return 0;break;case 'q':quiet = 1;break;case 'r':reg = 1;break;case 's':sig_num = get_signal (optarg, "killall");break;case 'u':if (!(pwent = getpwnam(optarg))) {fprintf (stderr, _("Cannot find user %s\n"), optarg);exit (1);}break;case 'v':verbose = 1;break;case 'w':wait_until_dead = 1;break;case 'I':/* option check is optind-1 but sig name is optind */if (strcmp(argv[optind-1],"-I") == 0 || strncmp(argv[optind-1],"--",2) == 0) {ignore_case = 1;} else {sig_num = get_signal (argv[optind]+1, "killall");}break;case 'V':/* option check is optind-1 but sig name is optind */if (strcmp(argv[optind-1],"-V") == 0 || strncmp(argv[optind-1],"--",2) == 0) {print_version();return 0;}sig_num = get_signal (argv[optind]+1, "killall");break;
#ifdef WITH_SELINUXcase 'Z': if (is_selinux_enabled()>0) {scontext=optarg;if (regcomp(&scontext_reg, scontext, REG_EXTENDED|REG_NOSUB) != 0) {fprintf(stderr, _("Bad regular expression: %s\n"), scontext);exit (1);}} else fprintf(stderr, "Warning: -Z (--context) ignored. Requires an SELinux enabled kernel\n");break;
#endif /*WITH_SELINUX*/case '?':/* Signal names are in uppercase, so check to see if the argv* is upper case */if (argv[optind-1][1] >= 'A' && argv[optind-1][1] <= 'Z') {sig_num = get_signal (argv[optind-1]+1, "killall");} else {/* Might also be a -## signal too */if (argv[optind-1][1] >= '0' && argv[optind-1][1] <= '9') {sig_num = atoi(argv[optind-1]+1);} else {usage(NULL);}}break;}}myoptind = optind;
#ifdef WITH_SELINUXif ((argc - myoptind < 1) && pwent==NULL && scontext==NULL)
#elseif ((argc - myoptind < 1) && pwent==NULL)
#endifusage(NULL);if (argc - myoptind > MAX_NAMES) {fprintf (stderr, _("killall: Maximum number of names is %d\n"),MAX_NAMES);exit (1);}if (!have_proc_self_stat()) {fprintf (stderr, _("killall: %s lacks process entries (not mounted ?)\n"),PROC_BASE);exit (1);}argv = argv + myoptind;/*printf("sending signal %d to procs\n", sig_num);*/
#ifdef WITH_SELINUXreturn kill_all(sig_num,argc - myoptind, argv, pwent, scontext ? &scontext_reg : NULL);
#else  /*WITH_SELINUX*/return kill_all(sig_num,argc - myoptind, argv, pwent);
#endif /*WITH_SELINUX*/
}

kill 代码关键点:kill 调用

/** Copyright (c) 1988, 1993, 1994*  The Regents of the University of California.  All rights reserved.** Redistribution and use in source and binary forms, with or without* modification, are permitted provided that the following conditions* are met:* 1. Redistributions of source code must retain the above copyright*    notice, this list of conditions and the following disclaimer.* 2. Redistributions in binary form must reproduce the above copyright*    notice, this list of conditions and the following disclaimer in the*    documentation and/or other materials provided with the distribution.* 3. All advertising materials mentioning features or use of this software*    must display the following acknowledgement:*    This product includes software developed by the University of*  California, Berkeley and its contributors.* 4. Neither the name of the University nor the names of its contributors*    may be used to endorse or promote products derived from this software*    without specific prior written permission.** THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE* ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF* SUCH DAMAGE.*/
/**  oct 5 1994 -- almost entirely re-written to allow for process names.*  modifications (c) salvatore valente <svalente@mit.edu>*  may be used / modified / distributed under the same terms as the original.**  1999-02-22 Arkadiusz Miśkiewicz <misiek@pld.ORG.PL>*  - added Native Language Support**  1999-11-13 aeb Accept signal numers 128+s.**/#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>        /* for isdigit() */
#include <unistd.h>
#include <signal.h>#include "c.h"
#include "nls.h"
#include "closestream.h"
#include "procutils.h"
#include "strutils.h"
#include "ttyutils.h"
#include "xalloc.h"struct signv {const char *name;int val;
} sys_signame[] = {/* POSIX signals */{ "HUP",   SIGHUP },   /* 1 */{ "INT",   SIGINT },   /* 2 */{ "QUIT",  SIGQUIT },  /* 3 */{ "ILL",   SIGILL },   /* 4 */
#ifdef SIGTRAP{ "TRAP",   SIGTRAP },  /* 5 */
#endif{ "ABRT",   SIGABRT },  /* 6 */
#ifdef SIGIOT{ "IOT", SIGIOT },   /* 6, same as SIGABRT */
#endif
#ifdef SIGEMT{ "EMT", SIGEMT },   /* 7 (mips,alpha,sparc*) */
#endif
#ifdef SIGBUS{ "BUS", SIGBUS },   /* 7 (arm,i386,m68k,ppc), 10 (mips,alpha,sparc*) */
#endif{ "FPE",    SIGFPE },   /* 8 */{ "KILL",  SIGKILL },  /* 9 */{ "USR1",  SIGUSR1 },  /* 10 (arm,i386,m68k,ppc), 30 (alpha,sparc*), 16 (mips) */{ "SEGV",   SIGSEGV },  /* 11 */{ "USR2", SIGUSR2 },  /* 12 (arm,i386,m68k,ppc), 31 (alpha,sparc*), 17 (mips) */{ "PIPE",   SIGPIPE },  /* 13 */{ "ALRM", SIGALRM },  /* 14 */{ "TERM", SIGTERM },  /* 15 */
#ifdef SIGSTKFLT{ "STKFLT",   SIGSTKFLT },    /* 16 (arm,i386,m68k,ppc) */
#endif{ "CHLD",   SIGCHLD },  /* 17 (arm,i386,m68k,ppc), 20 (alpha,sparc*), 18 (mips) */
#ifdef SIGCLD{ "CLD", SIGCLD },   /* same as SIGCHLD (mips) */
#endif{ "CONT",   SIGCONT },  /* 18 (arm,i386,m68k,ppc), 19 (alpha,sparc*), 25 (mips) */{ "STOP",   SIGSTOP },  /* 19 (arm,i386,m68k,ppc), 17 (alpha,sparc*), 23 (mips) */{ "TSTP",   SIGTSTP },  /* 20 (arm,i386,m68k,ppc), 18 (alpha,sparc*), 24 (mips) */{ "TTIN",   SIGTTIN },  /* 21 (arm,i386,m68k,ppc,alpha,sparc*), 26 (mips) */{ "TTOU", SIGTTOU },  /* 22 (arm,i386,m68k,ppc,alpha,sparc*), 27 (mips) */
#ifdef SIGURG{ "URG", SIGURG },   /* 23 (arm,i386,m68k,ppc), 16 (alpha,sparc*), 21 (mips) */
#endif
#ifdef SIGXCPU{ "XCPU",   SIGXCPU },  /* 24 (arm,i386,m68k,ppc,alpha,sparc*), 30 (mips) */
#endif
#ifdef SIGXFSZ{ "XFSZ",   SIGXFSZ },  /* 25 (arm,i386,m68k,ppc,alpha,sparc*), 31 (mips) */
#endif
#ifdef SIGVTALRM{ "VTALRM",   SIGVTALRM },    /* 26 (arm,i386,m68k,ppc,alpha,sparc*), 28 (mips) */
#endif
#ifdef SIGPROF{ "PROF",   SIGPROF },  /* 27 (arm,i386,m68k,ppc,alpha,sparc*), 29 (mips) */
#endif
#ifdef SIGWINCH{ "WINCH", SIGWINCH }, /* 28 (arm,i386,m68k,ppc,alpha,sparc*), 20 (mips) */
#endif
#ifdef SIGIO{ "IO",       SIGIO },    /* 29 (arm,i386,m68k,ppc), 23 (alpha,sparc*), 22 (mips) */
#endif
#ifdef SIGPOLL{ "POLL",   SIGPOLL },  /* same as SIGIO */
#endif
#ifdef SIGINFO{ "INFO",   SIGINFO },  /* 29 (alpha) */
#endif
#ifdef SIGLOST{ "LOST",   SIGLOST },  /* 29 (arm,i386,m68k,ppc,sparc*) */
#endif
#ifdef SIGPWR{ "PWR", SIGPWR },   /* 30 (arm,i386,m68k,ppc), 29 (alpha,sparc*), 19 (mips) */
#endif
#ifdef SIGUNUSED{ "UNUSED",   SIGUNUSED },    /* 31 (arm,i386,m68k,ppc) */
#endif
#ifdef SIGSYS{ "SYS", SIGSYS },   /* 31 (mips,alpha,sparc*) */
#endif
};static int arg_to_signum (char *arg, int mask);
static void nosig (char *name);
static void printsig (int sig);
static void printsignals (FILE *fp, int pretty);
static int usage (int status);
static int kill_verbose (char *procname, int pid, int sig);#ifdef HAVE_SIGQUEUE
static int use_sigval;
static union sigval sigdata;
#endifint main (int argc, char *argv[])
{int errors, numsig, pid;char *ep, *arg;int do_pid, do_kill, check_all;setlocale(LC_ALL, "");bindtextdomain(PACKAGE, LOCALEDIR);textdomain(PACKAGE);atexit(close_stdout);numsig = SIGTERM;do_pid = (! strcmp (program_invocation_short_name, "pid"));     /* Yecch */do_kill = 0;check_all = 0;/*  loop through the arguments.actually, -a is the only option can be used with other options.`kill' is basically a one-option-at-most program.  */for (argc--, argv++; argc > 0; argc--, argv++) {arg = *argv;if (*arg != '-') {break;}if (! strcmp (arg, "--")) {argc--, argv++;break;}if (! strcmp (arg, "-v") || ! strcmp (arg, "-V") ||! strcmp (arg, "--version")) {printf(UTIL_LINUX_VERSION);return EXIT_SUCCESS;}if (! strcmp (arg, "-h") || ! strcmp (arg, "--help"))return usage(EXIT_FAILURE);if (! strcmp (arg, "-a") || ! strcmp (arg, "--all")) {check_all++;continue;}if (! strcmp (arg, "-l") || ! strcmp (arg, "--list")) {if (argc < 2) {printsignals (stdout, 0);return EXIT_SUCCESS;}if (argc > 2)return usage (EXIT_FAILURE);/* argc == 2, accept "kill -l $?" */arg = argv[1];if ((numsig = arg_to_signum (arg, 1)) < 0)errx(EXIT_FAILURE, _("unknown signal: %s"), arg);printsig (numsig);return EXIT_SUCCESS;}/* for compatibility with procps kill(1) */if (! strncmp (arg, "--list=", 7) || ! strncmp (arg, "-l=", 3)) {char *p = strchr(arg, '=') + 1;if ((numsig = arg_to_signum(p, 1)) < 0)errx(EXIT_FAILURE, _("unknown signal: %s"), p);printsig (numsig);return EXIT_SUCCESS;}if (! strcmp (arg, "-L") || ! strcmp (arg, "--table")) {printsignals (stdout, 1);return EXIT_SUCCESS;}if (! strcmp (arg, "-p") || ! strcmp (arg, "--pid")) {do_pid++;if (do_kill)return usage (EXIT_FAILURE);continue;}if (! strcmp (arg, "-s") || ! strcmp (arg, "--signal")) {if (argc < 2) {return usage (EXIT_FAILURE);}do_kill++;if (do_pid)return usage (EXIT_FAILURE);argc--, argv++;arg = *argv;if ((numsig = arg_to_signum (arg, 0)) < 0) {nosig (arg);return EXIT_FAILURE;}continue;}if (! strcmp (arg, "-q") || ! strcmp (arg, "--queue")) {if (argc < 2)return usage (EXIT_FAILURE);argc--, argv++;arg = *argv;
#ifdef HAVE_SIGQUEUEsigdata.sival_int = strtos32_or_err(arg, _("invalid sigval argument"));use_sigval = 1;
#endifcontinue;}/*  `arg' begins with a dash but is not a known option.so it's probably something like -HUP, or -1/-ntry to deal with it.-n could be signal n, or pid -n (i.e. process group n).In case of doubt POSIX tells us to assume a signal.If a signal has been parsed, assume it's a pid, break */if (do_kill)break;arg++;if ((numsig = arg_to_signum (arg, 0)) < 0) {return usage (EXIT_FAILURE);}do_kill++;if (do_pid)return usage (EXIT_FAILURE);continue;}if (! *argv) {return usage (EXIT_FAILURE);}if (do_pid) {numsig = -1;}/*  we're done with the options.the rest of the arguments should be process ids and names.kill them.  */for (errors = 0; (arg = *argv) != NULL; argv++) {pid = strtol (arg, &ep, 10);if (! *ep)errors += kill_verbose (arg, pid, numsig);else  {struct proc_processes *ps = proc_open_processes();int ct = 0;if (!ps)continue;if (!check_all)proc_processes_filter_by_uid(ps, getuid());proc_processes_filter_by_name(ps, arg);while (proc_next_pid(ps, &pid) == 0) {errors += kill_verbose(arg, pid, numsig);ct++;}if (!ct) {errors++;warnx (_("cannot find process \"%s\""), arg);}proc_close_processes(ps);}}if (errors != 0)errors = EXIT_FAILURE;return errors;
}#ifdef SIGRTMIN
static int rtsig_to_signum(char *sig)
{int num, maxi = 0;char *ep = NULL;if (strncasecmp(sig, "min+", 4) == 0)sig += 4;else if (strncasecmp(sig, "max-", 4) == 0) {sig += 4;maxi = 1;}if (!isdigit(*sig))return -1;errno = 0;num = strtol(sig, &ep, 10);if (!ep || sig == ep || errno || num < 0)return -1;num = maxi ? SIGRTMAX - num : SIGRTMIN + num;if (num < SIGRTMIN || num > SIGRTMAX)return -1;return num;
}
#endifstatic int signame_to_signum (char *sig)
{size_t n;if (! strncasecmp (sig, "sig", 3))sig += 3;#ifdef SIGRTMIN/* RT signals */if (!strncasecmp(sig, "rt", 2))return rtsig_to_signum(sig + 2);
#endif/* Normal sugnals */for (n = 0; n < ARRAY_SIZE(sys_signame); n++) {if (! strcasecmp (sys_signame[n].name, sig))return sys_signame[n].val;}return (-1);
}static int arg_to_signum (char *arg, int maskbit)
{int numsig;char *ep;if (isdigit (*arg)) {numsig = strtol (arg, &ep, 10);if (numsig >= NSIG && maskbit && (numsig & 128) != 0)numsig -= 128;if (*ep != 0 || numsig < 0 || numsig >= NSIG)return (-1);return (numsig);}return signame_to_signum (arg);
}static void nosig (char *name)
{warnx (_("unknown signal %s; valid signals:"), name);printsignals (stderr, 1);
}static void printsig (int sig)
{size_t n;for (n = 0; n < ARRAY_SIZE(sys_signame); n++) {if (sys_signame[n].val == sig) {printf ("%s\n", sys_signame[n].name);return;}}
#ifdef SIGRTMINif (sig >= SIGRTMIN && sig <= SIGRTMAX) {printf ("RT%d\n", sig - SIGRTMIN);return;}
#endifprintf("%d\n", sig);
}#define FIELD_WIDTH 11
static void pretty_print_signal(FILE *fp, size_t term_width, size_t *lpos,int signum, const char *name)
{if (term_width < (*lpos + FIELD_WIDTH)) {fputc ('\n', fp);*lpos = 0;}*lpos += FIELD_WIDTH;fprintf (fp, "%2d %-8s", signum, name);
}static void printsignals (FILE *fp, int pretty)
{size_t n, lth, lpos = 0, width;if (!pretty) {for (n = 0; n < ARRAY_SIZE(sys_signame); n++) {lth = 1+strlen(sys_signame[n].name);if (lpos+lth > 72) {fputc ('\n', fp);lpos = 0;} else if (lpos)fputc (' ', fp);lpos += lth;fputs (sys_signame[n].name, fp);}
#ifdef SIGRTMINfputs (" RT<N> RTMIN+<N> RTMAX-<N>", fp);
#endiffputc ('\n', fp);return;}/* pretty print */width = get_terminal_width();if (width == 0)width = 72;elsewidth -= 1;for (n = 0; n < ARRAY_SIZE(sys_signame); n++)pretty_print_signal(fp, width, &lpos,sys_signame[n].val, sys_signame[n].name);#ifdef SIGRTMINpretty_print_signal(fp, width, &lpos, SIGRTMIN, "RTMIN");pretty_print_signal(fp, width, &lpos, SIGRTMAX, "RTMAX");
#endiffputc ('\n', fp);
}static int usage(int status)
{FILE *out = (status == 0 ? stdout : stderr);fputs(USAGE_HEADER, out);fprintf(out, _(" %s [options] <pid|name> [...]\n"), program_invocation_short_name);fputs(USAGE_OPTIONS, out);fputs(_(" -a, --all              do not restrict the name-to-pid conversion to processes\n""                        with the same uid as the present process\n"), out);fputs(_(" -s, --signal <sig>     send specified signal\n"), out);fputs(_(" -q, --queue <sig>      use sigqueue(2) rather than kill(2)\n"), out);fputs(_(" -p, --pid              print pids without signaling them\n"), out);fputs(_(" -l, --list [=<signal>] list signal names, or convert one to a name\n"), out);fputs(_(" -L, --table            list signal names and numbers\n"), out);fputs(USAGE_SEPARATOR, out);fputs(USAGE_HELP, out);fputs(USAGE_VERSION, out);fprintf(out, USAGE_MAN_TAIL("kill(1)"));return status;
}static int kill_verbose (char *procname, pid_t pid, int sig)
{int rc = 0;if (sig < 0) {printf ("%ld\n", (long)pid);return 0;}
#ifdef HAVE_SIGQUEUEif (use_sigval)rc = sigqueue(pid, sig, sigdata);else
#endifrc = kill (pid, sig);if (rc < 0) {warn(_("sending signal to %s failed"), procname);return 1;}return 0;
}

kill 与killall相关推荐

  1. 如何在 Linux 上使用 kill 和 killall 来管理进程

    了解如何使用 ps.kill 和 killall 命令来终止进程并回收系统资源. 在 Linux 中,每个程序和守护程序daemon都是一个"进程process". 大多数进程代表 ...

  2. Linux进程终止命令kill或killall​笔记

    在linux命令下,如果需要终止某个进程,可以使用kill或者killall等命令来实现.终止命令的原理都是向linux内核发送一个系统操作的信号以及某个进程的ID,然后系统内核会根据指定的进程ID进 ...

  3. Linux编程 7 (实时监测进程 top, 结束进程kill,killall)

    一. 实时监测进程 top 在一篇里讲到ps命令在收集进程信息时非常有用,但它只能显示某个特定时间点的信息.想要观察那些频繁换进换出的内存进程趋势,用top命令是合适的.使用top命令如下图所示: 在 ...

  4. 2023-04-03 Linux中杀死进程kill和killall命令的区别,着重介绍killall

    一.Linux killall 用于杀死一个进程,与 kill 不同的是它会杀死指定名字的所有进程.kill 命令杀死指定进程 PID,需要配合 ps 使用,而 killall 直接对进程对名字进行操 ...

  5. 【Linux】进程管理之kill、killall、pkill

    一.kill 命令   Linux 中的 kill 命令用来终止指定的进程的运行,是 Linux 下进程管理的常用命令.通常,终止一个前台进程可以使用 Ctrl+C 键,但是,对于一个后台进程就须用 ...

  6. Linux kill,killall和killall5

                          Linux kill,killall和killall5 kill和killall5这两个命令是系统自带的,即使最小化安装也有的命令,killall这个命令如 ...

  7. Linux笔记 No.20---(进程管理工具:ps、pstree、top、pgrep、kill、killall、pkill、查看系统资源的使用vmstat)

    文章目录 一.定时任务crontab实现每秒执行 二.进程 (一)Linux程序与进程 1.程序和进程的区别 2.进程和线程的区别 3.父子进程的关系 三.进程管理工具 (一)ps命令 (二)pstr ...

  8. pkill mysql_终止进程的工具kill,killall和pkill

    终止一个进程或终止一个正在运行的程序,一般是通过kill .killall.pkill等进行.比如一个程序已经死掉,但又不能退出,这时就应该考虑应用这些工具. 另外应用的场合就是在服务器管理中,在不涉 ...

  9. 几个进程管理的命令:pkill,pidof,kill,killall,job

    pkill命令可以按照进程名杀死进程.pkill和killall应用方法差不多,也是直接杀死运行中的程序:如果您想杀掉单个进程,请用kill来杀掉. pkill命令可以按照进程名杀死进程.pkill和 ...

  10. pkill mysql_centos下kill、killall、pkill命令区别

    kill是用来终止进程的 首先可以通过ps aux查看系统有哪些进程正在运行. 1.用kill来杀死某一个进程 #kill,加选项-9,加PID,表示杀死进程编号为PID的这个进程 # -1 重启 # ...

最新文章

  1. 近万个Python开源项目中精选Top34!
  2. 这些 IDEA 的优化设置赶紧安排起来,效率提升不是一点点!
  3. 进阶学习(3.7) Flyweight Pattern 享元模式
  4. 利用SQL05特性删除表中重复数据
  5. java web前后台交互_前后端交互(javaweb)
  6. 线程池是如何复用的?
  7. php mysql 替换 pdo,php操作MySQL数据库之PDO方式
  8. java for 面试题_Java面试题整理
  9. 艾伯维与和铂医药合作开发新冠病毒抗体;欧莱雅发起中国首个美妆科技初创挑战赛 | 美通企业日报...
  10. Jetson-TX2双声卡TLV320AIC32x4 alsa实现同时录音与播放
  11. 银河帝国----基地前奏
  12. jupyter notebook 误删恢复
  13. 剑指offer 62题 约瑟夫环
  14. 关于可计算、图灵机及CPU性能
  15. 电大计算机西方经济学考试题库,2011电大西方经济学网上作业1.2.3全部答案
  16. 个推+mui+html5 +java完成消息推送
  17. el-table使用lazy-tree模式,数据重载节点中的tree数据不会更新的问题
  18. React 更新阶段的生命周期 componentWillReceiveProps->shouldComponentUpdate->componentWillUpdate
  19. GSMS软件系统华为应急通讯完美版安装教程
  20. 机器人用的是什么编程语言

热门文章

  1. C#未将对象引用设置到对象的实例
  2. 爆肝整理|BAT100道JavaScrip面试真题集锦(附解析)
  3. Linux常用查看命令
  4. python+selenium进行web自动化测试
  5. 平安人寿多模态合成AI视频机器人:行业首个具备大规模应用能力的多模态合成机器人 | 百万人学AI评选
  6. 用Python抓包工具查看周边拼车情况
  7. android9.0魅族16,flyme太卡?魅友抢先为魅族16适配安卓9.0,还有MIUI10
  8. 存储器: Flash,eeprom,rom,ram
  9. 量化投资学习-3:股票与美女3-美女的股东婆家和娘家
  10. easyexcel设置单元格格式为文本