URxvt作为shell来运行东西,或者如何通过<;退出bash;输入>;,但是执行到目前为止输入的字符串?

URxvt作为shell来运行东西,或者如何通过<;退出bash;输入>;,但是执行到目前为止输入的字符串?,bash,Bash,我要找的是一个替代品,你可以在各种平铺WM中点击Mod+R,或者在Gnome DE中点击Alt+F2,这是一个运行东西的小窗口。如果没有我的bash别名和其他东西,我会感到非常难过,因为那些shell(至少是我现在可以使用的那些shell)是非交互式的,并且它们的交互性不能在运行时设置为选项 这就是为什么我决定使用URxvt窗口作为“一个命令的shell”。在我的WM中,我绑定了Mod+R快捷方式来执行 /bin/bash -c 'export ONE_COMMAND_SHELL=t &

我要找的是一个替代品,你可以在各种平铺WM中点击Mod+R,或者在Gnome DE中点击Alt+F2,这是一个运行东西的小窗口。如果没有我的bash别名和其他东西,我会感到非常难过,因为那些shell(至少是我现在可以使用的那些shell)是非交互式的,并且它们的交互性不能在运行时设置为选项

这就是为什么我决定使用URxvt窗口作为“一个命令的shell”。在我的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中

[ -v OC_SHELL ] && {
    export PS1=
    eaoc() { echo $OC_SHELL && [ $(( OC_SHELL++ )) -ge 1 ] && wait $! && exit; }
    trap eaoc DEBUG
}
通过这种方式,我可以区分一个URxvt实例,它将成为“一个命令的shell”,并将C-m组合(是的,它也适用于Enter)设置为退出shell,从而退出URxvt。问题是如何执行在退出之前输入的字符串

我发现了两条潜在的线索:

a) 使用BASH_命令

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"'
将导致
exec
exec
exec

b) 西格尔德身上有陷阱

如果你愿意,它可能对你有用

[ -v ONE_COMMAND_SHELL ] && {
    PS1=
    eaoc() { exit; }
    trap eaoc SIGCHLD
}
在~/.bashrc的末尾。PS1可能是非空的,但它可能没有子shell调用,或者陷阱将执行,shell将在生成提示之前退出。这将保持URxvt打开,直到分叉过程退出,因此可能被认为是解决方案的一半

c) 调试的陷阱

调试陷阱在任何要执行的简单命令之前和每个函数中的第一个命令之前执行。如果我们通过OC_SHELL提供一个数字,并计算执行命令的数量,如

/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 &
和它的父母一起死去。如何处理

有趣的是,调试陷阱在输入命令后立即执行,在使用
&
的情况下,此陷阱不会等待进程返回其状态代码或后台进程的pid

好的,这就是为什么需要以某种方式将输入的字符串包装到
(nohup…&)

这对我很有用:

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"'
这对我很有用:

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"'

我甚至没有尝试过eval,因为它是邪恶的,并且有反斜杠的潜在警告,但是因为我现在找不到任何bug,就让它去吧。PROMPT_命令非常棒,但是respond C-m一次又一次地附加“&”,所以不可能输入该命令。它对我来说就是这样(如果我用
\C-m
替换
\n
,它确实开始循环)。奇怪的是,你使用的是什么版本的bash,shopt-p说了什么?4.2.37(1)-release;
shopt-p
对于注释来说太长了,所以我甚至没有尝试eval,因为它是邪恶的,并且有反斜杠的潜在警告,但是因为我现在找不到任何bug,就随它去吧。PROMPT_命令非常棒,但是respond C-m一次又一次地附加了“&”,所以不可能输入该命令。它对我来说就是这样(如果我用
\C-m
替换
\n
,它确实开始循环)。奇怪的是,你使用的是什么版本的bash,以及
shopt-p
说的是什么?4.2.37(1)-发布;
shopt-p
对于注释来说太长了,所以它是