mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-01 09:29:51 +02:00
fix for crash without arrays built in; allow some job status changes while the jobs list is frozen; change format for interactive shell terminated job notifications; allow some job notifications while running traps
This commit is contained in:
@@ -9277,3 +9277,53 @@ subst.c
|
||||
- function_substitute: make sure we unbind the local REPLY we created
|
||||
at the current (fake) context
|
||||
From a report by Koichi Murase <myoga.murase@gmail.com>
|
||||
|
||||
4/30
|
||||
----
|
||||
|
||||
subst.c
|
||||
- expand_arrayref: fix crash from freeing memory that's only allocated
|
||||
and initialized if ARRAY_VARS is defined
|
||||
Report and patch from Henrik Lindström <henrik@lxm.se>
|
||||
|
||||
jobs.h,jobs.c
|
||||
- JLIST_POSIX: new format argument for pretty_print_job; implements
|
||||
POSIX requirement that jobs display the status of all background
|
||||
jobs and all jobs the user hasn't been notified about (unused yet)
|
||||
- JLIST_BGONLY: new format argument for pretty_print_job; restricts
|
||||
output to background jobs only (unused yet)
|
||||
|
||||
jobs.c,jobs.h,execute_cmd.c,subst.c
|
||||
- freeze_jobs_list: now takes an int argument with the new value of
|
||||
jobs_list_frozen; prep for having different values with different
|
||||
meanings; changed callers
|
||||
|
||||
jobs.c
|
||||
- wait_for_any_job: return right away if jobs_list_frozen > 0; allow
|
||||
job status changes (e.g., J_NOTIFIED) if jobs_list_frozen < 0; use
|
||||
this instead of testing executing_funsub directly
|
||||
- notify_and_cleanup: allow notification and status change if
|
||||
jobs_list_frozen < 0; don't delete any dead jobs
|
||||
- should_notify: takes a job index and returns 1 if the shell would
|
||||
notify the user about it, given the current job state
|
||||
- pretty_print_job: if the jobs list is frozen, only print status
|
||||
about jobs for which the shell would notify users (by calling
|
||||
should_notify())
|
||||
|
||||
subst.c
|
||||
- function_substitute: freeze the jobs list with value -1 so jobs
|
||||
can change status and possibly inhibit printing by `jobs'
|
||||
|
||||
5/2
|
||||
---
|
||||
jobs.c
|
||||
- notify_and_cleanup: allow job notifications if an interactive shell
|
||||
is running a trap (interactive == 0 && interactive_shell && running_trap)
|
||||
Fixes report by Koichi Murase <myoga.murase@gmail.com> on 11/14/2022
|
||||
- print_pipeline: don't print an extra space before the pipeline; push
|
||||
that into pretty_print_job; print the space after the pid if we
|
||||
print one
|
||||
|
||||
jobs.h
|
||||
- LONGEST_SIGNAL_DESC: update to 27 (macos SIGPROF). This changes the
|
||||
test output
|
||||
|
||||
@@ -728,6 +728,7 @@ support/mkinstalldirs f 755
|
||||
support/mkversion.sh f 755
|
||||
support/mksignames.c f
|
||||
support/signames.c f
|
||||
support/siglen.c f
|
||||
support/bashbug.sh f
|
||||
support/bashbug.sh.in f
|
||||
support/man2html.c f
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@
|
||||
|
||||
/* Define DONT_REPORT_SIGTERM if you don't want to see `Terminated' message
|
||||
when a job exits due to SIGTERM, since that's the default signal sent
|
||||
by the kill builtin. */
|
||||
by the kill builtin. Only effective for non-interactive shells. */
|
||||
#define DONT_REPORT_SIGTERM
|
||||
|
||||
/* Define DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS if you don't want builtins
|
||||
|
||||
-25
@@ -14,31 +14,6 @@
|
||||
.if \n(zY=1 .ig zY
|
||||
.TH BASH 1 "2024 April 23" "GNU Bash 5.3"
|
||||
.\"
|
||||
.\" There's some problem with having a `@'
|
||||
.\" in a tagged paragraph with the BSD man macros.
|
||||
.\" It has to do with `@' appearing in the }1 macro.
|
||||
.\" This is a problem on 4.3 BSD and Ultrix, but Sun
|
||||
.\" appears to have fixed it.
|
||||
.\" If you're seeing the characters
|
||||
.\" `@u-3p' appearing before the lines reading
|
||||
.\" `possible-hostname-completions
|
||||
.\" and `complete-hostname' down in READLINE,
|
||||
.\" then uncomment this redefinition.
|
||||
.\"
|
||||
.\" .de }1
|
||||
.\" .ds ]X \&\\*(]B\\
|
||||
.\" .nr )E 0
|
||||
.\" .if !"\\$1"" .nr )I \\$1n
|
||||
.\" .}f
|
||||
.\" .ll \\n(LLu
|
||||
.\" .in \\n()Ru+\\n(INu+\\n()Iu
|
||||
.\" .ti \\n(INu
|
||||
.\" .ie !\\n()Iu+\\n()Ru-\w\\*(]Xu-3p \{\\*(]X
|
||||
.\" .br\}
|
||||
.\" .el \\*(]X\h|\\n()Iu+\\n()Ru\c
|
||||
.\" .}f
|
||||
.\" ..
|
||||
.\"
|
||||
.ie \n(.g \{\
|
||||
.ds ' \(aq
|
||||
.ds " \(dq
|
||||
|
||||
+5
-1
@@ -2695,7 +2695,7 @@ execute_pipeline (COMMAND *command, int asynchronous, int pipe_in, int pipe_out,
|
||||
prev = NO_PIPE;
|
||||
add_unwind_protect (uw_restore_stdin, (void *) (intptr_t) lstdin);
|
||||
lastpipe_flag = 1;
|
||||
old_frozen = freeze_jobs_list ();
|
||||
old_frozen = freeze_jobs_list (1);
|
||||
lastpipe_jid = stop_pipeline (0, (COMMAND *)NULL); /* XXX */
|
||||
add_unwind_protect (uw_lastpipe_cleanup, (void *) (intptr_t) old_frozen);
|
||||
#if defined (JOB_CONTROL)
|
||||
@@ -2831,6 +2831,10 @@ execute_connection (COMMAND *command, int asynchronous, int pipe_in, int pipe_ou
|
||||
#endif
|
||||
|
||||
QUIT;
|
||||
#if defined (JOB_CONTROL)
|
||||
if (command->value.Connection->connector == ';' && job_control && interactive)
|
||||
notify_and_cleanup ();
|
||||
#endif
|
||||
optimize_connection_fork (command); /* XXX */
|
||||
exec_result = execute_command_internal (command->value.Connection->second,
|
||||
asynchronous, pipe_in, pipe_out,
|
||||
|
||||
@@ -337,10 +337,11 @@ static SigHandler *old_cont = (SigHandler *)SIG_DFL;
|
||||
/* A place to temporarily save the current pipeline. */
|
||||
static struct pipeline_saver *saved_pipeline;
|
||||
|
||||
/* Set this to non-zero whenever you don't want the jobs list to change at
|
||||
/* Set this to 1 whenever you don't want the jobs list to change at
|
||||
all: no jobs deleted and no status change notifications. This is used,
|
||||
for example, when executing SIGCHLD traps, which may run arbitrary
|
||||
commands. */
|
||||
commands. Set to -1 if you allow status change notifications but no
|
||||
jobs deleted. 0 means everything is allowed. */
|
||||
static int jobs_list_frozen;
|
||||
|
||||
static char retcode_name_buffer[64];
|
||||
@@ -1905,19 +1906,26 @@ printable_job_status (int j, PROCESS *p, int format)
|
||||
/* This is the way to print out information on a job if you
|
||||
know the index. FORMAT is:
|
||||
|
||||
JLIST_NORMAL) [1]+ Running emacs
|
||||
JLIST_STANDARD) [1]+ Running emacs
|
||||
JLIST_LONG ) [1]+ 2378 Running emacs
|
||||
-1 ) [1]+ 2378 emacs
|
||||
|
||||
JLIST_NORMAL) [1]+ Stopped ls | more
|
||||
JLIST_STANDARD) [1]+ Stopped ls | more
|
||||
JLIST_LONG ) [1]+ 2369 Stopped ls
|
||||
2367 | more
|
||||
JLIST_PID_ONLY)
|
||||
Just list the pid of the process group leader (really
|
||||
the process group).
|
||||
JLIST_CHANGED_ONLY)
|
||||
Use format JLIST_NORMAL, but list only jobs about which
|
||||
the user has not been notified. */
|
||||
Use format JLIST_STANDARD, but list only jobs about which
|
||||
the user has not been notified.
|
||||
JLIST_POSIX)
|
||||
Use format JLIST_STANDARD, list all background jobs, running
|
||||
and stopped, plus jobs about which the user has not been
|
||||
notified (that would be notified)
|
||||
JLIST_BGONLY)
|
||||
Use format JLIST_STANDARD, but restrict output to background
|
||||
jobs only. */
|
||||
|
||||
/* Print status for pipeline P. If JOB_INDEX is >= 0, it is the index into
|
||||
the JOBS array corresponding to this pipeline. FORMAT is as described
|
||||
@@ -1945,9 +1953,14 @@ print_pipeline (PROCESS *p, int job_index, int format, FILE *stream)
|
||||
fprintf (stream, format ? " " : " |");
|
||||
|
||||
if (format != JLIST_STANDARD)
|
||||
fprintf (stream, "%5ld", (long)p->pid);
|
||||
{
|
||||
fprintf (stream, "%5ld", (long)p->pid);
|
||||
if (p == first)
|
||||
fprintf (stream, " ");
|
||||
}
|
||||
|
||||
fprintf (stream, " ");
|
||||
if (p != first)
|
||||
fprintf (stream, " ");
|
||||
|
||||
if (format > -1 && job_index >= 0)
|
||||
{
|
||||
@@ -2021,6 +2034,29 @@ print_pipeline (PROCESS *p, int job_index, int format, FILE *stream)
|
||||
fflush (stream);
|
||||
}
|
||||
|
||||
/* We want to print information about a job if it's running or terminated in
|
||||
the background, if it's stopped, or if it was a foreground job terminated
|
||||
due to a signal that we don't ignore (SIGINT and possibly SIGTERM and
|
||||
SIGPIPE). If we change this, change the conditions in notify_of_job_status()
|
||||
so they stay consistent.
|
||||
|
||||
This is for use by the jobs builtin. */
|
||||
|
||||
static int
|
||||
should_notify (int job)
|
||||
{
|
||||
/* Background jobs, stopped jobs whether they were in the foreground or
|
||||
background. */
|
||||
if ((IS_FOREGROUND (job) == 0) || STOPPED (job))
|
||||
return 1;
|
||||
|
||||
/* Foreground job killed by a signal we report on. */
|
||||
if (DEADJOB (job) && IS_FOREGROUND (job) && job_killed_by_signal (job))
|
||||
return 1;
|
||||
|
||||
return 0; /* catch-all */
|
||||
}
|
||||
|
||||
/* Print information to STREAM about jobs[JOB_INDEX] according to FORMAT.
|
||||
Must be called with SIGCHLD blocked or queued with queue_sigchld */
|
||||
static void
|
||||
@@ -2028,6 +2064,13 @@ pretty_print_job (int job_index, int format, FILE *stream)
|
||||
{
|
||||
register PROCESS *p;
|
||||
|
||||
/* If the jobs list is frozen, skip jobs we would remove and not report on */
|
||||
if (jobs_list_frozen && should_notify (job_index) == 0)
|
||||
return;
|
||||
|
||||
if (format == JLIST_BGONLY && IS_FOREGROUND (job_index))
|
||||
return;
|
||||
|
||||
/* Format only pid information about the process group leader? */
|
||||
if (format == JLIST_PID_ONLY)
|
||||
{
|
||||
@@ -2041,6 +2084,12 @@ pretty_print_job (int job_index, int format, FILE *stream)
|
||||
return;
|
||||
format = JLIST_STANDARD;
|
||||
}
|
||||
else if (format == JLIST_POSIX)
|
||||
{
|
||||
if (IS_FOREGROUND (job_index) && IS_NOTIFIED (job_index))
|
||||
return;
|
||||
format = JLIST_STANDARD;
|
||||
}
|
||||
|
||||
if (format != JLIST_NONINTERACTIVE)
|
||||
fprintf (stream, "[%d]%c ", job_index + 1,
|
||||
@@ -2050,8 +2099,10 @@ pretty_print_job (int job_index, int format, FILE *stream)
|
||||
if (format == JLIST_NONINTERACTIVE)
|
||||
format = JLIST_LONG;
|
||||
|
||||
p = jobs[job_index]->pipe;
|
||||
if (format == JLIST_STANDARD)
|
||||
fprintf (stream, "%c", ' '); /* used to be in print_pipeline */
|
||||
|
||||
p = jobs[job_index]->pipe;
|
||||
print_pipeline (p, job_index, format, stream);
|
||||
|
||||
/* We have printed information about this job. When the job's
|
||||
@@ -3275,7 +3326,7 @@ wait_for_any_job (int flags, struct procstat *ps)
|
||||
sigset_t set, oset;
|
||||
|
||||
/* Allow funsubs to run this, but don't remove jobs from the jobs table. */
|
||||
if (jobs_list_frozen && executing_funsub == 0)
|
||||
if (jobs_list_frozen > 0)
|
||||
return -1;
|
||||
|
||||
/* First see if there are any unnotified dead jobs that we can report on */
|
||||
@@ -3297,13 +3348,11 @@ return_job:
|
||||
if (jobs_list_frozen == 0) /* must be running a funsub to get here */
|
||||
{
|
||||
notify_of_job_status (); /* XXX */
|
||||
#if 1 /* kre@munnari.oz.au 01/30/2024 */
|
||||
|
||||
/* kre@munnari.oz.au 01/30/2024 */
|
||||
delete_job (i, posixly_correct ? DEL_NOBGPID : 0);
|
||||
#else
|
||||
delete_job (i, 0);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
else /* if (jobs_list_frozen < 0) */ /* status changes only */
|
||||
jobs[i]->flags |= J_NOTIFIED; /* clean up later */
|
||||
#if defined (COPROCESS_SUPPORT)
|
||||
coproc_reap ();
|
||||
@@ -3371,12 +3420,15 @@ return_job:
|
||||
void
|
||||
notify_and_cleanup (void)
|
||||
{
|
||||
if (jobs_list_frozen)
|
||||
if (jobs_list_frozen > 0)
|
||||
return;
|
||||
|
||||
if (interactive || interactive_shell == 0 || sourcelevel)
|
||||
if (interactive || interactive_shell == 0 || sourcelevel || (interactive_shell && running_trap))
|
||||
notify_of_job_status ();
|
||||
|
||||
if (jobs_list_frozen < 0)
|
||||
return; /* status changes only */
|
||||
|
||||
cleanup_dead_jobs ();
|
||||
}
|
||||
|
||||
@@ -4357,14 +4409,19 @@ notify_of_job_status (void)
|
||||
if (termsig && WIFSIGNALED (s) && termsig != SIGINT && termsig != SIGPIPE)
|
||||
#endif
|
||||
{
|
||||
#if 0
|
||||
fprintf (stderr, "%s", j_strsignal (termsig));
|
||||
|
||||
if (WIFCORED (s))
|
||||
fprintf (stderr, _(" (core dumped)"));
|
||||
|
||||
fprintf (stderr, "\n");
|
||||
#else
|
||||
print_pipeline (jobs[job]->pipe, job, JLIST_STANDARD, stderr);
|
||||
#endif
|
||||
}
|
||||
/* foreground jobs that exit cleanly */
|
||||
/* foreground jobs that exit cleanly or due to a signal we
|
||||
don't report on */
|
||||
jobs[job]->flags |= J_NOTIFIED;
|
||||
}
|
||||
else if (job_control)
|
||||
@@ -4970,12 +5027,12 @@ itrace("mark_dead_jobs_as_notified: child_max = %d ndead = %d ndeadproc = %d", j
|
||||
/* Here to allow other parts of the shell (like the trap stuff) to
|
||||
freeze and unfreeze the jobs list. */
|
||||
int
|
||||
freeze_jobs_list (void)
|
||||
freeze_jobs_list (int n)
|
||||
{
|
||||
int o;
|
||||
|
||||
o = jobs_list_frozen;
|
||||
jobs_list_frozen = 1;
|
||||
jobs_list_frozen = n;
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,9 +34,14 @@
|
||||
#define JLIST_PID_ONLY 2
|
||||
#define JLIST_CHANGED_ONLY 3
|
||||
#define JLIST_NONINTERACTIVE 4
|
||||
#define JLIST_POSIX 5
|
||||
#define JLIST_BGONLY 6
|
||||
|
||||
/* I looked it up. For pretty_print_job (). The real answer is 24. */
|
||||
#define LONGEST_SIGNAL_DESC 24
|
||||
/* I looked it up. For pretty_print_job (). The real answer is 27
|
||||
(macOS SIGPROF) but the makefile or configure can override it. */
|
||||
#ifndef LONGEST_SIGNAL_DESC
|
||||
# define LONGEST_SIGNAL_DESC 27
|
||||
#endif
|
||||
|
||||
/* Defines for the wait_for_* functions and for the wait builtin to use */
|
||||
#define JWAIT_PERROR (1 << 0)
|
||||
@@ -301,7 +306,7 @@ extern int give_terminal_to (pid_t, int);
|
||||
|
||||
extern void run_sigchld_trap (int);
|
||||
|
||||
extern int freeze_jobs_list (void);
|
||||
extern int freeze_jobs_list (int);
|
||||
extern int unfreeze_jobs_list (void);
|
||||
extern void set_jobs_list_frozen (int);
|
||||
extern int jobs_list_frozen_status (void);
|
||||
|
||||
@@ -1010,7 +1010,7 @@ describe_pid (pid_t pid)
|
||||
}
|
||||
|
||||
int
|
||||
freeze_jobs_list (void)
|
||||
freeze_jobs_list (int n)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -7242,9 +7242,11 @@ flush_parser_state (sh_parser_state_t *ps)
|
||||
FREE (ps->token_state);
|
||||
ps->token_state = 0;
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
if (ps->pipestatus)
|
||||
array_dispose (ps->pipestatus);
|
||||
ps->pipestatus = 0;
|
||||
#endif
|
||||
|
||||
/* We want to free the saved token and leave the current token for error
|
||||
reporting and cleanup. */
|
||||
|
||||
@@ -448,7 +448,7 @@ main (int argc, char **argv, char **env)
|
||||
|
||||
/* Fix for the `infinite process creation' bug when running shell scripts
|
||||
from startup files on System V. */
|
||||
login_shell = make_login_shell = 0;
|
||||
login_shell = make_login_shell = su_shell = 0;
|
||||
|
||||
/* If this shell has already been run, then reinitialize it to a
|
||||
vanilla state. */
|
||||
@@ -1996,7 +1996,7 @@ shell_reinitialize (void)
|
||||
no_rc = no_profile = 1;
|
||||
|
||||
/* Things that get 0. */
|
||||
login_shell = make_login_shell = executing = 0;
|
||||
login_shell = make_login_shell = su_shell = executing = 0;
|
||||
debugging = debugging_mode = 0;
|
||||
do_version = line_number = last_command_exit_value = 0;
|
||||
forced_interactive = interactive_shell = interactive = 0;
|
||||
|
||||
@@ -7088,8 +7088,10 @@ function_substitute (char *string, int quoted, int flags)
|
||||
add_unwind_protect (uw_unbind_localvar, "REPLY");
|
||||
}
|
||||
|
||||
old_frozen = freeze_jobs_list ();
|
||||
#if 1 /* TAG:bash-5.3 myoga.murase@gmail.com 04/30/2024 */
|
||||
old_frozen = freeze_jobs_list (-1);
|
||||
add_unwind_protect (uw_lastpipe_cleanup, (void *) (intptr_t) old_frozen);
|
||||
#endif
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
unwind_protect_var (pipeline_pgrp);
|
||||
@@ -7806,7 +7808,9 @@ expand_arrayref:
|
||||
|
||||
temp = quote_var_value (temp, quoted, pflags);
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
FREE (tt);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
temp = (char *)NULL;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i, l, longest, verb;
|
||||
size_t len;
|
||||
char *msg;
|
||||
|
||||
verb = (argc > 1 && argv[1] && strcmp (argv[1], "-l") == 0);
|
||||
|
||||
longest = 0;
|
||||
for (i = 0; i < NSIG; i++) {
|
||||
msg = strsignal (i);
|
||||
len = msg ? strlen (msg) : 0;
|
||||
l = len;
|
||||
if (msg && verb)
|
||||
printf ("%d\t%s\n", l, msg);
|
||||
if (l > longest)
|
||||
longest = l;
|
||||
}
|
||||
printf ("%d\n", longest);
|
||||
exit (0);
|
||||
}
|
||||
+25
-25
@@ -16,17 +16,17 @@ Waiting for job 6
|
||||
job 6 returns 0
|
||||
Waiting for job 7
|
||||
job 7 returns 0
|
||||
[1] Running sleep 2 &
|
||||
[2] Running sleep 2 &
|
||||
[3] Running sleep 2 &
|
||||
[4]- Running sleep 2 &
|
||||
[5]+ Running ( sleep 2; exit 4 ) &
|
||||
[1] Running sleep 2 &
|
||||
[2] Running sleep 2 &
|
||||
[3] Running sleep 2 &
|
||||
[4]- Running sleep 2 &
|
||||
[5]+ Running ( sleep 2; exit 4 ) &
|
||||
4
|
||||
0
|
||||
i killed it
|
||||
12
|
||||
[1]- Running sleep 20 &
|
||||
[3]+ Running sleep 20 &
|
||||
[1]- Running sleep 20 &
|
||||
[3]+ Running sleep 20 &
|
||||
5: ok 1
|
||||
./jobs5.sub: line 40: wait: %8: no such job
|
||||
2: ok 2
|
||||
@@ -53,7 +53,7 @@ async list wait for child
|
||||
forked
|
||||
wait-when-no-children
|
||||
posix jobs output
|
||||
[1]+ Done sleep 1
|
||||
[1]+ Done sleep 1
|
||||
wait-for-job
|
||||
./jobs.tests: line 96: wait: %2: no such job
|
||||
127
|
||||
@@ -84,36 +84,36 @@ wait-for-non-child
|
||||
./jobs.tests: line 150: wait: pid 1 is not a child of this shell
|
||||
127
|
||||
3 -- 1 2 3 -- 1 - 2 - 3
|
||||
[1] Running sleep 300 &
|
||||
[2]- Running sleep 350 &
|
||||
[3]+ Running sleep 400 &
|
||||
[1] Running sleep 300 &
|
||||
[2]- Running sleep 350 &
|
||||
[3]+ Running sleep 400 &
|
||||
running jobs:
|
||||
[1] Running sleep 300 &
|
||||
[2]- Running sleep 350 &
|
||||
[3]+ Running sleep 400 &
|
||||
[1] Running sleep 300 &
|
||||
[2]- Running sleep 350 &
|
||||
[3]+ Running sleep 400 &
|
||||
./jobs.tests: line 167: kill: %4: no such job
|
||||
./jobs.tests: line 169: jobs: %4: no such job
|
||||
current job:
|
||||
[3]+ Running sleep 400 &
|
||||
[3]+ Running sleep 400 &
|
||||
previous job:
|
||||
[2]- Running sleep 350 &
|
||||
[2]- Running sleep 350 &
|
||||
after kill -STOP
|
||||
running jobs:
|
||||
[1] Running sleep 300 &
|
||||
[3]- Running sleep 400 &
|
||||
[1] Running sleep 300 &
|
||||
[3]- Running sleep 400 &
|
||||
stopped jobs:
|
||||
[2]+ Stopped sleep 350
|
||||
[2]+ Stopped sleep 350
|
||||
after disown
|
||||
[2]+ Stopped sleep 350
|
||||
[3]- Running sleep 400 &
|
||||
[2]+ Stopped sleep 350
|
||||
[3]- Running sleep 400 &
|
||||
running jobs:
|
||||
[3]- Running sleep 400 &
|
||||
[3]- Running sleep 400 &
|
||||
stopped jobs:
|
||||
[2]+ Stopped sleep 350
|
||||
[2]+ Stopped sleep 350
|
||||
after kill -s CONT
|
||||
running jobs:
|
||||
[2]+ Running sleep 350 &
|
||||
[3]- Running sleep 400 &
|
||||
[2]+ Running sleep 350 &
|
||||
[3]- Running sleep 400 &
|
||||
stopped jobs:
|
||||
after kill -STOP, backgrounding %3:
|
||||
[3]+ sleep 400 &
|
||||
|
||||
Reference in New Issue
Block a user