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 &>/dev/null) && shopt -s inherit_errexit
fail() {
return 1
}
foo() {
# 这里输出重定向到 &2 是为了在 Case 5 可以看到结果
echo 1 >&2
fail
echo 2 >&2
}
# echo "Case 1:"
# foo
# echo "Case 2:"
# foo || true
# echo "Case 3:"
# while read -r var; do
# foo || true
# done < <(printf -- 'a\nb\n')
# echo "Case 4:"
# if foo; then
# echo 3
# fi
# echo "Case 5:"
# 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">&</span><span class="pl-k">></span>/dev/null) <span class="pl-k">&&</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> 这里输出重定向到 &2 是为了在 Case 5 可以看到结果</span>
<span class="pl-c1">echo</span> 1 <span class="pl-k">>&2</span>
fail
<span class="pl-c1">echo</span> 2 <span class="pl-k">>&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 < <(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 "$1"
rm -f ./*
}
cleanup /no/longer/there || {
printf >&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">>&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 "$1" || 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>