
- オプションを使用してgnome-terminal内でコマンドを実行するアプリケーションランチャーがありますが、端末に移動してcrtl-zを使用してコマンドを中断してバックグラウンドに移動しようとするたびに何も起こりません。私の検索では、bashでインタラクティブシェルを起動する方法に関する多くの記事が表示されましたが、そこで試したことは何も機能しませんでした。 gnome-terminalを起動し、コマンドを一時停止し、後でプロンプトを表示するコマンドを実行する方法はありますか?
答え1
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
コマンドが実際に端末インスタンスを生成するために「ターミナルサーバー」を呼び出し、ここで実行されているプロセスにファイル記述子を渡すことができないため、ソリューションは複雑で深刻です。
xterm
あるいは、他の端末の場合、解決策mlterm
はより簡単で実用的です。
bash_in_xterm(){
local IFS
xterm -e bash --rcfile <(printf '. ~/.bashrc; set -m; %s\n' "$*")
}
vi +'cmd'
また、bashがこのようなものを一緒にまとめる必要なく、インタラクティブシェルの前にいくつかのコマンドを実行するオプションがあれば良いでしょう--rcfile <(...)
。たぶんそうかもしれません。しかし、理解することはできません;-)
これはset -m
、bashが以下を使用して初期化ファイルをインポートするために必要です。モニターモードがオフ^Z
つまり、ジョブ制御がなく、などを使用する可能性がありませんfg
。bg
開始されたコマンドが終了したときにシェルを終了して端末を閉じるには、次のように機能を変更できます(最新バージョンの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
。CHLD
拡張形式をサポートしていない以前のバージョンのbashでは、${var@P}
より面倒な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)"