使用管道 ("|") 作为 bash 或 zsh 命令中的第一个符号

Use pipe ("|") as first symbol in bash or zsh command

我有两个简单的脚本:

./cpthat

BlueM/cliclick 在键盘上输入:Shift+Cmd+A,然后Cmd+C,激活iTerm 终端机:

#!/bin/zsh
cliclick kd:shift,cmd t:a ku:shift t:c ku:cmd
pbpaste>$THATF

./that

#!/bin/zsh
cat $THATF

这会打印出 cpthat 存储的最后一个命令的输出。

(我知道我可以 运行 $ command > $THATF 直接但由于其他原因我需要对命令输出进行追溯操作。另外,线程不安全。)

挑战:

我正在尝试到达可以使用管道启动 zshbash 命令的位置:

$ |grep -i sometext

实际上发生这种情况的地方:

$ that|grep -i sometext

这有可能吗?

您不需要以 | 开头。 grep 实用程序自然读取 STDIN.

这是一个人为的例子:

# /bin/sh
# count_matches
grep  | wc -l

$ cat file | count_matches thing

您可以看到您要查找的 | 在命令行本身,而不是在脚本中

同样有效:

$ count_matches thing < file

在第一个示例中,STDIN 连接(通过管道)到第一个命令的输出(通常是 cat)。在第二个中,它是通过重定向从实际文件中获取的。

所以,只需摆脱 | 就可以了。

回答我自己的问题。

显示在命令开头单独使用 | 的 GIF 动画会自动替换为上一个命令的输出:

编辑 ~/.zshrc 以覆盖 zsh 的 zle accept-line 小部件

将以下内容附加到 ~/ .zshrc


readonly THATF="path/to/your/temporary/file"

my-accept-line () {  
  if [[ "${BUFFER:0:1}" == '|' ]]; then    
    /usr/local/bin/cliclick kd:shift,cmd t:a ku:shift w:100 t:c ku:cmd
    pbpaste>"${THATF}"
    BUFFER='cat ${THATF} '${BUFFER}
  fi  
  zle .accept-line
}

zle -N accept-line my-accept-line

说明

  • 当您在输入命令后点击 enter 时,zsh 运行 accept-line 小部件。
  • 我们覆盖了那个小部件,但在退出之前我们记得用 zle .accept-line 调用原始小部件。带有点前缀的工厂小部件是 运行.
  • iTerm2中,shift+cmd+a选择上一个命令的所有输出,cmd+c将其复制到系统粘贴板。
  • 我们粘贴粘贴板的内容并将其重定向到先前声明的临时文件,由 ${THATF} 指向。
  • 我们在 zle widget 代码中可用的 zsh 特殊变量 $BUFFER 前面添加上一个命令的输出。

奖金

  • 我已经将各种 fn 键组合重新映射到我在 shell.
  • 中经常使用的表情符号和 unicode 符号
  • fn+ctrl+arrow down 输入⏬符号;当作为 shell 命令的一部分输入并调用 zle accept-line 小部件时,将替换为您捕获的最后一个命令输出的 第一行 :
BUFFER=${BUFFER//⏬/$(cat ${THAT1F})}

在我的实现中,${THAT1F) 的声明和填充如上,只是通过 sed 进行管道过滤,只抓取流中直到 \NUL 或 \n 的部分先到.

依赖关系、注意事项:

这个特定的解决方案取决于:

  • cliclick 调度 macOS 键盘事件。也许存在本地解决方案,例如ANSI/escape序列。
  • iTerm 处理用于复制最后命令输出的键绑定。
  • zsh 用于 zle 小部件可配置性。

此外,我必须提到上面的代码片段是最基本的、概念验证的、最小的。如果您要实施类似的措施,请采取措施确保安全和健全。一个开始的地方不是覆盖 accept-line 小部件,而是覆盖其他小部件与键绑定的组合,这样 1) 您可以事先查看和编辑修改后的命令,以及 2) 您必须按 enter 键接受您修改后的命令。