- 类型Ctrl+Z
- 运行
%&
或bg
但是,我希望在不中断进程太多的情况下做到这一点(不要在我输入内容以重新启动它时让它暂停很长时间)。例如,如果它正在播放音频,而我不想干扰它。看起来在运行时没有办法真正移动它(请参阅这和这),但我很乐意接受一个快捷方式,它可以一步完成上述两个操作。
这里有一个类似的问题,但是关于 zsh:我如何才能通过一次按下 Ctrl-Z 和 bg 来使进程在后台继续?
答案1
命令当然可以合并,但触发它们却很困难。
一个选项是约束在 shell 中按 Ctrl-Z因此,您可以点击一次来暂停,然后再次点击来bg
。
我的解决方案是设置全局快捷方式来运行脚本完成这项工作。首先,活动终端窗口中运行的 shell 的 PID得到。然后获取前台进程,最后暂停并恢复。如果你想杀死它,也是同样的方法。
一个恼人的问题是 KDE 的 konsole,它每个终端窗口都有一个进程。我在这里找到了答案,或者至少它为我指明了正确的方向:http://wundermark.blogspot.com.au/2013/01/the-sick-and-twisted-world-of.html?m=1
脚本如下:
#!/bin/bash
#get the active window
WID=$( xprop -root _NET_ACTIVE_WINDOW | grep -o '0x[0-9a-f]\+' )
#get the parent's process ID (looks like I don't need this as there's only ever one konsole/gnome-terminal process running)
TPID=$( xprop -id $WID _NET_WM_PID | grep -o '[0-9a-f]\+' )
#get the window class, to check what terminal is running
TERM=$( xprop -id $WID WM_CLASS | grep -o 'konsole\|gnome-terminal' ) #change this to match your terminal. only tested with konsole
#quit if a terminal is not active
if [[ -z "$TERM" ]] ; then
exit -1
fi
#get bash PID for the window, somehow
if [[ "$TERM" == "konsole" ]] ; then
#this seems really really roundabout, but here goes..
#for every konsole window (which may have many tabs/sessions)
for WINDOW in $( qdbus org.kde.konsole /Windows org.freedesktop.DBus.Introspectable.Introspect | grep "node name" | grep -o "[0-9]\+" ) ; do
#get the "current" session, which I guess is the active tab. seems to work
SESSION=$( qdbus org.kde.konsole /Windows/$WINDOW org.kde.konsole.Window.currentSession )
#get the window ID from the environment variables (why is not available via qdbus??)
KWID=$( qdbus org.kde.konsole /Sessions/$SESSION org.kde.konsole.Session.environment | grep WINDOWID | grep -o "[0-9]\+" )
#convert it to hex, to match the query at the top
KWID=$( printf "0x%x\n" $KWID )
#if this active tab is in the active window, it's the one we want. grab the PID of the shell
if [[ "$WID" == "$KWID" ]] ; then
SHELL_PID=$( qdbus org.kde.konsole /Sessions/$SESSION org.kde.konsole.Session.processId )
break
fi
done
else
ps --ppid $TPID #<- need to figure out which bash PID for the WID, as above for KDE
echo "only works for KDE atm. sorry"
exit -1
fi
echo WID=$WID PID=$PID TERM=$TERM SHELL_PID=$SHELL_PID
#find the foreground process
ps -O stat --ppid $SHELL_PID | grep -v PID | while read CHILD ; do
if [[ -n "$(echo $CHILD | awk '{print $2}' | grep \+)" ]] ; then
PID=$( echo $CHILD | awk '{print $1}' )
kill -SIGSTOP $PID
sleep 0.0001 #??
kill -SIGCONT $PID
break
fi
done
这很好用。例如,
>>> sleep 100 #press shortcut here
[1]+ Stopped sleep 100
>>> jobs #check it's been restarted
[1]+ Running sleep 100 &
>>>
但是它确实依赖于窗口管理器能够设置全局快捷方式并能够获取活动终端和 shell,这真是太绕了。我猜如果 ssh 正在运行,可能也会出现问题,不确定。