tag:github.com,2008:/just-talks/shell/discussions Recent discussions in just-talks/shell 2024-09-13T12:27:19+00:00 tag:github.com,2008:7177845 这个 bash 的坑有一劳永逸的解决方法? 2024-09-13T12:27:18+00:00 2024-09-13T12:27:19+00:00 adoyle-h https://github.com/adoyle-h <h2 dir="auto">set -o errexit -o pipefail 对于条件判断以及输入重定向无效</h2> <p dir="auto">举个例子</p> <div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#!/usr/bin/env bash set -o errexit -o nounset -o pipefail -o errtrace (shopt -p inherit_errexit &amp;&gt;/dev/null) &amp;&amp; shopt -s inherit_errexit fail() { return 1 } foo() { # 这里输出重定向到 &amp;2 是为了在 Case 5 可以看到结果 echo 1 &gt;&amp;2 fail echo 2 &gt;&amp;2 } # echo &quot;Case 1:&quot; # foo # echo &quot;Case 2:&quot; # foo || true # echo &quot;Case 3:&quot; # while read -r var; do # foo || true # done &lt; &lt;(printf -- 'a\nb\n') # echo &quot;Case 4:&quot; # if foo; then # echo 3 # fi # echo &quot;Case 5:&quot; # if [[ $(foo) == 'abc' ]]; then # echo 3 # fi"><pre class="notranslate"><span class="pl-c"><span class="pl-c">#!</span>/usr/bin/env bash</span> <span class="pl-c1">set</span> -o errexit -o nounset -o pipefail -o errtrace (shopt -p inherit_errexit <span class="pl-k">&amp;</span><span class="pl-k">&gt;</span>/dev/null) <span class="pl-k">&amp;&amp;</span> <span class="pl-c1">shopt</span> -s inherit_errexit <span class="pl-en">fail</span>() { <span class="pl-k">return</span> 1 } <span class="pl-en">foo</span>() { <span class="pl-c"><span class="pl-c">#</span> 这里输出重定向到 &amp;2 是为了在 Case 5 可以看到结果</span> <span class="pl-c1">echo</span> 1 <span class="pl-k">&gt;&amp;2</span> fail <span class="pl-c1">echo</span> 2 <span class="pl-k">&gt;&amp;2</span> } <span class="pl-c"><span class="pl-c">#</span> echo "Case 1:"</span> <span class="pl-c"><span class="pl-c">#</span> foo</span> <span class="pl-c"><span class="pl-c">#</span> echo "Case 2:"</span> <span class="pl-c"><span class="pl-c">#</span> foo || true</span> <span class="pl-c"><span class="pl-c">#</span> echo "Case 3:"</span> <span class="pl-c"><span class="pl-c">#</span> while read -r var; do</span> <span class="pl-c"><span class="pl-c">#</span> foo || true</span> <span class="pl-c"><span class="pl-c">#</span> done &lt; &lt;(printf -- 'a\nb\n')</span> <span class="pl-c"><span class="pl-c">#</span> echo "Case 4:"</span> <span class="pl-c"><span class="pl-c">#</span> if foo; then</span> <span class="pl-c"><span class="pl-c">#</span> echo 3</span> <span class="pl-c"><span class="pl-c">#</span> fi</span> <span class="pl-c"><span class="pl-c">#</span> echo "Case 5:"</span> <span class="pl-c"><span class="pl-c">#</span> if [[ $(foo) == 'abc' ]]; then</span> <span class="pl-c"><span class="pl-c">#</span> echo 3</span> <span class="pl-c"><span class="pl-c">#</span> fi</span></pre></div> <p dir="auto">取消对应的注释,查看输出。</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Case 1: 1"><pre class="notranslate"><code class="notranslate">Case 1: 1 </code></pre></div> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Case 2: 1 2"><pre class="notranslate"><code class="notranslate">Case 2: 1 2 </code></pre></div> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Case 3: 1 2 1 2"><pre class="notranslate"><code class="notranslate">Case 3: 1 2 1 2 </code></pre></div> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Case 4: 1 2 3"><pre class="notranslate"><code class="notranslate">Case 4: 1 2 3 </code></pre></div> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Case 5: 1 2"><pre class="notranslate"><code class="notranslate">Case 5: 1 2 </code></pre></div> <p dir="auto">在 Case 2、3、4 中,fail 报错了,但程序依然运行下去。<br> 即使使用 <code class="notranslate">trap</code> 也无法捕获 ERR。</p> <p dir="auto">这个 BUG (Feature?) 可能会导致严重的问题。在 <a href="https://mywiki.wooledge.org/BashPitfalls#errexit" rel="nofollow">https://mywiki.wooledge.org/BashPitfalls#errexit</a> 有提到一个例子:</p> <div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# WRONG cleanup() { cd &quot;$1&quot; rm -f ./* } cleanup /no/longer/there || { printf &gt;&amp;2 'Cleanup failed\n' exit 1 }"><pre class="notranslate"><span class="pl-c"><span class="pl-c">#</span> WRONG</span> <span class="pl-en">cleanup</span>() { <span class="pl-c1">cd</span> <span class="pl-s"><span class="pl-pds">"</span><span class="pl-smi">$1</span><span class="pl-pds">"</span></span> rm -f ./<span class="pl-k">*</span> } cleanup /no/longer/there <span class="pl-k">||</span> { <span class="pl-c1">printf</span> <span class="pl-k">&gt;&amp;2</span> <span class="pl-s"><span class="pl-pds">'</span>Cleanup failed\n<span class="pl-pds">'</span></span> <span class="pl-c1">exit</span> 1 }</pre></div> <p dir="auto">当 cd 要切换的目录不存在会报错,但是由于上层调用用了 <code class="notranslate">||</code> 导致 <code class="notranslate">rm -f ./*</code> 会继续执行。<br> 正确的处理方式是这么写:</p> <div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Right cleanup() { cd &quot;$1&quot; || return rm -f ./* }"><pre class="notranslate"><span class="pl-c"><span class="pl-c">#</span> Right</span> <span class="pl-en">cleanup</span>() { <span class="pl-c1">cd</span> <span class="pl-s"><span class="pl-pds">"</span><span class="pl-smi">$1</span><span class="pl-pds">"</span></span> <span class="pl-k">||</span> <span class="pl-k">return</span> rm -f ./<span class="pl-k">*</span> }</pre></div> <p dir="auto">但是这只能解决这一种情况。当 <code class="notranslate">func-a || func-b</code> 这种格式下,func-a 内所有执行的函数都有可能报错,那要给每个执行都加上 <code class="notranslate">|| return</code> 吗?这显然不合理。</p> <p dir="auto"><code class="notranslate">func-a || func-b</code> 这种格式其实会经常用到,<code class="notranslate">func-b</code> 是一个容错处理函数。但是 bash 的语法机制又会导致这种错误。</p> <p dir="auto">想问问有无一劳永逸的解决方法?</p> tag:github.com,2008:7128756 MacOS 自带了 realpath 命令 2024-09-02T15:19:16+00:00 2024-09-02T15:19:17+00:00 adoyle-h https://github.com/adoyle-h <p dir="auto">以前写 shell 脚本总是难受于 MacOS 没有 realpath。想写个通用的脚本很麻烦。今天发现自 MacOS 13 起(2022 年 10 月发布的),就自带了 realpath。<br> <a href="https://apple.stackexchange.com/a/450116" rel="nofollow">https://apple.stackexchange.com/a/450116</a><br> 可能是个过时的冷知识。</p> tag:github.com,2008:4917984 解释命令:explainshell 2023-03-02T11:42:40+00:00 2023-03-10T08:15:30+00:00 adoyle-h https://github.com/adoyle-h <p dir="auto"><a href="https://explainshell.com/" rel="nofollow">https://explainshell.com/</a></p> tag:github.com,2008:4917679 非常酷的开源项目和团队:charm 2023-03-02T10:06:21+00:00 2023-03-03T03:37:49+00:00 adoyle-h https://github.com/adoyle-h <p dir="auto"><a href="https://charm.sh/" rel="nofollow">https://charm.sh/</a></p> <p dir="auto">他们用 golang 做了很多交互体验非常棒的终端工具与库。</p> tag:github.com,2008:4917814 tmux 技巧交流 2023-03-02T10:45:50+00:00 2023-03-02T10:51:02+00:00 adoyle-h https://github.com/adoyle-h <p dir="auto">大家分享一下 tmux 方面的小技巧。</p> tag:github.com,2008:4917810 一图说明移动光标的快捷键 2023-03-02T10:44:35+00:00 2023-03-02T10:44:36+00:00 adoyle-h https://github.com/adoyle-h <p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/1998490/222406380-53ca4179-7aa7-4548-a6a5-64a9da19fcda.png"><img src="https://user-images.githubusercontent.com/1998490/222406380-53ca4179-7aa7-4548-a6a5-64a9da19fcda.png" alt="image" style="max-width: 100%;"></a></p> <p dir="auto">此图出处找不到了。</p> tag:github.com,2008:4917648 声明式编写 Bash 补全脚本:bash-completor 2023-03-02T09:57:09+00:00 2023-03-02T10:40:29+00:00 adoyle-h https://github.com/adoyle-h <p dir="auto"><a href="https://github.com/adoyle-h/bash-completor">https://github.com/adoyle-h/bash-completor</a></p> <p dir="auto">编写简单的 Bash 补全脚本仅需一行。可对于拥有许多复杂参数的命令来说,这就不够用了。开发者需要编写<a href="https://www.gnu.org/software/bash/manual/html_node/A-Programmable-Completion-Example.html" rel="nofollow">可编程补全</a>脚本。</p> <p dir="auto">可是,编写复杂的可编程补全脚本却是一件困难的事。Bash 脚本的语法十分自由(容易出错),教程也五花八门,你可能需要踩很多坑。 即使有 <a href="https://github.com/scop/bash-completion">scop/bash-completion</a> 这样现成的补全脚本库,可是它只收录常用命令。对于某些社区不常用的命令,还是得自己手写补全脚本。</p> <p dir="auto">bash-completor 是一个用 bash 脚本编写的 Bash 补全脚本生成器。无须安装额外的依赖。帮助 bash 新手快速地实现 bash 补全。 它用声明式写法来实现逻辑。学习门槛非常低。</p> <p dir="auto">可能有人会想,bash 就一胶水语言,不应该用来写这么复杂的功能。为何不用 js 、go 、rust 等高级编程语言来实现补全逻辑? 当然可以,只不过这会引入开发环境配置,依赖部署等问题。 需要使用 bash 补全功能的人一定安装了 bash 。所以用 Bash 脚本来写,不引入其他依赖。用户安装使用就很简单。</p> tag:github.com,2008:4917772 预览各种 shell 配色:theme.sh 2023-03-02T10:31:42+00:00 2023-03-02T10:31:42+00:00 adoyle-h https://github.com/adoyle-h <p dir="auto"><a href="https://github.com/lemnos/theme.sh">https://github.com/lemnos/theme.sh</a></p> <p dir="auto"><a target="_blank" rel="noopener noreferrer" href="https://github.com/lemnos/theme.sh/raw/master/demo.gif"><img src="https://github.com/lemnos/theme.sh/raw/master/demo.gif" alt=".gif" data-animated-image="" style="max-width: 100%;"></a></p> tag:github.com,2008:4917767 将命令托管到后台队列里执行:pueue 2023-03-02T10:30:11+00:00 2023-03-02T10:30:11+00:00 adoyle-h https://github.com/adoyle-h <p dir="auto"><a href="https://github.com/Nukesor/pueue">https://github.com/Nukesor/pueue</a></p> <p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/Nukesor/images/main/pueue-v2.0.0.gif"><img src="https://raw.githubusercontent.com/Nukesor/images/main/pueue-v2.0.0.gif" alt=".gif" data-animated-image="" style="max-width: 100%;"></a></p> tag:github.com,2008:4917761 如何写好命令行程序 2023-03-02T10:28:22+00:00 2023-03-02T10:28:22+00:00 adoyle-h https://github.com/adoyle-h <ul dir="auto"> <li>Command Line Interface Guidelines: <a href="https://clig.dev/" rel="nofollow">https://clig.dev/</a> <ul dir="auto"> <li><a href="https://github.com/cli-guidelines/cli-guidelines">文档源码</a></li> </ul> </li> <li><a href="http://docopt.org/" rel="nofollow">docopt</a>: Command-line interface description language</li> </ul> tag:github.com,2008:4917739 现代化终端程序 2023-03-02T10:23:33+00:00 2023-03-02T10:23:34+00:00 adoyle-h https://github.com/adoyle-h <ul dir="auto"> <li><a href="https://github.com/Eugeny/tabby">https://github.com/Eugeny/tabby</a> 跨平台</li> <li><a href="https://github.com/alacritty/alacritty">https://github.com/alacritty/alacritty</a> 跨平台</li> <li><a href="https://github.com/Maximus5/ConEmu">https://github.com/Maximus5/ConEmu</a> 仅限 Windows 平台</li> </ul> tag:github.com,2008:4917732 增删改查 JSON, TOML, YAML, XML, CSV 的命令:dasel 2023-03-02T10:20:53+00:00 2023-03-02T10:20:54+00:00 adoyle-h https://github.com/adoyle-h <p dir="auto"><a href="https://github.com/TomWright/dasel">https://github.com/TomWright/dasel</a></p> <p dir="auto">支持解析 JSON, TOML, YAML, XML, CSV。格式转换很方便。<br> 支持增删改查字段的操作,可以替代 <a href="https://github.com/stedolan/jq">jq</a> 和 <a href="https://github.com/kislyuk/yq">yq</a> 这类工具。</p> tag:github.com,2008:4917724 对比 BSD sed 和 GNU sed 的差异 2023-03-02T10:17:20+00:00 2023-03-02T10:17:21+00:00 adoyle-h https://github.com/adoyle-h <p dir="auto"><a href="https://riptutorial.com/sed/topic/9436/bsd-macos-sed-vs--gnu-sed-vs--the-posix-sed-specification" rel="nofollow">https://riptutorial.com/sed/topic/9436/bsd-macos-sed-vs--gnu-sed-vs--the-posix-sed-specification</a></p> <p dir="auto">MacOS 默认的 sed 是 BSD 版本的,就有很多参数跟 GNU sed 不一样。</p> tag:github.com,2008:4917717 让 bash 也能拥有 fish、zsh 的语法高亮和自动补全 2023-03-02T10:15:34+00:00 2023-03-02T10:15:35+00:00 adoyle-h https://github.com/adoyle-h <p dir="auto"><a href="https://github.com/akinomyoga/ble.sh">https://github.com/akinomyoga/ble.sh</a></p> <p dir="auto">体验还不错</p> tag:github.com,2008:4917708 超酷的现代化 prompt 工具:starship 2023-03-02T10:14:21+00:00 2023-03-02T10:14:22+00:00 adoyle-h https://github.com/adoyle-h <p dir="auto"><a href="https://github.com/starship/starship">https://github.com/starship/starship</a></p> <p dir="auto">跨平台,跨 shell,开源,插件化。<br> 你可以用来定制你的 shell prompt。</p> <p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/starship/starship/master/media/demo.gif"><img src="https://raw.githubusercontent.com/starship/starship/master/media/demo.gif" alt="" data-animated-image="" style="max-width: 100%;"></a></p> tag:github.com,2008:4917671 非常酷的 shell:nushell 2023-03-02T10:04:28+00:00 2023-03-02T10:04:29+00:00 adoyle-h https://github.com/adoyle-h <p dir="auto"><a href="https://www.nushell.sh/" rel="nofollow">https://www.nushell.sh/</a></p> <p dir="auto">用 Rust 写的,跨平台的,开源的 shell。内置了许多用户友好的基础命令。管道加上类似 SQL 的语法,操作数据很方便。</p> <p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/1998490/222396737-26d635a4-dfcb-48cc-9595-e4192dad2081.png"><img src="https://user-images.githubusercontent.com/1998490/222396737-26d635a4-dfcb-48cc-9595-e4192dad2081.png" alt="image" style="max-width: 100%;"></a></p> tag:github.com,2008:4917664 跨平台跨终端跨 Shell 的补全工具:Fig 2023-03-02T10:01:31+00:00 2023-03-02T10:01:32+00:00 adoyle-h https://github.com/adoyle-h <p dir="auto"><a href="https://github.com/withfig/autocomplete">https://github.com/withfig/autocomplete</a></p> <p dir="auto">Fig 非常强大,跨平台,跨终端,跨 Shell,支持插件。是先进的 shell 工具。<br> 它在系统常驻一个 fig 进程,在 shell 补全时与 fig 进程进行交互。</p> <p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/74884a83c88c19b27b1a451b7e618fe773c6a48f6cb209a02d3fe70381a4f9d9/68747470733a2f2f6669672e696f2f676966732f64656d6f2d776974682d6865616465722e676966"><img src="https://camo.githubusercontent.com/74884a83c88c19b27b1a451b7e618fe773c6a48f6cb209a02d3fe70381a4f9d9/68747470733a2f2f6669672e696f2f676966732f64656d6f2d776974682d6865616465722e676966" alt=".gif" style="max-width: 100%;"></a></p> tag:github.com,2008:4917634 现代化 unix 命令 2023-03-02T09:53:11+00:00 2023-03-02T09:53:12+00:00 adoyle-h https://github.com/adoyle-h <p dir="auto"><a href="https://github.com/ibraheemdev/modern-unix">https://github.com/ibraheemdev/modern-unix</a></p> <p dir="auto">另外我再补充几个</p> <ul dir="auto"> <li>better cd:<a href="https://github.com/skywind3000/z.lua">https://github.com/skywind3000/z.lua</a></li> <li>better tail:<a href="https://github.com/halturin/multitail">https://github.com/halturin/multitail</a></li> </ul>