Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pause a running script in Mac terminal and then resume later

How can I pause (not stop) a running script from Terminal in OSX, to resume it later from the point it paused?

like image 758
Jikku Jose Avatar asked Dec 18 '13 04:12

Jikku Jose


People also ask

How do I resume my paused application on Mac?

In the search bar, search for the application "Terminal" and open it. In the text area of Terminal type the code "kill -CONT 155". Replacing the '155' with the PID number of the application you want to un-pause.

How do you pause resume in terminal?

Stop, Pause & Resume Terminal Processes: Let's start by getting the terminal open by using your keyboard and pressing CTRL + ALT + T . Once started that command will keep running over and over again. I assume you don't need to keep pinging forever, so you can stop it with CTRL + C . That's it.

How do you pause a script?

Execution of a batch script can also be paused by pressing CTRL-S (or the Pause|Break key) on the keyboard, this also works for pausing a single command such as a long DIR /s listing. Pressing any key will resume the operation. Pause is often used at the end of a script to give the user time to read some output text.


3 Answers

If you're using BASH as the shell (which is the default shell on a Mac), you can use BASH's built in job control capabilities.

If the script is running in the foreground of your terminal, you can press Control-Z to pause the script. This will suspend the running of the script.

To restart it, type jobs and you'll see the suspended job listed there. Type fg or more specific fg %x where x is the number of the suspended job.

$ test.pl   # Test script (prints out Foo every two seconds
Foo!
Foo!
^Z
$  # Job has been suspended
$ jobs
[1] + Stopped                  ./test.pl
$ fg %1  #Restarts Job #1
Foo!

The Control-Z key that suspends the job is the default, but could be modified. The stty can change this and will show you the current default:

$ stty -a     
speed 9600 baud; 40 rows; 120 columns;
lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl
        -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
        -extproc
iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel iutf8
        -ignbrk brkint -inpck -ignpar -parmrk
oflags: opost onlcr -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
        -dtrflow -mdmbuf
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;
        eol2 = <undef>; erase = ^H; intr = ^C; kill = ^U; lnext = ^V;
        min = 1; quit = ^\; reprint = ^R; start = ^Q; status = ^T;
        stop = ^S; susp = ^Z; time = 0; werase = ^W;

You can see the very last line has susp = ^Z. This is the key that will suspend your script. In this case, it's Control-Z.

You can also use the bg command to make a suspended job run in the background. However, that background job will terminate when you close the shell/Terminal Window unless you had prepended nohup to the front of the command.

like image 147
David W. Avatar answered Oct 21 '22 08:10

David W.


Find the process ID of the running script.

To stop (or what you refer to as pause) the script, say:

kill -SIGSTOP PID

To resume the stopped (or paused) process, say:

kill -SIGCONT PID

(where PID refers to the numeric process ID.)

like image 11
devnull Avatar answered Oct 21 '22 06:10

devnull


To complement devnull's and DavidW's helpful answers:
Here are convenience functions for suspending (pausing) / resuming a script by name, from any shell (not just the one that started the script):

Pass the script's filename(s) (without path):

suspend-script someScript ...

and later:

resume-script someScript ...

Update: Added additional function for killing a script by name: kill-script someScript ...

  • Works with scripts run by either bash or sh (which is effectively just a bash alias on macOS).
  • If multiple instances of a script are running, only the most recently started is targeted.
  • Exit code will be non-zero in case of failure (including not finding a running script by the given name).
  • suspend-script and resume-script: if a script process is already in the desired state, no operation is performed (and no error is reported).

Functions (e.g., place them in ~/.bash_profile):

suspend-script() {
  [[ -z $1 || $1 == '-h' || $1 == '--help' ]] && { echo "Usage: $FUNCNAME scriptFileName ..."$'\n'"Suspends the specified bash/sh script(s)."; return $(( ${#1} == 0 )); }
  local ec=0
  for p in "$@"; do
    pkill -STOP -nf '/?(bash|sh)[ ]+(.*/)?'"$p"'( |$)' \
      && echo "'$1' suspended." \
      || { ec=$?; echo "ERROR: bash/sh script process not found: '$p'" 1>&2; }
  done
  return $ec
}

resume-script() {
  [[ -z $1 || $1 == '-h' || $1 == '--help' ]] && { echo "Usage: $FUNCNAME scriptFileName ..."$'\n'"Resumes the specified bash/sh script(s)."; return $(( ${#1} == 0 )); }
  local ec=0
  for p in "$@"; do
    pkill -CONT -nf '/?(bash|sh)[ ]+(.*/)?'"$p"'( |$)' \
     && echo "'$1' resumed." \
     || { ec=$?; echo "ERROR: bash/sh script process not found: '$p'" 1>&2; }
  done
  return $ec
}

kill-script() {
  [[ -z $1 || $1 == '-h' || $1 == '--help' ]] && { echo "Usage: $FUNCNAME scriptFileName ..."$'\n'"Kills the specified bash/sh script(s)."; return $(( ${#1} == 0 )); }
  local ec=0
  for p in "$@"; do
    pkill -nf '/?(bash|sh)[ ]+(.*/)?'"$p"'( |$)' \
     && echo "'$1' killed." \
     || { ec=$?; echo "ERROR: bash/sh script process not found: '$p'" 1>&2; }
  done
  return $ec
}
like image 4
mklement0 Avatar answered Oct 21 '22 08:10

mklement0