Gnome-Terminal

gnome-terminal - 執行具有暫停功能的命令

  • March 31, 2020

我有一個應用程序啟動器,它使用 – 選項在 gnome-terminal 中執行命令,但是每當我進入終端並嘗試 crtl-z 嘗試掛起命令並將其移動到後台時,什麼都沒有發生。我的搜尋發現了一堆關於在 bash 中啟動互動式 shell 的文章,但我在那裡嘗試過的也沒有任何效果。有沒有辦法啟動 gnome-terminal 並執行一個命令,讓我能夠暫停命令並稍後顯示提示?

bash_in_gnome_terminal(){
   local IFS
   printf -v cmd %q ". ~/.bashrc; set -m; $*"
   gnome-terminal -- bash -c "bash --rcfile <(echo $cmd)"
}

bash_in_gnome_terminal tail -f ~/.xsession-errors
bash_in_gnome_terminal 'grep -r pattern dir | less'

由於該gnome-terminal命令實際上呼叫“終端伺服器”以生成終端實例,並且您無法將文件描述符傳遞給其中執行的程序,因此該解決方案很複雜(並且被削弱了!)。

使用其他終端xtermmlterm解決方案更簡單,功能更強大:

bash_in_xterm(){
   local IFS
   xterm -e bash --rcfile <(printf '. ~/.bashrc; set -m; %s\n' "$*")
}

此外,如果 bash 可以選擇在互動式 shell(如vi +'cmd')之前執行一些命令,而無需像--rcfile <(...). 也許它甚至有 - 但我無法弄清楚;-)

之所以需要,set -m是因為 bash 在監視模式關閉^Z的情況下獲取初始化文件,即沒有作業控制和使用, fg,bg等的可能性。


如果您希望在啟動命令退出時退出 shell 並關閉終端,可以像這樣修改函式

$$ assumes a recent version of bash $$:

bash_in_gnome_terminal(){
   local IFS
   set -- 'sigchld(){ local j="\j"; ((${j@P})) || exit; }; trap sigchld CHLD;' "$@"
   printf -v cmd %q ". ~/.bashrc; set -m; $*"
   gnome-terminal -- bash -c "bash --rcfile <(echo $cmd)"
}

${var@P}表單擴展 中的任何提示轉義var,並且\j提示轉義擴展為作業數。因此,如果沒有更多作業,j="\j"; ((${j@P})) || exit從陷阱呼叫的將退出 shell。CHLD

在不支持${var@P}擴展形式的舊版本 bash 中,必須使用更笨重的 kludge:

set -- 'sigchld(){ trap - CHLD; test "$(jobs -p)" || exit; trap sigchld CHLD; }; trap sigchld CHLD;' "$@"

這裡CHLD必須禁用陷阱然後重新啟用,否則$(jobs -p)命令替換將遞歸觸發它。


這整個事情可以做成一個獨立的腳本而不是一個函式:

#! /bin/bash

# uncomment and edit the following line accordingly
# set -- <fixed command and arguments> "$@"

# this only works in bash >= 4.4
# set -- 'sigchld(){ local j="\j"; ((${j@P})) || exit; }; trap sigchld CHLD;' "$@"
set -- 'sigchld(){ trap - CHLD; test "$(jobs -p)" || exit; trap sigchld CHLD; }; trap sigchld CHLD;' "$@"

printf -v cmd %q ". ~/.bashrc; set -m; $*"
gnome-terminal -- bash -c "bash --rcfile <(echo $cmd)"

引用自:https://unix.stackexchange.com/questions/575173