Skip to content

Commit 76b226a

Browse files
committed
update
1 parent 861211a commit 76b226a

6 files changed

+152
-2
lines changed

.editorconfig

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ end_of_line = lf
88
trim_trailing_whitespace = true
99
insert_final_newline = true
1010

11-
[{build,*.js}]
11+
[*.{js,mjs}]
1212
indent_size = 4
1313
; this option just works with prettier, not implemented with editorconfig
1414
max_line_length = 100
+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# 一个复杂的小 bug: cd 补全问题
2+
3+
如果你同时在使用 [fnm](https://github.com/Schniz/fnm)[bash-completion](https://github.com/scop/bash-completion), bash-it 的 [aliases.completion.bash](https://github.com/Bash-it/bash-it/blob/master/completion/available/aliases.completion.bash) 这三个工具,你会遇到一个 BUG。
4+
5+
## BUG 描述
6+
7+
使用 cd 按 Tab 补全路径时,每个路径都会额外加上一个空格。
8+
9+
比如 `cd /<Tab>` 然后选中 /usr,补全后变成 `cd /usr <光标位置>`。但正常期望的应该是 `cd /usr<光标位置>`
10+
11+
## 复现问题
12+
13+
省略,懒得写。
14+
15+
## 排错关键
16+
17+
当同时使用 fnm, bash-completion, bash-it 的 aliases.completion.bash:
18+
19+
```sh
20+
> complete -p cd
21+
complete -F _comp_complete_minimal cd
22+
23+
> alias cd
24+
alias cd='__fnmcd'
25+
26+
> complete -p __fnmcd
27+
complete -F _comp_complete_minimal __fnmcd
28+
```
29+
30+
当同时开启 bash-completion 和 bash-it 的 aliases.completion.bash,不使用 fnm:
31+
32+
```sh
33+
> complete -p cd
34+
complete -o nospace -F _comp_cmd_cd cd
35+
36+
> alias cd
37+
-bash: alias: cd: not found
38+
39+
> complete -p __fnmcd
40+
-bash: complete: __fnmcd: no completion specification
41+
```
42+
43+
当同时开启 bash-completion 和 fnm,不使用 bash-it 的 aliases.completion.bash:
44+
45+
```sh
46+
> complete -p cd
47+
-bash: complete: cd: no completion specification
48+
49+
> alias cd
50+
alias cd='__fnmcd'
51+
52+
> complete -p __fnmcd
53+
-bash: complete: __fnmcd: no completion specification
54+
```
55+
56+
当同时开启 bash-it 的 aliases.completion.bash 和 bash-completion, fnm,不使用 bash-completion:
57+
58+
```sh
59+
> complete -p cd
60+
-bash: complete: cd: no completion specification
61+
62+
> alias cd
63+
alias cd='__fnmcd'
64+
65+
> complete -p __fnmcd
66+
-bash: complete: __fnmcd: no completion specification
67+
```
68+
69+
## 原因分析
70+
71+
根因不在 bash-completion 也不在 bash-it,而在于 fnm 的 `--use_on_cd` 参数。
72+
73+
fnm 的[初始化](https://github.com/Schniz/fnm#bash)这么写:`eval "$(fnm env --use-on-cd --shell bash)"`
74+
75+
然而在 [`fn use_on_cd`](https://github.com/Schniz/fnm/blob/1a58394b53c918fa130e22116056f7b4f8e4997c/src/shell/bash.rs) 可以看到这段。
76+
77+
```sh
78+
__fnmcd() {{
79+
\cd "$@" || return $?
80+
__fnm_use_if_file_found
81+
}}
82+
83+
alias cd=__fnmcd
84+
__fnm_use_if_file_found
85+
```
86+
87+
`_comp_complete_minimal` 是 bash-completion 源码里定义的。
88+
89+
由于 `alias cd='__fnmcd'` 的存在,aliases.completion.bash 会把 cd 的补全函数用 __fnmcd 的补全函数代替。
90+
91+
而 aliases.completion.bash 也会给 __fnmcd 添加一个 `complete -F _comp_complete_minimal __fnmcd`
92+
93+
这就导致了 `complete -F _comp_complete_minimal cd`
94+
95+
## 解决办法
96+
97+
不要用 --use-on-cd 参数。这功能只是在 cd 目录时自动查找是否存在 .node-version 或 .nvmrc 文件,自动切换 node 版本用的。
98+
99+
`eval "$(fnm env --shell bash)"`

others/curl-fail-fast.md

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# curl 快速失败
2+
3+
`curl -f` 有助于快速判断错误。如果不加 `-f` 参数,curl 执行后的 exit code 永远都是 0。这在编写 shell 脚本时可能会引发问题。
4+
5+
比如请求错误的链接地址时,
6+
7+
`curl -Lo docker.bash https://raw.githubusercontent.com/docker/cli/no-master/contrib/completion/bash/docker`
8+
9+
curl 命令执行成功。得到的 docker.bash 的文件内容是 `404: Not Found`
10+
11+
`curl -fLo docker.bash https://raw.githubusercontent.com/docker/cli/no-master/contrib/completion/bash/docker`
12+
13+
curl 命令执行失败。并且会打印 `curl: (56) The requested URL returned error: 404`,并且 exit code 会是 56。
14+
15+
加上 `-f` 参数,curl 会识别 http response header 的状态码。

others/editorconfig.md

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# editorconfig
2+
3+
## 易错的文件匹配
4+
5+
-`[/file]` 不能用 `/` 开头
6+
-`[file]` `[./file]`
7+
8+
-`[abc,*.sh]` 多文件必须要有 `{}`
9+
-`[{abc,*.sh}]` `[{*.sh,abc}]` 可以正常使用
10+
-`[{*.sh,abc/}]` `[{*.sh,abc/*}]`, `*.sh` 的匹配会失效,这应该是个 bug
11+
-`[{**/*.sh,abc/}]` `[{**/*.sh,abc/*}]`, 可以正常使用
12+
13+
- `[*.lua]``[*.{lua}]``[**/*.lua]` 都会递归匹配所有目录下的 `*.lua`
14+
- `[./*.lua]` 不会递归匹配,只匹配根目录下的 `*.lua`
15+
- `[*/*.lua]` 只匹配一层目录下 `*.lua`,不匹配二层及以下子目录的 `*.lua`
16+
17+
-`folder` `folder/` 不会对 `folder/` 目录下的文件生效
18+
-`folder/*` 只匹配一层目录下的文件,不匹配二层及以下子目录的文件
19+
-`folder/**` 递归匹配所有文件

shell/bash-tricks.md

+9
Original file line numberDiff line numberDiff line change
@@ -353,3 +353,12 @@ https://superuser.com/a/1348950/1776434
353353
## [ ][[ ]] 的区别
354354

355355
https://stackoverflow.com/a/3427931/4622308
356+
357+
## `${var+x}``${var:+x}` 的区别
358+
359+
`${var+x}``${var:+x}` 是 Bash 中的两种不同的参数扩展方式,它们的行为略有不同:
360+
361+
- **`${var+x}`** 只要 `var` 被设置(无论是否为空),都会返回 `x`
362+
- **`${var:+x}`** 只有当 `var` 被设置且不为空时,才会返回 `x`;否则返回空。
363+
364+
两者主要用于不同的场景:`${var+x}` 用于检测变量是否被设置,而 `${var:+x}` 用于检测变量是否既被设置又有值。

shell/printf-array.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
# `printf '%s\n' $@` 为何可以打印多行?
1+
# printf 打印多行
2+
3+
## `printf '%s\n' $@` 为何可以打印多行?
24

35
比如 `f() { printf '%s\n' $@; }`,当执行 `f 1 2 3` 时会分行打印 1 2 3。
46

@@ -12,3 +14,9 @@
1214

1315
- https://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html
1416
- https://stackoverflow.com/a/39690101/4622308
17+
18+
## printf -- '\n' 打印多行
19+
20+
`printf 'a\nb\nc\n'` 可以打印多行。但当字符串以 `-` 开头,比如 `printf '-a\n-b\n--c\n'`,就会报错“无效的选项”。
21+
22+
应当写 `printf -- '-a\n-b\n--c\n'`

0 commit comments

Comments
 (0)