我的命令行卫生很差。当我狂热地梦想一个有用的管道存在时,我很少将它提交给某个地方的 shell 配置。相反,我让fzf
稍后在我需要的时候疏通它。我的函数没有记录,名称和变量非常短,因为我倾向于编写高尔夫代码,并且特定于当时的用例而不是通用的。
从那以后,我决定这是最佳方法。
不!我真的相信这一点。我有理由。
在我们的专业中,命令或 shell 历史的概念是一个被严重低估的机制。
考虑这样一个事实——如果你保留所有历史记录并以终端命令的形式表达你的所有操作任务——你可能在几秒钟内就拥有了你工作的全部历史记录(除了编码工件)。如何使用openssl
创建 x509 证书?在主机群中检查Spectre的最简单方法是什么?如果您可以从可能回答问题的命令中回忆起一些子字符串,那么历史搜索可以将丢失的记忆带到您的指尖,以便立即重新使用。
想象一下其他职业如何重视这种即时、无限保留、零努力记录的回忆,这种回忆转化为立即可用的行动。提交特定类型法律文件的律师?老师给一组测试打分?你可能会想得更多,但我的观点是,在白领软件工程工作的交叉点上,shell 历史的概念具有巨大的潜力。
这是一个取自我自己工作的实际示例。您的用例可能会有所不同,但我有时遇到的一种情况是为我因内核更新等原因而关闭的主机解封 Vault 实例。反馈循环看起来像这样:
啊,我得解封这个 Vault 实例。我的开封钥匙又在哪里?
哦,是的,它在Bitwarden。我可以用rbw抓住它:
rbw get 'Vault Unseal Key'
废话。什么实例需要解封?
我想我可以问领事:
http :8500/v1/health/state/critical
哦。我可以将这些节点作为可以与其他东西一起使用的端点列表吗?
http :8500/v1/health/state/critical \ | jq -r '.[].ServiceID' \ | awk -F: '{ print "http://" $2 ":" $3; }'
注意:这是一个子示例,因为我不知道该管道。我从httpie命令开始,然后敲击jq
命令,然后迭代地进行awk
过滤,在添加的管道之间运行命令,看看我在两者之间得到了什么。
好的。我有我的启封密钥和需要启封的端点。我可以用zsh
循环将它们粘合在一起:
http :8500/v1/health/state/critical \ | jq -r '.[].ServiceID' \ | awk -F: '{ print "http://" $2 ":" $3; }' \ | while read -rh do VAULT_HOST=$h vault operator unseal $(rbw get 'Vault Unseal Key') done
这里的最后一个命令是粗鲁的,有点迟钝。不难看出如何将其清理干净并将其放入经过精心编码的 shell 函数或脚本中:我的 Vault 解封密钥的变量、提取密封主机列表的函数等等。
但我经常做这种短脚本。并且“我编写的小管道的数量⨉
将它们转换为好的 shell 脚本并放入正确的文件并提交到我的 dotfiles 存储库所需的时间”这个数字真的很重要。所以我只是跳过它!
我曾经为此评判自己。然而,在多年的过程中,我因为没有在某个脚本中记录我的许多管道而不是在我的 shell 历史中记录我的许多管道而自责的次数非常少,甚至不存在。
我确实有一个很大的遗憾:当我没有把它们带到我的工作站时。但是你知道有专门设计的工具可以帮助你随身携带你的 shell 历史吗?这已经不是什么大问题了!
那么,当你在你的 shell 历史中包含大型且有时复杂的操作,经常这样做,并让你的.shell_history
成长为一个美丽而可怕的花园时会发生什么?
您可以完成很多工作,并且 a) 记录这些快捷方式和 b) 使用它们的开销基本上是无摩擦的。借助fzf
等功能触手可及的功能,您在命令行工作中的整个职业生涯的整个历史都可以立即获得。你不会局限于你认为值得克服任何障碍来为后代记录它的东西。一切都在那里,您不必考虑记录任何内容。
举个例子:我已经很长时间没有直接使用低级 S3 指标了。但我确实记得过去需要通过 S3 存储桶聚合总流量。通过键入Ctrl-r aws s3 statistics <RET>
,我可以在大约两秒钟内找到为您回答该问题的命令:
today="$(date +%s)" for bucket in $(aws s3 ls | awk '{ print $NF; }') do echo -n "$bucket " aws cloudwatch get-metric-statistics \ --namespace AWS/S3 \ --start-time "$(echo $today - 86400 | bc)" --end-time "$today" \ --period 86400 \ --statistics Average \ --region us-east-1 \ --metric-name BucketSizeBytes \ --dimensions Name=BucketName,Value=$bucket Name=StorageType,Value=StandardStorage \ | jq '.Datapoints[].Average' \ | gnumfmt --to=si done
几年后,这可能无法 100% 用于类似任务,但粉碎Ctrl-x Ctrl-e
,快速编辑,然后继续。不太难,你可以看到为什么将它提交给像 shell 函数这样非常正式的东西是不值得的开销。当时很具体,现在需要调整,在这种情况下使用它非常适合“从我的历史中获取并调整它”。¹
尝试这个:
Ctrl-r
更好)¹我会承认,在团队情况下,像这样的例子会有点崩溃。虽然我可以在一秒钟内完成我们的 S3 流量,但您如何将这些知识和能力传播给其他人?文档和脚本的大型存储库可以解决这个问题,但我在这篇文章中的目的是让人们明白,低摩擦成本和低门槛成本是让历史大放异彩的原因。也许有一个很好的方法可以让团队共享协同工作。
² 这里还有一篇关于“命令行优先工作”的帖子,但我只想强调我认为将尽可能多的工作整合到命令行形式中会有很大的好处。以 shell 历史记录的形式轻松调用的操作是与互操作性、可重复性等许多其他好处一样的好处之一。
也在这里发布。