1

私が探しているのは、さまざまなタイリング WM で Mod+R を押すか、Gnome DE で Alt+F2 を押すことによっておそらく見たことのあるすべてのものの代替です。そこから物事を実行するための小さなウィンドウです。これらのシェル (少なくとも現在使用できるもの) は非対話的であり、実行時に対話性をオプションとして設定できないため、bash エイリアスやその他のものが失われることなく非常に悲しいです。

これが、URxvt ウィンドウを「1 つのコマンドのシェル」として使用することにした理由です。私のWMでは、Mod + Rショートカットを実行するようにバインドしています

/bin/bash -c 'export ONE_COMMAND_SHELL=t && urxvt -name one_command_shell' 

そして、置きます

[ -v ONE_COMMAND_SHELL ] && bind -x '"\C-m":"exit"'

私の ~/.bashrc で

このようにして、「1 つのコマンドのシェル」になる URxvt インスタンスを区別し、Cm の組み合わせ (はい、Enter キーでも機能します) を設定して、シェル、つまり URxvt を終了することができます。問題は、終了する前にこれまでに入力された文字列を実行する方法ですか?

私は2つの潜在的な手がかりを見つけました:

a) BASH_COMMAND の利用

BASH_COMMAND
     The command currently being executed or about to be executed,  unless  the
     shell  is executing a command as the result of a trap, in which case it is
     the command executing at the time of the trap.

しかし、私はそれを機能させませんでした

[ -v ONE_COMMAND_SHELL ] && bind -x '"\C-m":"exec $BASH_COMMAND exit"'

execexecが発生しexecます。

b) SIGCHLD のトラップ!

あなたが配置すれば、それはあなたのために働くかもしれません

[ -v ONE_COMMAND_SHELL ] && {
    PS1=
    eaoc() { exit; }
    trap eaoc SIGCHLD
}

~/.bashrcの最後に。PS1 は空ではないかもしれませんが、サブシェル呼び出しがないかもしれません。さもなければ、トラップが実行され、プロンプトが生成される前にシェルが終了します。これにより、フォークされたプロセスが終了するまで URxvt が開いたままになるため、解決策の途中と見なされる場合があります。

c) DEBUG へのトラップ。

DEBUG トラップは、実行される単純なコマンドの前、および各関数の最初のコマンドの前に実行されますOC_SHELL を介して数値を指定し、実行されたコマンドの数をカウントするとします。たとえば…</p>

/bin/bash -c 'export OC_SHELL=0 && urxvt -name one_command_shell' 
# note a zero ----------------^

そして ~/.bashrc の最後に

[ -v OC_SHELL ] && {
    export PS1=
    eaoc() { echo $OC_SHELL && [ $(( OC_SHELL++ )) -ge 1 ] && wait $! && exit; }
    trap eaoc DEBUG
}

再び失敗します。私たちのプロセスは、

$ gimp &

親と一緒に死ぬ。それに対処する方法は?

興味深いことに、コマンドが入力された直後にDEBUG トラップが実行されます。このトラップは、プロセスがステータス コードまたはバックグラウンド プロセスの pid を返すのを待ちません&

わかりました、それがbashとは無関係にプロセスを作成する方法です入力された文字列を何らかの方法でラップする必要があります(nohup … &)

4

1 に答える 1

1

これは私にとってはうまくいきます:

one_command_execute() {
    eval $(echo "$READLINE_LINE") &
    exit
}

[ -v ONE_COMMAND_SHELL ] && bind -x '"\C-m":"one_command_execute"'

別のバージョンはありませんeval:

one_command_checkexit() {
    [ -v ONE_COMMAND_DONE ] && exit
    ONE_COMMAND_DONE=1
}

[ -v ONE_COMMAND_SHELL ] && PROMPT_COMMAND=one_command_checkexit

これは、コマンドが終了するまでウィンドウを閉じません。すべてをバックグラウンドで自動的に実行するには、次を追加します。

[ -v ONE_COMMAND_SHELL ] && bind '"\C-m":" & \n"'
于 2013-03-23T19:19:39.203 に答える