使用管道 ("|") 作为 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
- Shift+Cmd+A 选择 上一个命令的输出,并且
- Cmd+C 复制 "that"到剪贴板。
pbpaste
然后 将 写入系统范围定义的文件 $THATF。
./that
#!/bin/zsh
cat $THATF
这会打印出 cpthat
存储的最后一个命令的输出。
(我知道我可以 运行 $ command > $THATF
直接但由于其他原因我需要对命令输出进行追溯操作。另外,线程不安全。)
挑战:
我正在尝试到达可以使用管道启动 zsh
或 bash
命令的位置:
$ |grep -i sometext
实际上发生这种情况的地方:
$ that|grep -i sometext
这有可能吗?
- 覆盖管道运算符?
- zsh 配置魔术?
- 我大量使用 zsh,但我愿意接受任何解决方案。
您不需要以 |
开头。 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 的部分先到.
依赖关系、注意事项:
这个特定的解决方案取决于:
此外,我必须提到上面的代码片段是最基本的、概念验证的、最小的。如果您要实施类似的措施,请采取措施确保安全和健全。一个开始的地方不是覆盖 accept-line
小部件,而是覆盖其他小部件与键绑定的组合,这样 1) 您可以事先查看和编辑修改后的命令,以及 2) 您必须按 enter 键接受您修改后的命令。
我有两个简单的脚本:
./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
- Shift+Cmd+A 选择 上一个命令的输出,并且
- Cmd+C 复制 "that"到剪贴板。
pbpaste
然后 将 写入系统范围定义的文件 $THATF。
./that
#!/bin/zsh
cat $THATF
这会打印出 cpthat
存储的最后一个命令的输出。
(我知道我可以 运行 $ command > $THATF
直接但由于其他原因我需要对命令输出进行追溯操作。另外,线程不安全。)
挑战:
我正在尝试到达可以使用管道启动 zsh
或 bash
命令的位置:
$ |grep -i sometext
实际上发生这种情况的地方:
$ that|grep -i sometext
这有可能吗?
- 覆盖管道运算符?
- zsh 配置魔术?
- 我大量使用 zsh,但我愿意接受任何解决方案。
您不需要以 |
开头。 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 的部分先到.
依赖关系、注意事项:
这个特定的解决方案取决于:
此外,我必须提到上面的代码片段是最基本的、概念验证的、最小的。如果您要实施类似的措施,请采取措施确保安全和健全。一个开始的地方不是覆盖 accept-line
小部件,而是覆盖其他小部件与键绑定的组合,这样 1) 您可以事先查看和编辑修改后的命令,以及 2) 您必须按 enter 键接受您修改后的命令。