在Mac终端中暂停正在运行的脚本,然后再继续

Jik*_*ose 17 macos bash terminal

如何从OSX中的终端暂停(不停止)正在运行的脚本,以便稍后从暂停的点恢复?

Dav*_* W. 44

如果您使用BASH作为shell(它是Mac上的默认shell),您可以使用BASH的内置作业控制功能.

如果脚本在终端的前台运行,您可以按Control- Z暂停脚本.这将暂停脚本的运行.

要重新启动它,请键入,jobs然后您将看到其中列出的已暂停作业.键入fg或更具体fg %x在哪里x是暂停作业的编号.

$ 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!
Run Code Online (Sandbox Code Playgroud)

挂起作业的Control-Z键是默认值,但可以修改.该stty的可以改变这一点,会告诉你当前的默认:

$ 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;
Run Code Online (Sandbox Code Playgroud)

你可以看到最后一行有susp = ^Z.这是暂停脚本的关键.在这种情况下,它是Control-Z.

您还可以使用该bg命令在后台运行暂停的作业.但是,当您关闭shell /终端窗口时,后台作业将终止,除非您已将nohup添加到命令的前面.

  • 我认为这值得一试 (6认同)
  • 优秀!这绝对值得标记为答案。 (2认同)

dev*_*ull 9

找到正在运行的脚本的进程ID.

要停止(或称为暂停)脚本,请说:

kill -SIGSTOP PID
Run Code Online (Sandbox Code Playgroud)

要恢复已停止(或暂停)的过程,请说:

kill -SIGCONT PID
Run Code Online (Sandbox Code Playgroud)

(其中PID是指数字进程ID.)

  • 除此之外,他可以按Ctrl-Z暂停,然后再按"fg"继续. (3认同)

mkl*_*nt0 4

为了补充devnullDavidW 的有用答案:
以下是从任何shell(不仅仅是启动脚本的 shell)按名称暂停(暂停)/恢复脚本的便捷函数:

传递脚本的文件名(不带路径):

suspend-script someScript ...

然后:

resume-script someScript ...

更新:添加了按名称杀死脚本的附加功能:kill-script someScript ...

  • 与由bash或运行的脚本一起使用sh(这实际上只是bashmacOS 上的别名)。
  • 如果脚本的多个实例正在运行,则仅针对最近启动的实例。
  • 如果失败(包括未找到给定名称的正在运行的脚本),退出代码将为非零。
  • suspend-scriptresume-script:如果脚本进程已经处于所需状态,则不执行任何操作(并且不报告错误)。

函数(例如,将它们放在 中~/.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
}
Run Code Online (Sandbox Code Playgroud)