iTerm2 进阶使用技巧(博客分享) - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
iyaozhen
V2EX    分享创造

iTerm2 进阶使用技巧(博客分享)

  •  3
     
  •   iyaozhen
    iyaozhen 2021-03-23 16:01:33 +08:00 6424 次点击
    这是一个创建于 1694 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近公司正版整顿,不让使用 SecureCRT 了(主要是 Windows 转过来了),乘机推广一波 iTerm2,但基本只有些入门教程,稍微深入点的没有,所以自己总结了下

    全文: https://iyaozhen.com/iterm2-tips.html 可能阅读体验更好

    摘录:

    iTerm2 的优点这里不做赘述了,第一次使用的话可以先看看官网的介绍:features 、Highlights for New Users 。本文主要是结合实际使用场景,介绍一些进阶使用技巧(基本的 Oh My Zsh 、rzsz 等配置就不重复说明了)。

    跳板机自动登录

    现在很多公司登录服务器都需要先登录到一个跳板机然后再登录到目标机器,每次输入密码(一般还是动态的)很麻烦。一般的教程推荐使用 expext 解决这个问题,这里介绍一个更简单、直接的办法。

    首先,要先解决登录到跳板机的连接复用问题,这个输入 ssh 本身的范畴,一般教程都是说在 ~/.ssh/config 增加下面的配置:

    host * ControlMaster auto ControlPath ~/.ssh/master-%r@%h:%p 

    但这样有个问题,iTerm2 第一次登录的 tab 关闭后,就失效了,再登录就又要密码了。其实再增加一个配置即可。

    ControlPersist yes ServerAliveInterval 60 

    之前的设置只是实现了连接复用,但 tab 关闭 ssh 进程结束后,连接也被销毁了,ControlPersist 项的意思是进程结束后连接还保持,再有相同的( ControlPath 配置)连接,还能继续使用此连接。

    再者,每次输入 ssh xxx 很麻烦(而且跳板机登录后还得输入 ssh xxx ),当然你可以配置 alias+expext 但也不是太方便,特别是 Windows 转过来的。对此,iTerm2 本身也提供了很强大的 Profiles 功能,能一键登录目标机器(还可以设置快捷键)。

    有些自己的常用机器,还可以复制一下这份基础的 relay 配置。

    再加一行( Send text at start 处)。

    还可以把机器打个标签,然后页面上就能分组,方便选择。

    还有一个,有时候会发现,有些机器一会儿没操作就会被断开 ssh,一方面可以设置 ServerAliveInterval,但作用不大,因为实际连接服务器的是 relay 跳板机。iTerm2 其实没有可以显式设置这个功能的地方,有些同学可能找到个这个配置:

    可能错误使用的比较多,iTerm2 还特意提示了,开启这个功能不能 session 保持。那到底有没有办法呢,还是有的。其实这个特性是为了安全,是 TMOUT 环境变量控制的,export 设置一个比较大的值(比如 12h,保证第二天来了不断就行)。这个可以设置在自己常用机器的环境变量里,或者定义一个 Snippet 方便使用(后面还有介绍)。

    到此基本上解决了如何便捷登录机器的问题。但之前用 SecureCRT 的同学可能有个地方不太习惯,iTerm2 的 Duplicate Tab 只能复制当前的 profile,比如我先快捷键打开 relay profile,然后输入 ssh 到一台机器,此时复制的 tab,只到 relay 跳板机,还得翻一下之前的 ssh 命令。

    不过直接打开的就是之前配置的 test02 这种 profile,复制 tab 的时候就能直接到当前机器登录状态。但一般管理的机器非常多,不可能都配置到 profile,还是有点不方便。不过这个也能解决,下面 script 自定义脚本章节有介绍。

    Scripts

    iTerm2 还有个非常强大的功能,就是支持自定义脚本,而且新版的脚本可以用 Python 写,只要想象力够丰富,可以实现很多功能。动手前可以先多看几遍官网的文档说明:Scripting Fundamentals 。

    先介绍一些基本概念,上下文按层级划分:app 、window 、tab 、session,如下图所示:

    我们做一些操作的时候需要明白操作的上下文对象,那么一个对象具体可以做什么呢,需要看具体文档: https://iterm2.com/python-api/。可以按照官方示例做一遍,官网也有很多例子可以参考。

    下面我们尝试用 script 来实现增强版的 Duplicate Tab 的功能,能复制当前已登录的服务器。模拟我们手工操作的过程,可以把步骤分为 3 部分:

    1. 获取当前 user/hostname

    一开始我看到 tab 的名称都能显示当前 host,但查了一番资料未果。中间查阅文档发现 iTerm2 内置了很多变量,其中有 hostname,但试了下只能获取到 Mac 电脑的 hostname 。后来又想我在服务器上执行 hostname 命令,然后怎么把这个结果传递给 iTerm2 。

    一通翻文档,发现了 iTerm2 有个特殊的 Escape Codes 功能,简单来说就输出包含一些特殊字符的时候,屏幕上不会显示,但 iTerm2 会捕获这种逃逸字符,然后实现一些特殊功能。比如强大的 Shell Integration 就是基于此实现(还有很多其它强悍的功能,但需要安装脚本,生产环境不能使用)。

    参考官方文档,setting-user-defined-variables 章节,设置 hostname 和 uname 变量:

    set_hostname_cmd = r'printf "\033]1337;SetUserVar=%s=%s\007" hostname `echo -n $(hostname) | base64`' set_uname_cmd = r'printf "\033]1337;SetUserVar=%s=%s\007" uname `echo -n $USER | base64`' 

    这里可以看到我们字符串里面有特殊字符,而且我们希望他们不转义,而是原样输出,可以在字符串前面增加 r 表示 raw 原始字符串。

    同时我们需要把这个请求发送到当前 session,结合前面上下文的介绍和文档,我们可以这样获取当前 session 并发送命令:

    app = await iterm2.async_get_app(connection) current_tab = app.current_terminal_window.current_tab session = current_tab.current_session set_hostname_cmd = r'printf "\033]1337;SetUserVar=%s=%s\007" hostname `echo -n $(hostname) | base64`' await session.async_send_text(set_hostname_cmd + "\n") set_uname_cmd = r'printf "\033]1337;SetUserVar=%s=%s\007" uname `echo -n $USER | base64`' await session.async_send_text(set_uname_cmd + "\n") hostname = await session.async_get_variable("user.hostname") uname = await session.async_get_variable("user.uname") shell_cmd = "ssh %s@%s\n" % (uname, hostname) 
    1. 新建一个窗口

    用 Python API 可以新建窗口,但这里使用一个更直接的方式,直接点击 Duplicate Tab 菜单:

    await iterm2.MainMenu.async_select_menu_item(connection, "Duplicate Tab") 
    1. 登录记录的服务器

    一开始直接使用 await session.async_send_text(shell_cmd),但发现输出到了原来的 tab/session,看来需要获取到新创建的 tab 。本来想 Window.tabs,获取到最后一个 tab,应该就是刚新建的。

    后来翻了下文档,发现还有一个更高级的实现,使用 FocusMonitor 监听 tab 的变化,获取到新增 tab_id 后再发送命令。

    async with iterm2.FocusMonitor(connection) as monitor: while True: update = await monitor.async_get_next_update() if update.selected_tab_changed: tab_id = update.selected_tab_changed.tab_id print("The active tab is now %s" % tab_id) break current_tab = app.get_tab_by_id(tab_id) session = current_tab.current_session await session.async_send_text(shell_cmd) 

    最后附上完整代码:

    #!/usr/bin/env python3 import iterm2 # This script was created with the "basic" environment which does not support adding dependencies # with pip. async def main(connection): app = await iterm2.async_get_app(connection) current_tab = app.current_terminal_window.current_tab session = current_tab.current_session # 设置 hostname/user 自定义变量 set_hostname_cmd = r'printf "\033]1337;SetUserVar=%s=%s\007" hostname `echo -n $(hostname) | base64`' await session.async_send_text(set_hostname_cmd + "\n") set_uname_cmd = r'printf "\033]1337;SetUserVar=%s=%s\007" uname `echo -n $USER | base64`' await session.async_send_text(set_uname_cmd + "\n") # 获取变量(有点小问题,立即获取可能没有) hostname = await session.async_get_variable("user.hostname") uname = await session.async_get_variable("user.uname") shell_cmd = "ssh %s@%s\n" % (uname, hostname) # 新建窗口 await iterm2.MainMenu.async_select_menu_item(connection, "Duplicate Tab") # 获取到新增的 tab async with iterm2.FocusMonitor(connection) as monitor: while True: update = await monitor.async_get_next_update() if update.selected_tab_changed: tab_id = update.selected_tab_changed.tab_id print("The active tab is now %s" % tab_id) break # 登录 shell current_tab = app.get_tab_by_id(tab_id) session = current_tab.current_session await session.async_send_text(shell_cmd) iterm2.run_until_complete(main) 

    然后还可以把这个脚本加到 action (下文有介绍)里面,更加方便使用。当然这个脚本还有很多可以完善的地方,比如我发现设置自定义变量毕竟是通过捕获输出来设置到当前上下文的,立即获取太快了,很可能获取不到。不过从此例子可以看出,Scripts 没有做不到,只有想不到。

    Toolbelt

    习 SecureCRT 的同学,经常用的一个功能可能就是,自定义一些命令按钮,用起来很是方便。iTerm2 也有类似的功能,叫做 Toolbelt,可以在右边显示很多功能区,默认的可能比较宽,可以自己调整大小后,点击 Toolbelt -> Set Default Width,保存当前的宽度。还能在 profile 里面配置默认打开 Toolbelt 。

    Toolbelt 里面功能很多,可以都打开看看,这里介绍两个个人常用的 ---more---

    全文: https://iyaozhen.com/iterm2-tips.html

    大家还有什么能高级使用技巧吗?

    25 条回复    2021-03-30 09:50:34 +08:00
    asanelder
        1
    asanelder  
       2021-03-23 17:02:03 +08:00
    zbcs! 收藏了
    AEDaydreamer
        2
    AEDaydreamer  
       2021-03-23 17:05:21 +08:00 via Android
    为什么我 iterm ssh Linux 很容易卡输入,Windows terminal 就很少遇到
    iyaozhen
        3
    iyaozhen  
    OP
       2021-03-23 17:08:06 +08:00
    @asanelder 感谢支持
    iyaozhen
        4
    iyaozhen  
    OP
       2021-03-23 17:09:01 +08:00
    @AEDaydreamer 是不是网络环境不一样,可以再开个窗口 ping 着。
    或者看看目标机器 CPU 等资源,看看是不是服务器本身卡
    l6241425
        5
    l6241425  
       2021-03-23 17:22:45 +08:00
    iterm2 可以试试 alacritty
    ssh 保持和窗口管理 可以试试 tmux
    iyaozhen
        6
    iyaozhen  
    OP
       2021-03-23 17:29:13 +08:00
    @l6241425 第一次听说 alacritty,试用下

    tmux 也是一个很好的路子
    jiezhi
        7
    jiezhi  
       2021-03-23 17:33:56 +08:00
    写了个 iTerm 自动换背景图片的工具
    FurN1
        8
    FurN1  
       2021-03-23 19:33:48 +08:00
    好评!学习了

    @l6241425 Alacritty 以快著称,不过我更喜欢在 Linux 上用。iTerm2 虽然慢(比 Terminal.app 明显慢),不过算是 macOS 特色软件,功能丰富
    ming7435
        9
    ming7435  
       2021-03-23 19:39:26 +08:00
    我用 MobaXterm
    Tink
        10
    Tink  
    PRO
       2021-03-23 19:40:43 +08:00 via Android
    干货满满
    AEDaydreamer
        11
    AEDaydreamer  
       2021-03-23 21:14:43 +08:00 via Android
    @iyaozhen 好的学习了
    iyaozhen
        12
    iyaozhen  
    OP
       2021-03-23 21:25:09 +08:00 via Android
    @Tink 感谢支持
    HeyVincent
        13
    HeyVincent  
       2021-03-23 21:37:17 +08:00
    赞一个
    lovestudykid
        14
    lovestudykid  
       2021-03-23 23:40:42 +08:00
    iTerm 有些自带的脚本,比如 ssh 后 pbcopy 到本地,发送文件到本地等,比较有用。不过现在主要用 alacritty 了
    silymore
        15
    silymore  
       2021-03-24 00:15:17 +08:00 via iPhone
    问个 iterm 配置问题,之前手贱改过一次滚轮相关的配置,结果改不回去了,现在的状况是默认进去 shell 往上滚是白屏,但进 vim 往上滚就可以正常滚,谁知道怎么两个都能滚吗
    Harry1993
        16
    Harry1993  
       2021-03-24 00:39:00 +08:00
    不知道我有有理解正,第一的跳板可以用 ssh host1 -j host2 。的,在.ssh/config 也可以置 ProxyJump 。
    iyaozhen
        17
    iyaozhen  
    OP
       2021-03-24 01:19:17 +08:00
    @silymore 文章中也有提,这种情况可以在配置选项中找下 mouse 相关的(页面右上角有个只显示非默认值的选项),实在不行只能重装了。
    iyaozhen
        18
    iyaozhen  
    OP
       2021-03-24 01:20:15 +08:00
    @Harry1993 嗯嗯 实际解决跳板机的方案有很多。我这个可以不极客,但是适合普通操作 GUI 的同学
    testerzhang
        19
    testerzhang  
       2021-03-24 08:34:07 +08:00
    改天尝试下,谢谢 share
    iyaozhen
        20
    iyaozhen  
    OP
       2021-03-24 09:58:42 +08:00 via Android
    @testerzhang 感谢支持
    liaoberlin
        21
    liaoberlin  
       2021-03-26 11:25:56 +08:00
    大佬大佬 这都能看见你
    iyaozhen
        22
    iyaozhen  
    OP
       2021-03-26 15:27:33 +08:00
    @liaoberlin 一会儿群里领 水军工资
    endoffight
        23
    endoffight  
       2021-03-26 17:29:03 +08:00
    我补充一个
    ![]( https://i.loli.net/2021/03/26/ImjzP1hKfnXNHB7.png)
    trigger 染色
    iyaozhen
        24
    iyaozhen  
    OP
       2021-03-26 19:38:05 +08:00
    @endoffight 这个很不错呀 看日志

    trigger 也是一块强大的功能 后面我也补充下
    kingfalse
        25
    kingfalse  
       2021-03-30 09:50:34 +08:00 via Android
    一键安装漂亮且功能强大的 iterm2

    https://github.com/KingFalse/ohmyiterm2
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5166 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 38ms UTC 09:04 PVG 17:04 LAX 01:04 JFK 04:04
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86