从标准输入流中读取并执行shell指定函数

巧妙的ohmytmux配置

oh my tmux的配置,发现他们很巧妙的将配置和shell函数放到一个文件里

比如切换鼠标模式的相关配置和shell函数,

# : << EOF # ...省略其他配置文件信息 # toggle mouse bind m run "cut -c3- ~/.tmux.conf | sh -s _toggle_mouse" # EOF # # _toggle_mouse() { #   old=$(tmux show -gv mouse) #   new="" # #   if [ "$old" = "on" ]; then #     new="off" #   else #     new="on" #   fi # #   tmux set -g mouse $new # } # # "$@"

 主要功能时 将m键绑定上   cut -c3- ~/.tmux.conf | sh -s _toggle_mouse 

cut命令切换注释

第一个巧妙的地方时   cut -c3- ~/.tmux.conf ,此命令运行的结果是

: << EOF ...省略其他配置文件信息 toggle mouse nd m run "cut -c3- ~/.tmux.conf | sh -s _toggle_mouse" EOF  _toggle_mouse() {   old=$(tmux show -gv mouse)   new=""    if [ "$old" = "on" ]; then     new="off"   else     new="on"   fi    tmux set -g mouse $new }  "$@"

一个完美的脚本就出现了!将每一行的前两个字符去掉,

  1. 使用  '<<EOF'  和  'EOF'  完美的将原来的配置放到多行注释里,
  2. 将原来使用 '# '  注释掉的shell函数 打开

 sh执行命令

从sh的文档中可以看到 -s 使用执行标准输入里执行命令

OPTIONS        -s        Read commands from the standard input. STDIN        The standard input shall be used only if one of the following is true:          *  The -s option is specified.          *  The -c option is not specified and no operands are specified.          *  The script executes one or more commands that require input from standard input (such as a read command that does not redirect its input).         See the INPUT FILES section.         When the shell is using standard input and it invokes a command that also uses standard input, the shell shall ensure that  the  standard  input  file  pointer        points  directly  after  the command it has read when the command begins execution. It shall not read ahead in such a manner that any characters intended to be        read by the invoked command are consumed by the shell (whether interpreted by the shell or not) or that characters that are not read by the invoked command are        not  seen  by the shell. When the command expecting to read standard input is started asynchronously by an interactive shell, it is unspecified whether charac‐        ters are read by the command or interpreted by the shell.         If the standard input to sh is a FIFO or terminal device and is set to non-blocking reads, then sh shall enable blocking reads on standard  input.  This  shall        remain in effect when the command completes.

 执行指定函数

从sh的man文档里没有看出来可以指定执行脚本里的哪个函数呢,ohmytmux怎么让sh知道执行哪个函数的呢?

注意到cut后的脚本没,最后一行是  "$@" 

在shell中$@用来获得脚本的所有入参,所以   cut -c3- ~/.tmux.conf | sh -s _toggle_mouse 执行的真正脚本时

: << EOF ...省略其他配置文件信息 toggle mouse nd m run "cut -c3- ~/.tmux.conf | sh -s _toggle_mouse" EOF  _toggle_mouse() {   old=$(tmux show -gv mouse)   new=""    if [ "$old" = "on" ]; then     new="off"   else     new="on"   fi    tmux set -g mouse $new }  _toggle_mouse

这样是不是很明了了,

脚本第一行的  ':' 是shell中的空命令占位符,它什么也不干,永远返回0

<<EOF   到  EOF定义了一个多行文本,这个多行文本没有人用, 相当于把原来的配置都注释掉了

接着 定义一个名字为_toggle_mouse的函数

最后一行  执行该行数

这就是另一个巧妙的地方, 将要执行的函数名当做参数传给shell,并通过$@将 指定的函数 放到最后一样

通过这种方式我们就可以方便的执行shell中指定的函数了

参考

oh my tmux github : https://github.com/gpakosz/.tmux

发表评论

相关文章