捕获在我的 shell 中启动 运行 进程的命令
capture the command that launched the running process in my shell
我试着让 windows 在 GNU screen 中的标题自动等于工作目录的路径 PLUS 过程 运行ning 如果有的话(例如:npm start 或 vim file.js)
为此,我在我的 .zshrc 中添加了这些行:
precmd () {
local action = action_to_define
if [[ $TERM == screen* ]]; then
printf -Pn '\ek%~ $action\e\'
fi
}
这会(以某种方式)将路径作为标题发送到屏幕(参见 this post)
和变量 action 将打印 运行ning 程序(如果存在)
我尝试了 local action= $(history | tail -1 | sed 's#[0-9 ]*##')
因为这个 select 历史上最后一个命令的提示(就像 history !!
会做如果选项 !!
被识别,这不是出于某种原因...)
和local action= $(ps -lr | tail -1 | sed 's#^.*:...##')
因为这个select运行ning进程的命令
但它不起作用,好像这个过程既没有被历史捕获也没有被ps...也许在动作启动之前precmd
运行,所以我尝试了其他功能,如 preexec
或 zshaddhistory
没有任何运气......
precmd
挂钩仅在命令完成后 运行,就在显示下一个提示之前。因此它可用于更改显示提示时的终端标题。为了在命令为 运行 时更改终端标题,您需要 preexec
挂钩,即在命令被接受后 运行(在按下 Enter,就在命令之前 运行.
当在提示符下确认命令时,此命令将以三种形式作为参数传递给preexec
- 第一个参数是键入的字符串,包括任何 new-lines(只要历史记录机制处于活动状态,它通常是活动的)
- 第二个参数是单行,size-limited(如果太长,它会被截断)带有扩展别名的命令版本。
- 第三个参数是命令的全文,实际上是运行(带有扩展别名)
所以这应该可以解决问题:
preexec () {
local action=""
if [[ $TERM == screen* ]]; then
printf -Pn '\ek%~ $action\e\'
fi
}
由于precmd
钩子只有运行,在提示下一个命令之前,可以简化为:
precmd () {
if [[ $TERM == screen* ]]; then
printf -Pn '\ek%~\e\'
fi
}
虽然这不是它不起作用的主要原因,但重要的是要注意在 Zsh(和大多数其他 Unix shell)中 [=19= 之前或之后不能有 spaces ] 为参数赋值时。
确切的行为可能会有所不同,具体取决于您放置 space 的位置以及您使用的是 local
或 set
之类的东西还是简单的赋值。
以问题中的代码为例:
在 =
前后放置 space 和 local
通常会导致 错误分配
% local action = action_to_define
zsh: bad assignment
仅在 =
之后将 spaces 与 local 一起将分配一个空字符串给变量和 create/set 另一个空变量或导致上下文错误,取决于预期值是否是可行的参数名称:
% local action= "echo"
这会清空 action
和 echo
% local action= "echo foo"
local: not valid in this context: echo foo
此处 action
也被清空,但 local
之后失败,因为 echo foo
由于包含 space.[=30= 而不是一个可行的参数名称]
我试着让 windows 在 GNU screen 中的标题自动等于工作目录的路径 PLUS 过程 运行ning 如果有的话(例如:npm start 或 vim file.js)
为此,我在我的 .zshrc 中添加了这些行:
precmd () {
local action = action_to_define
if [[ $TERM == screen* ]]; then
printf -Pn '\ek%~ $action\e\'
fi
}
这会(以某种方式)将路径作为标题发送到屏幕(参见 this post)
和变量 action 将打印 运行ning 程序(如果存在)
我尝试了 local action= $(history | tail -1 | sed 's#[0-9 ]*##')
因为这个 select 历史上最后一个命令的提示(就像 history !!
会做如果选项 !!
被识别,这不是出于某种原因...)
和local action= $(ps -lr | tail -1 | sed 's#^.*:...##')
因为这个select运行ning进程的命令
但它不起作用,好像这个过程既没有被历史捕获也没有被ps...也许在动作启动之前precmd
运行,所以我尝试了其他功能,如 preexec
或 zshaddhistory
没有任何运气......
precmd
挂钩仅在命令完成后 运行,就在显示下一个提示之前。因此它可用于更改显示提示时的终端标题。为了在命令为 运行 时更改终端标题,您需要 preexec
挂钩,即在命令被接受后 运行(在按下 Enter,就在命令之前 运行.
当在提示符下确认命令时,此命令将以三种形式作为参数传递给preexec
- 第一个参数是键入的字符串,包括任何 new-lines(只要历史记录机制处于活动状态,它通常是活动的)
- 第二个参数是单行,size-limited(如果太长,它会被截断)带有扩展别名的命令版本。
- 第三个参数是命令的全文,实际上是运行(带有扩展别名)
所以这应该可以解决问题:
preexec () {
local action=""
if [[ $TERM == screen* ]]; then
printf -Pn '\ek%~ $action\e\'
fi
}
由于precmd
钩子只有运行,在提示下一个命令之前,可以简化为:
precmd () {
if [[ $TERM == screen* ]]; then
printf -Pn '\ek%~\e\'
fi
}
虽然这不是它不起作用的主要原因,但重要的是要注意在 Zsh(和大多数其他 Unix shell)中 [=19= 之前或之后不能有 spaces ] 为参数赋值时。
确切的行为可能会有所不同,具体取决于您放置 space 的位置以及您使用的是 local
或 set
之类的东西还是简单的赋值。
以问题中的代码为例:
在
=
前后放置 space 和local
通常会导致 错误分配% local action = action_to_define zsh: bad assignment
仅在
=
之后将 spaces 与 local 一起将分配一个空字符串给变量和 create/set 另一个空变量或导致上下文错误,取决于预期值是否是可行的参数名称:% local action= "echo"
这会清空
action
和echo
% local action= "echo foo" local: not valid in this context: echo foo
此处
action
也被清空,但local
之后失败,因为echo foo
由于包含 space.[=30= 而不是一个可行的参数名称]