some little tweaks, modify Twikoo.astro to support auto reload when first loading; add new post add_twikoo_for_fuwari.md

This commit is contained in:
2026-03-07 20:07:01 +08:00
parent 2704ee5a4a
commit 085312af35
17 changed files with 2084 additions and 1426 deletions

View File

@ -34,7 +34,7 @@ export default defineConfig({
nesting: true,
}),
swup({
theme: false,
theme: true,
animationClass: "transition-swup-", // see https://swup.js.org/options/#animationselector
// the default value `transition-` cause transition delay
// when the Tailwind class `transition-all` is used

View File

@ -17,28 +17,28 @@
},
"dependencies": {
"@astrojs/check": "^0.9.6",
"@astrojs/rss": "^4.0.14",
"@astrojs/sitemap": "^3.6.0",
"@astrojs/svelte": "7.2.3",
"@astrojs/rss": "^4.0.15",
"@astrojs/sitemap": "^3.7.0",
"@astrojs/svelte": "7.2.5",
"@astrojs/tailwind": "^6.0.2",
"@expressive-code/core": "^0.41.4",
"@expressive-code/plugin-collapsible-sections": "^0.41.4",
"@expressive-code/plugin-line-numbers": "^0.41.4",
"@expressive-code/core": "^0.41.7",
"@expressive-code/plugin-collapsible-sections": "^0.41.7",
"@expressive-code/plugin-line-numbers": "^0.41.7",
"@fontsource-variable/jetbrains-mono": "^5.2.8",
"@fontsource/roboto": "^5.2.9",
"@fontsource/roboto": "^5.2.10",
"@iconify-json/fa6-brands": "^1.2.6",
"@iconify-json/fa6-regular": "^1.2.4",
"@iconify-json/fa6-solid": "^1.2.4",
"@iconify-json/material-symbols": "^1.2.50",
"@iconify-json/material-symbols": "^1.2.60",
"@iconify/svelte": "^4.2.0",
"@swup/astro": "^1.7.0",
"@swup/astro": "^1.8.0",
"@tailwindcss/typography": "^0.5.19",
"astro": "5.13.10",
"astro-expressive-code": "^0.41.4",
"astro-expressive-code": "^0.41.7",
"astro-icon": "^1.1.5",
"hastscript": "^9.0.1",
"katex": "^0.16.27",
"markdown-it": "^14.1.0",
"katex": "^0.16.35",
"markdown-it": "^14.1.1",
"mdast-util-to-string": "^4.0.0",
"overlayscrollbars": "^2.12.0",
"pagefind": "^1.4.0",
@ -53,10 +53,10 @@
"remark-github-admonitions-to-directives": "^1.0.5",
"remark-math": "^6.0.0",
"remark-sectionize": "^2.1.0",
"sanitize-html": "^2.17.0",
"sanitize-html": "^2.17.1",
"sharp": "^0.34.5",
"stylus": "^0.64.0",
"svelte": "^5.39.8",
"svelte": "^5.53.7",
"tailwindcss": "^3.4.19",
"typescript": "^5.9.3",
"unist-util-visit": "^5.0.0"
@ -68,7 +68,7 @@
"@types/hast": "^3.0.4",
"@types/markdown-it": "^14.1.2",
"@types/mdast": "^4.0.4",
"@types/sanitize-html": "^2.16.0",
"@types/sanitize-html": "^2.16.1",
"postcss-import": "^16.1.1",
"postcss-nesting": "^13.0.2"
},

2724
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -51,7 +51,7 @@ let links: NavBarLink[] = navBarConfig.links.map(
<Icon name="material-symbols:palette-outline" class="text-[1.25rem]"></Icon>
</button>
)}
{/* @ts-expect-error client:only 是 Astro 指令,非组件 Prop */}
<LightDarkSwitch client:only="svelte"></LightDarkSwitch>
<button aria-label="Menu" name="Nav Menu" class="btn-plain scale-animation rounded-lg w-11 h-11 active:scale-90 md:!hidden" id="nav-menu-switch">
<Icon name="material-symbols:menu-rounded" class="text-[1.25rem]"></Icon>

View File

@ -7,19 +7,87 @@ const shouldRender = enable && envId;
---
{shouldRender && (
<div id="twikoo-comment"></div>
<div id="twikoo-comment" class="card-base p-6 mb-4 text-black/75 dark:text-white/75 transition">
<p>加载评论中...</p>
</div>
<script is:inline src="https://s4.zstatic.net/npm/twikoo@1.7.1/dist/twikoo.min.js"></script>
<script is:inline define:vars={{ envId, lang }}>
(function() {
const MAX_RETRIES = 3;
const RETRY_DELAY = 2000;
<script define:vars={{ envId, lang }}>
document.addEventListener('DOMContentLoaded', () => {
if (typeof twikoo !== 'undefined') {
twikoo.init({
envId,
el: '#twikoo-comment',
lang,
}).catch(console.error);
let scriptRetryCount = 0;
let initRetryCount = 0;
// 尝试初始化 Twikoo
function initTwikoo() {
if (typeof twikoo === 'undefined') {
// Twikoo 对象不存在,说明脚本还没加载成功,重试加载脚本
if (scriptRetryCount < MAX_RETRIES) {
scriptRetryCount++;
console.log(`Twikoo 库未加载,尝试重新加载脚本 (${scriptRetryCount}/${MAX_RETRIES})……`);
setTimeout(loadScript, RETRY_DELAY);
} else {
console.error('Twikoo 库加载失败,已达到最大重试次数。');
showError('评论加载失败,请刷新页面重试。');
}
return;
}
twikoo.init({ envId, el: '#twikoo-comment', lang })
.then(() => {
console.log('Twikoo 初始化成功');
})
.catch(err => {
console.error('Twikoo 初始化失败:', err);
if (initRetryCount < MAX_RETRIES) {
initRetryCount++;
console.log(`尝试重新初始化 (${initRetryCount}/${MAX_RETRIES})……`);
setTimeout(initTwikoo, RETRY_DELAY);
} else {
showError('评论加载失败,请刷新页面重试。');
}
});
}
});
function loadScript() {
const script = document.createElement('script');
// 推荐在中国使用
// https://registry.npmmirror.com/twikoo/1.7.1/files/dist/twikoo.min.js
// https://s4.zstatic.net/npm/twikoo@1.7.1/dist/twikoo.min.js
// 推荐在全球使用
// https://cdn.jsdelivr.net/npm/twikoo@1.7.1/dist/twikoo.min.js
// 备用选项
// https://s4.zstatic.net/ajax/libs/twikoo/1.6.41/twikoo.min.js
// https://lib.baomitu.com/twikoo/1.6.39/twikoo.min.js
script.src = 'https://s4.zstatic.net/npm/twikoo@1.7.1/dist/twikoo.min.js';
script.onload = () => {
console.log('Twikoo 脚本加载成功');
scriptRetryCount = 0;
initTwikoo();
};
script.onerror = () => {
console.error('Twikoo 脚本加载失败');
if (scriptRetryCount < MAX_RETRIES) {
scriptRetryCount++;
console.log(`尝试重新加载脚本 (${scriptRetryCount}/${MAX_RETRIES})……`);
setTimeout(loadScript, RETRY_DELAY);
} else {
showError('评论加载失败,请刷新页面重试。');
}
};
document.head.appendChild(script);
}
// 显示错误信息到评论区
function showError(msg) {
const container = document.querySelector('#twikoo-comment');
if (container) container.innerHTML = `<p style="color: red;">${msg}</p>`;
}
loadScript();
})();
</script>
)}

View File

@ -0,0 +1,311 @@
---
title: Expressive Code Example
published: 2024-04-10
description: How code blocks look in Markdown using Expressive Code.
tags: [Markdown, Blogging, Demo]
category: Examples
draft: false
---
Here, we'll explore how code blocks look using [Expressive Code](https://expressive-code.com/). The provided examples are based on the official documentation, which you can refer to for further details.
## Expressive Code
### Syntax Highlighting
[Syntax Highlighting](https://expressive-code.com/key-features/syntax-highlighting/)
#### Regular syntax highlighting
```js
console.log('This code is syntax highlighted!')
```
#### Rendering ANSI escape sequences
```ansi
ANSI colors:
- Regular: Red Green Yellow Blue Magenta Cyan
- Bold: Red Green Yellow Blue Magenta Cyan
- Dimmed: Red Green Yellow Blue Magenta Cyan
256 colors (showing colors 160-177):
160 161 162 163 164 165
166 167 168 169 170 171
172 173 174 175 176 177
Full RGB colors:
ForestGreen - RGB(34, 139, 34)
Text formatting: Bold Dimmed Italic Underline
```
### Editor & Terminal Frames
[Editor & Terminal Frames](https://expressive-code.com/key-features/frames/)
#### Code editor frames
```js title="my-test-file.js"
console.log('Title attribute example')
```
---
```html
<!-- src/content/index.html -->
<div>File name comment example</div>
```
#### Terminal frames
```bash
echo "This terminal frame has no title"
```
---
```powershell title="PowerShell terminal example"
Write-Output "This one has a title!"
```
#### Overriding frame types
```sh frame="none"
echo "Look ma, no frame!"
```
---
```ps frame="code" title="PowerShell Profile.ps1"
# Without overriding, this would be a terminal frame
function Watch-Tail { Get-Content -Tail 20 -Wait $args }
New-Alias tail Watch-Tail
```
### Text & Line Markers
[Text & Line Markers](https://expressive-code.com/key-features/text-markers/)
#### Marking full lines & line ranges
```js {1, 4, 7-8}
// Line 1 - targeted by line number
// Line 2
// Line 3
// Line 4 - targeted by line number
// Line 5
// Line 6
// Line 7 - targeted by range "7-8"
// Line 8 - targeted by range "7-8"
```
#### Selecting line marker types (mark, ins, del)
```js title="line-markers.js" del={2} ins={3-4} {6}
function demo() {
console.log('this line is marked as deleted')
// This line and the next one are marked as inserted
console.log('this is the second inserted line')
return 'this line uses the neutral default marker type'
}
```
#### Adding labels to line markers
```jsx {"1":5} del={"2":7-8} ins={"3":10-12}
// labeled-line-markers.jsx
<button
role="button"
{...props}
value={value}
className={buttonClassName}
disabled={disabled}
active={active}
>
{children &&
!active &&
(typeof children === 'string' ? <span>{children}</span> : children)}
</button>
```
#### Adding long labels on their own lines
```jsx {"1. Provide the value prop here:":5-6} del={"2. Remove the disabled and active states:":8-10} ins={"3. Add this to render the children inside the button:":12-15}
// labeled-line-markers.jsx
<button
role="button"
{...props}
value={value}
className={buttonClassName}
disabled={disabled}
active={active}
>
{children &&
!active &&
(typeof children === 'string' ? <span>{children}</span> : children)}
</button>
```
#### Using diff-like syntax
```diff
+this line will be marked as inserted
-this line will be marked as deleted
this is a regular line
```
---
```diff
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
+this is an actual diff file
-all contents will remain unmodified
no whitespace will be removed either
```
#### Combining syntax highlighting with diff-like syntax
```diff lang="js"
function thisIsJavaScript() {
// This entire block gets highlighted as JavaScript,
// and we can still add diff markers to it!
- console.log('Old code to be removed')
+ console.log('New and shiny code!')
}
```
#### Marking individual text inside lines
```js "given text"
function demo() {
// Mark any given text inside lines
return 'Multiple matches of the given text are supported';
}
```
#### Regular expressions
```ts /ye[sp]/
console.log('The words yes and yep will be marked.')
```
#### Escaping forward slashes
```sh /\/ho.*\//
echo "Test" > /home/test.txt
```
#### Selecting inline marker types (mark, ins, del)
```js "return true;" ins="inserted" del="deleted"
function demo() {
console.log('These are inserted and deleted marker types');
// The return statement uses the default marker type
return true;
}
```
### Word Wrap
[Word Wrap](https://expressive-code.com/key-features/word-wrap/)
#### Configuring word wrap per block
```js wrap
// Example with wrap
function getLongString() {
return 'This is a very long string that will most probably not fit into the available space unless the container is extremely wide'
}
```
---
```js wrap=false
// Example with wrap=false
function getLongString() {
return 'This is a very long string that will most probably not fit into the available space unless the container is extremely wide'
}
```
#### Configuring indentation of wrapped lines
```js wrap preserveIndent
// Example with preserveIndent (enabled by default)
function getLongString() {
return 'This is a very long string that will most probably not fit into the available space unless the container is extremely wide'
}
```
---
```js wrap preserveIndent=false
// Example with preserveIndent=false
function getLongString() {
return 'This is a very long string that will most probably not fit into the available space unless the container is extremely wide'
}
```
## Collapsible Sections
[Collapsible Sections](https://expressive-code.com/plugins/collapsible-sections/)
```js collapse={1-5, 12-14, 21-24}
// All this boilerplate setup code will be collapsed
import { someBoilerplateEngine } from '@example/some-boilerplate'
import { evenMoreBoilerplate } from '@example/even-more-boilerplate'
const engine = someBoilerplateEngine(evenMoreBoilerplate())
// This part of the code will be visible by default
engine.doSomething(1, 2, 3, calcFn)
function calcFn() {
// You can have multiple collapsed sections
const a = 1
const b = 2
const c = a + b
// This will remain visible
console.log(`Calculation result: ${a} + ${b} = ${c}`)
return c
}
// All this code until the end of the block will be collapsed again
engine.closeConnection()
engine.freeMemory()
engine.shutdown({ reason: 'End of example boilerplate code' })
```
## Line Numbers
[Line Numbers](https://expressive-code.com/plugins/line-numbers/)
### Displaying line numbers per block
```js showLineNumbers
// This code block will show line numbers
console.log('Greetings from line 2!')
console.log('I am on line 3')
```
---
```js showLineNumbers=false
// Line numbers are disabled for this block
console.log('Hello?')
console.log('Sorry, do you know what line I am on?')
```
### Changing the starting line number
```js showLineNumbers startLineNumber=5
console.log('Greetings from line 5!')
console.log('I am on line 6')
```

View File

@ -0,0 +1,206 @@
---
title: 为 Fuwari 添加Twikoo评论组件
published: 2026-03-07
description: ''
image: ''
tags: [fuwari, twikoo]
category: '教程'
draft: false
lang: ''
---
## Twikoo 一个简洁、安全、免费的静态网站评论系统。
## 部署Twikoo
我部署[Twikoo](https://twikoo.js.org/)用的方案是 mongodb altas 云数据库后端 (具有免费的数据存储空间大约512MB左右对于评论系统已经很足够了) + [vercel](https://vercel.com/) 云函数部署.
也就是这个Twikoo的[文档](https://twikoo.js.org/backend.html#vercel-%E9%83%A8%E7%BD%B2).
### MongoDB Atlas 数据库创建
Twikoo提供的 [注册MongoDB Atlas教程](https://twikoo.js.org/mongodb-atlas.html)
最后记得要保管好 我们的`连接字符串`.
### Vercel 部署
Twikoo提供的 [Vercel 部署教程](https://twikoo.js.org/backend.html#vercel-%E9%83%A8%E7%BD%B2)
vercel 部署,由于域名的原因,中国境内无法直接访问 vercel分配的域名需要自己手动添加一个自己的自定义域名才能访问。
## 前端部署
首先打开项目的 `src/components`位置新建一个Twikoo.astro组件
并填入一下内容
```astro title="src/components/Twikoo.astro"
---
// src/components/Twikoo.astro
import { twikooConfig } from "../config";
const { enable, envId, lang = "zh_CN" } = twikooConfig;
const shouldRender = enable && envId;
---
{shouldRender && (
<div id="twikoo-comment">
<p>加载评论中...</p>
</div>
<script is:inline define:vars={{ envId, lang }}>
(function() {
const MAX_RETRIES = 3;
const RETRY_DELAY = 2000;
let scriptRetryCount = 0;
let initRetryCount = 0;
// 尝试初始化 Twikoo
function initTwikoo() {
if (typeof twikoo === 'undefined') {
// Twikoo 对象不存在,说明脚本还没加载成功,重试加载脚本
if (scriptRetryCount < MAX_RETRIES) {
scriptRetryCount++;
console.log(`Twikoo 库未加载,尝试重新加载脚本 (${scriptRetryCount}/${MAX_RETRIES})...`);
setTimeout(loadScript, RETRY_DELAY);
} else {
console.error('Twikoo 库加载失败,已达到最大重试次数。');
showError('评论加载失败,请刷新页面重试。');
}
return;
}
twikoo.init({ envId, el: '#twikoo-comment', lang })
.then(() => {
console.log('Twikoo 初始化成功');
})
.catch(err => {
console.error('Twikoo 初始化失败:', err);
if (initRetryCount < MAX_RETRIES) {
initRetryCount++;
console.log(`尝试重新初始化 (${initRetryCount}/${MAX_RETRIES})……`);
setTimeout(initTwikoo, RETRY_DELAY);
} else {
showError('评论加载失败,请刷新页面重试。');
}
});
}
function loadScript() {
const script = document.createElement('script');
// 推荐在中国使用
// https://registry.npmmirror.com/twikoo/1.7.1/files/dist/twikoo.min.js
// https://s4.zstatic.net/npm/twikoo@1.7.1/dist/twikoo.min.js
// 推荐在全球使用
// https://cdn.jsdelivr.net/npm/twikoo@1.7.1/dist/twikoo.min.js
// 备用选项
// https://s4.zstatic.net/ajax/libs/twikoo/1.6.41/twikoo.min.js
// https://lib.baomitu.com/twikoo/1.6.39/twikoo.min.js
script.src = 'https://s4.zstatic.net/npm/twikoo@1.7.1/dist/twikoo.min.js';
script.onload = () => {
console.log('Twikoo 脚本加载成功');
scriptRetryCount = 0;
initTwikoo();
};
script.onerror = () => {
console.error('Twikoo 脚本加载失败');
if (scriptRetryCount < MAX_RETRIES) {
scriptRetryCount++;
console.log(`尝试重新加载脚本 (${scriptRetryCount}/${MAX_RETRIES})……`);
setTimeout(loadScript, RETRY_DELAY);
} else {
showError('评论加载失败,请刷新页面重试。');
}
};
document.head.appendChild(script);
}
// 显示错误信息到评论区
function showError(msg) {
const container = document.querySelector('#twikoo-comment');
if (container) container.innerHTML = `<p style="color: red;">${msg}</p>`;
}
loadScript();
})();
</script>
)}
```
在`src/pages/posts/[...slug].astro`文件中的大概 113行左右结束就是文章整个模块的渲染区域
我们在他之后添加一下内容
```diff title="src/pages/posts/[...slug].astro" lang="astro" startLineNumber=103
...
<Markdown class="mb-6 markdown-content onload-animation">
<Content />
</Markdown>
{licenseConfig.enable && <License title={entry.data.title} slug={entry.slug} pubDate={entry.data.published} class="mb-6 rounded-xl license-container onload-animation"></License>}
</div>
</div>
+ <div class="flex w-full rounded-[var(--radius-large)] overflow-hidden relative mb-4">
+ <div id="post-container" class="card-base p-6 mb-4 text-black/75 dark:text-white/75 transition" class:list={["card-base z-10 px-6 md:px-9 pt-6 pb-4 relative w-full ", {} ]}>
+ <Twikoo />
+ </div>
+ </div>
<div class="flex flex-col md:flex-row justify-between mb-4 gap-4 overflow-hidden w-full">
<a href={entry.data.nextSlug ? getPostUrlBySlug(entry.data.nextSlug) : "#"}
...
```
Twikoo 在初始化时候需要调用init函数如下
```html
<!-- from https://twikoo.js.org/frontend.html#%E9%80%9A%E8%BF%87-cdn-%E5%BC%95%E5%85%A5 -->
<script>
twikoo.init({
envId: '您的环境id', // 腾讯云环境填 envIdVercel 环境填地址https://xxx.vercel.app
el: '#tcomment', // 容器元素
// region: 'ap-guangzhou', // 环境地域,默认为 ap-shanghai腾讯云环境填 ap-shanghai 或 ap-guangzhouVercel 环境不填
// path: location.pathname, // 用于区分不同文章的自定义 js 路径,如果您的文章路径不是 location.pathname需传此参数
// lang: 'zh-CN', // 用于手动设定评论区语言,支持的语言列表 https://github.com/twikoojs/twikoo/blob/main/src/client/utils/i18n/index.js
})
</script>
```
为了方便传参数,我们需要在 `src/types/config.ts`中添加一个twikooConfig配置
```ts title="src/types/config.ts"
export type TwikooConfig = {
enable?: boolean;
envId?: string;
lang?: string;
};
```
最后在`src/config.ts`中添加一下修改并配置自己的`envId`
```diff title="src/config.ts" lang="ts" "填入之前在Twikoo云函数部署时拿到的Id"
import type {
ExpressiveCodeConfig,
LicenseConfig,
NavBarConfig,
ProfileConfig,
SiteConfig,
+ TwikooConfig,
} from "./types/config";
...
// 在文件最后添加一下内容
+ export const twikooConfig: TwikooConfig = {
+ enable: true,
+ envId: "填入之前在Twikoo云函数部署时拿到的Id",
+ };
```
配置好后`pnpm dev`测试一下,能看到文章底下的评论区了。
最后记得点击Twikoo评论区的小设置齿轮配置一下Twikoo的一些通知系统。

View File

@ -207,7 +207,7 @@ fdisk /dev/sda #对sda磁盘进行分区
> - n: 创建分区
> - p: 查看分区
> - q: 不保存退出
> - w: 保存并退出 所有操作在执行”w”前都不会生效
> - w: 保存并退出 所有操作在执行"w"前都不会生效
![img](https://s1.vika.cn/space/2023/04/14/19d395dd4761416eb96503de9016e74f)

View File

@ -62,7 +62,7 @@ C 语言最初是用于系统开发工作,特别是组成操作系统的程序
C 程序
一个 C 语言程序,可以是 3 行,也可以是数百万行,它可以写在一个或多个扩展名为 .c 的文本文件中例如hello.c。可以使用 VScode/Dev-C++/Vim或者其他编辑器来编写 C 语言程序。
一个 C 语言程序,可以是 3 行,也可以是数百万行,它可以写在一个或多个扩展名为 ".c" 的文本文件中例如hello.c。可以使用 VScode/Dev-C++/Vim或者其他编辑器来编写 C 语言程序。
@ -86,7 +86,7 @@ C11也被称为C1X指ISO标准ISO/IEC 9899:2011。在它之前的C语言
- 增加了更多浮点处理宏(宏)。
- 匿名结构体/联合体支持。这个在gcc早已存在C11将其引入标准。
- 静态断言Static assertions_Static_assert(),在解释 #if#error 之后被处理。
- 新的 fopen() 模式,(…x)。类似 POSIX 中的 O_CREAT|O_EXCL在文件锁中比较常用。
- 新的 fopen() 模式,("…x")。类似 POSIX 中的 O_CREAT|O_EXCL在文件锁中比较常用。
- 新增 quick_exit() 函数作为第三种终止程序的方式。当 exit()失败时可以做最少的清理工作。
## 环境配置
@ -103,7 +103,7 @@ C11也被称为C1X指ISO标准ISO/IEC 9899:2011。在它之前的C语言
## 程序结构
### C hello world 实例
### C "hello world" 实例
C 程序主要包括以下几个部分:
@ -128,8 +128,8 @@ int main() {
| :---------------: | :----------------------------------------------------------: |
| #include<stdio.h> | 预处理指令,告诉 C 编译器在实际编译之前要包含 stdio.h 文件。 |
| int main() | 程序的主函数,程序从这里开始运行 |
| /*…*/ | “…”里的内容会被编译器忽略,这里放置程序的注释内容。它们被称为程序的注释 |
| printf(…) | C语言 中一个可用的函数,会在屏幕上显示消息…(括号内的内容) |
| /*…*/ | "…"里的内容会被编译器忽略,这里放置程序的注释内容。它们被称为程序的注释 |
| printf(…) | C语言 中一个可用的函数,会在屏幕上显示消息"…(括号内的内容)" |
| return 0; | 终止main()函数,并返回值0. |
### 编译 & 执行 C 程序
@ -150,7 +150,7 @@ printf("hello world! \n");
- printf
- (
- Hello, World! \n
- "Hello, World! \n"
- )
- ;
@ -208,7 +208,7 @@ hideToggle 点我查看
| char | 声明字符型变量或函数返回值类型 |
| const | 定义常量,如果一个变量被 const 修饰,那么它的值就不能再被改变 |
| continue | 结束当前循环,开始下一轮循环 |
| default | 开关语句中的其它分支 |
| default | 开关语句中的"其它"分支 |
| do 循环语句的循环体 | |
| double | 声明双精度浮点型变量或函数返回值类型 |
| else | 条件语句否定分支(与 if 连用) |
@ -575,7 +575,7 @@ int g = 20;
| ---------- | -------------------------- |
| \ | \ 字符 |
| ' | 字符 |
| " | 字符 |
| " | " 字符 |
| ? | ? 字符 |
| \a | 警报铃声 |
| \b | 退格键 |
@ -609,7 +609,7 @@ Hello World
### 字符串常量
字符串字面值或常量是括在双引号 “” 中的。一个字符串包含类似于字符常量的字符:普通的字符、转义序列和通用的字符。
字符串字面值或常量是括在双引号 "" 中的。一个字符串包含类似于字符常量的字符:普通的字符、转义序列和通用的字符。
您可以使用空格做分隔符,把一个很长的字符串常量进行分行。
@ -931,10 +931,10 @@ A^B = 0011 0001
| 运算符 | 描述 | 实例 |
| ------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
| & | 按位与操作,按二进制位进行”与”运算。运算规则:`0&0=0; 0&1=0; 1&0=0; 1&1=1;` | (A & B) 将得到 12即为 0000 1100 |
| \| | 按位或运算符,按二进制位进行”或”运算。运算规则:`0 | 0=0; 0 |
| ^ | 异或运算符,按二进制位进行异或运算。运算规则:`0^0=0; 0^1=1; 1^0=1; 1^1=0;` | (A ^ B) 将得到 49即为 0011 0001 |
| ~ | 取反运算符,按二进制位进行取反运算。运算规则:`~1=-2; ~0=-1;` | (~A ) 将得到 -61即为 1100 0011一个有符号二进制数的补码形式。 |
| & | 按位与操作,按二进制位进行"与"运算。运算规则:`0&0=0; 0&1=0; 1&0=0; 1&1=1;` | (A & B) 将得到 12即为 0000 1100 |
| \| | 按位或运算符,按二进制位进行"或"运算。运算规则:`0 | 0=0; 0 |
| ^ | 异或运算符,按二进制位进行"异或"运算。运算规则:`0^0=0; 0^1=1; 1^0=1; 1^1=0;` | (A ^ B) 将得到 49即为 0011 0001 |
| ~ | 取反运算符,按二进制位进行"取反"运算。运算规则:`~1=-2; ~0=-1;` | (~A ) 将得到 -61即为 1100 0011一个有符号二进制数的补码形式。 |
| << | 二进制左移运算符。将一个运算对象的各二进制位全部左移若干位左边的二进制位丢弃右边补0。 | A << 2 将得到 240即为 1111 0000 |
| >> | 二进制右移运算符。将一个数的各二进制位全部右移若干位正数左补0负数左补1右边丢弃。 | A >> 2 将得到 15即为 0000 1111 |

View File

@ -290,11 +290,11 @@ printf("%s%s%s",a,b,c); // 输出How are you
- put(字符数组)
将一个字符串输出到终端
作用等效于printf(%s,c);也可以输出转义字符
作用等效于printf("%s",c);也可以输出转义字符
![3.jpg](https://s1.vika.cn/space/2022/12/01/1aede231c9b74806b62f3f93416083af)
- gets(字符数组)
从终端输入一个字符串到字符数组,并且得到一个函数值,该函数值为字符数组的起始地址。
相比于scanf(%s,c);可以返回数组的地址值
相比于scanf("%s",c);可以返回数组的地址值
![4.jpg](https://s1.vika.cn/space/2022/12/01/4fee6e5fd444452a8746f3b3725475b3)

View File

@ -44,7 +44,7 @@ lang: ''
### 1、为什么要定义
- 程序中用到的所有函数必须先定义,后使用
- 程序中用到的所有函数必须"先定义,后使用"
- 同变量定义的道理类似,需要事先告知系统该函数功能、参数等信息,具体包括:
@ -136,7 +136,7 @@ m=max(a,max(b,c)); //将调用max函数的结果再重新作为下一次
**1.形参:定义函数时,函数名括号后面的变量称为形式参数(或虚拟参数)**
- 形参在函数调用时被分配内存单元,调用结束后立即释放
- 形参为变量时,实参与形参的数据传递是值传递,即单向传递
- 形参为变量时,实参与形参的数据传递是"值传递",即"单向传递"
**2.实参:在主调函数中调用一个函数时,函数名后面括号中的参数称为实际参数**
@ -145,7 +145,7 @@ m=max(a,max(b,c)); //将调用max函数的结果再重新作为下一次
- 形参与实参的类型应相同或i赋值兼容。
note red modern
注:实参向形参的数据传递是值传递,单向传递,只能由实参传给形参,而不能由形参传给实参。
注:实参向形参的数据传递是"值传递",单向传递,只能由实参传给形参,而不能由形参传给实参。
实参和形参在内存中占有不同的存储单元,实参无法得到形参的值。
endnote

View File

@ -55,10 +55,10 @@ lang: ''
注意事项:
note red modern
指针变量前面的”*”表示该变量为指针型变量指针变量名是p而不是 *p。
指针变量前面的"*"表示该变量为指针型变量指针变量名是p而不是 *p。
在定义指针变量时必须指定**基类型**(因为不同类型的数据在内存中所占的字节数和存放方式是不同的)
指向整形数据的指针类型表示为int*读作指向int的指针或 int指针
指向整形数据的指针类型表示为"int*"读作指向int的指针或 int指针
指针变量中只能存放地址(指针),试图将一个整数赋给一个指针变量是不合法的。
@ -87,8 +87,8 @@ endnote
- **强调两个运算符。**
> “&”取地址运算符 &a是变量a的地址
> “*” 指针运算符(间接访问运算符) *p代表指针变量p指向的对象
> "&"取地址运算符 &a是变量a的地址
> "*" 指针运算符(间接访问运算符) *p代表指针变量p指向的对象
例:

View File

@ -99,7 +99,7 @@ lang: ''
> - 有几百种不同的license
> - 有些license去遵守是有点难度的
> - GNU GPL说如果被修改,发布的代码也要在GPL下发布,你只能用GPL代码
> - copyleft(非盈利版权)
> - "copyleft"(非盈利版权)
> - **自由软件 && 免费软件**
> - 自由软件不一定免费
> - 免费软件并不公开源码
@ -230,10 +230,10 @@ endfolding
- 项与项之间以空格隔开
- options修饰一个命令的行为
- 单字母选项一般带有”-“,例如:-a,-b,-c,或者-abc
- 全字母选项前常带有”–”,例如:help
- 单字母选项一般带有"-",例如:-a,-b,-c,或者-abc
- 全字母选项前常带有"",例如:help
- 参数是一个文件名或者其他被该命令需要的数据
- 多个命令用”;”进行分隔
- 多个命令用";"进行分隔
> - 多种层次的帮助
> - [whatis](https://www.atdunbg.xyz/2023/03/19/cloud_linux_1/#whatis)
@ -256,7 +256,7 @@ whatis是查询一个命令执行什么功能并把查询结果打印到显
> - 为名提供相关帮助文档
- 几乎所有的命令都有 man “页”
- 几乎所有的命令都有 man "页"
- 页面分成章节,共八章
@ -302,8 +302,8 @@ whereis命令用于查找文件。
- 在[]中的参数是可以选择的
- 大写的参数在<>中表示变量
- 文本后面跟随…表示一个列表
- x|y|z表示 x或者y或者z
*-abc表示 任意-a,-b,或者-c的任意组合
- x|y|z表示 "x或者y或者z"
*-abc表示 "任意-a,-b,或者-c的任意组合"
## SHELl的常用命令
@ -687,11 +687,11 @@ note info modern
- 撤销改变
- u 撤销最近的改变
- U 撤销当前行自从光标定位在上面开始的所有改变
- Ctrl+r 重做最后一次 撤销 改变
- Ctrl+r 重做最后一次 "撤销" 改变
## SHELL基础
** Shell 一种特殊的程序,被称为脚本语言,他是用户与unix/Linux系统 心脏 之间的接口.**
** Shell 一种特殊的程序,被称为脚本语言,他是用户与unix/Linux系统 "心脏" 之间的接口.**
![img](https://s1.vika.cn/space/2023/03/20/3a31fd6533004826b195dc3a86e667a5)
@ -968,7 +968,7 @@ export
- 字符测试
- =:等于,比如:[$A”=“$B]
- =:等于,比如:["$A"="$B"]
- != :不等于
@ -976,9 +976,9 @@ export
- > :大于
- -z:字符串长度为null
- -z:字符串长度为"null"
- -n:字符串长度不为null
- -n:字符串长度不为"null"
- 整数测试
@ -1289,7 +1289,7 @@ continue [n] # 跳出指定循环(未指定默认为1)
> - 默认匹配是与
- 可以用-0或者是-not表示”或”或者是
- 可以用-0或者是-not表示"或"或者是
- 括号可以用来检测逻辑操作的顺序,但必须用斜线转义
- find -user joe -not -group joe
- find -user joe -0 -user jane
@ -1335,7 +1335,7 @@ continue [n] # 跳出指定循环(未指定默认为1)
- 必须用-exec或者-ok打头执行命令
- -ok在对每个文件进行动作前提示
- 命令必须以空格+斜线(" )+分号结尾
- 命令必须以空格+斜线("" )+分号结尾
- 可以使用{}作为文件名字占位符
- find -size + 100M -ok mv {} /tmp/largefiles/ \ ;
@ -1501,7 +1501,7 @@ gpgcheck=1
- 从这些文件进行读写是合法的操作:
- echo Message > /dev/tty1
- echo "Message" > /dev/tty1
- 三种文件属性决定访问哪种驱动:

View File

@ -15,7 +15,7 @@ lang: ''
### Socket 通讯
- 所谓socket通常也称作套接字 ,用于描述IR地址和端口,是一个通信链的句柄。应用程序通常通过套接字向网络发出请求或者应答网络请求。
- 所谓socket通常也称作"套接字" ,用于描述IR地址和端口,是一个通信链的句柄。应用程序通常通过"套接字"向网络发出请求或者应答网络请求。
![img](https://s1.vika.cn/space/2023/04/19/c3c2efcc5f0840f4bb365212449401c1)
@ -45,15 +45,15 @@ linux下的服务管理有两类:
### System V 服务
System V 曾经也被称为 AT&T System V是Unix操作系统众多版本中的一支。它最初由 AT&T 开发在1983年第一次发布。一共发行了4个 System V 的主要版本版本1、2、3 和 4。System V Release 4或者称为SVR4是最成功的版本成为一些UNIX共同特性的源头例如 SysV 初始化脚本 (/etc/init.d)用来控制系统启动和关闭System V Interface Definition (SVID) 是一个System V 如何工作的标准定义。
System V 曾经也被称为 AT&T System V是Unix操作系统众多版本中的一支。它最初由 AT&T 开发在1983年第一次发布。一共发行了4个 System V 的主要版本版本1、2、3 和 4。System V Release 4或者称为SVR4是最成功的版本成为一些UNIX共同特性的源头例如 "SysV 初始化脚本" (/etc/init.d)用来控制系统启动和关闭System V Interface Definition (SVID) 是一个System V 如何工作的标准定义。
> - 通常被成为System VSysV
> - 通常被成为"System V""SysV"
- 许多脚本都是用文件系统目录的格式来组织的
- 可启用或者禁用资源服务
- 经常使用几个配置文件
- 大多数服务启动一个或多个进程
- 命令被包裹在脚本中.
- 命令被"包裹"在脚本中.
- 服务由/etc/init.d/目录中的脚本管理
- 例如: /etc/init.d/sshd status
- service sshd status
@ -143,7 +143,7 @@ System V 曾经也被称为 AT&T System V是Unix操作系统众多版本
### Rsyslog 服务
**把日志集中存储在一个安全的地方, 通过日志分析系统的运行情况. Rsyslog全称the Rocket-fast SYStem for LOG processing,是一种应用于UNIX和Linux计算机系统在IP网络转发日志消息开源软件实用的程序。它实现了基本的syslog协议,扩展了基于内容过滤的过滤能力,丰富灵活的配置选项,并增加了诸如使用TCP传输的特点。**
**把日志集中存储在一个安全的地方, 通过日志分析系统的运行情况. Rsyslog全称"the Rocket-fast SYStem for LOG processing",是一种应用于UNIX和Linux计算机系统在IP网络转发日志消息开源软件实用的程序。它实现了基本的syslog协议,扩展了基于内容过滤的过滤能力,丰富灵活的配置选项,并增加了诸如使用TCP传输的特点。**
> - 格式: selector action
> - selector : facility.level
@ -230,7 +230,7 @@ endfolding
- 启用TCP
- $ModLoad imtcp
- $InputTCPServerRun 514
- $template TemplateName, 格式, < options>
- $template TemplateName, "格式", < options>
- 引号模板:
- ? TemplateName
@ -300,7 +300,7 @@ endfolding
- can be used to start additional programs
- special expansions are available (%C, %s)
- 例如:
- in.telnetd: ALL : spawn echo login attempt from %C to %s| mail -S warning root
- in.telnetd: ALL : spawn echo "login attempt from %C to %s"| mail -S warning root
- deny:
- 可作为hosts.allow中的一个选项
- 例如:
@ -331,7 +331,7 @@ endfolding
![img](https://s1.vika.cn/space/2023/04/21/d34dc5807a5946b2bca55e836f6a0ed4)
> - 所有文件和进程都具备安全环境( security context )
> - 所有文件和进程都具备"安全环境"( security context )
- 环境包含几个元素,根据安全的需要使用不同的元素
- user.role:type:sensitivity:category
@ -353,7 +353,7 @@ endfolding
- system_ _r - - -般为进程的角色
> - 一组叫做策略( policy)的规则会决定控制的严格程度
> - 一组叫做"策略( policy)"的规则会决定控制的严格程度
- 进程要么是被限制的(restricted) ,要么是无束缚的( unconfined)
- 策略被用来定义被限制的进程能够使用哪些资源
@ -450,7 +450,7 @@ endfolding
- 域字段叫做始发地址
- rdata字段被引申为支持额外数据r 下-一个演示片对此进行了解释
- 一般来说, -一个域通常有一 个主名称服务器,它保存数据的主要副本
- 域或区块的其它规范性名称服务器被称为从服务器,它们会将其数据与主服务器同步
- 域或区块的其它规范性名称服务器被称为"从服务器",它们会将其数据与主服务器同步
- SOA rdata
- 主名称服务器的FQDN
- 联系邮件地址
@ -458,7 +458,7 @@ endfolding
- 在刷新序列号码之前刷新延迟时间
- 从服务器的重试间隔
- 当从服务器无法连接它的主服务器时,记录会过期
- 否定性答复(no such host)的TTL最小值
- 否定性答复("no such host")的TTL最小值
| 记录类型 | 说明 |
| -------- | ---------------------- |
@ -494,11 +494,11 @@ zone "example.com"
- 一般可以用来代替匹配列表(允许嵌套! )
- 最好的办法是在/etc/named.conf文件的开始处定义ACL
- 声明示例
- aclytrusted {192.168.1.21; }
- acl classroom { 192.168.0.0/24; trusted;};
- acl cracker { 192.168.1.0/24; };
- acl mymasters { 192.168.0.254; };
- acl myaddresses { 127.0.0.1; 192.168.0.1; };
- acly"trusted {192.168.1.21; }
- acl "classroom" { 192.168.0.0/24; trusted;};
- acl "cracker" { 192.168.1.0/24; };
- acl "mymasters" { 192.168.0.254; };
- acl "myaddresses" { 127.0.0.1; 192.168.0.1; };
- 内置ACL
- BIND预定义了几个ACL:
- none - 不匹配任何IP地址
@ -567,10 +567,10 @@ zone "example.com"
> - mountd, statd和lockd可以被强制使用一个静态端口
- 在/etc/sysconfig/nfs中设置MOUNTD_ PORT、STATD_ PORT LOCKD_ TCPPORTHE和LOCKD_ UDPPORT变量
- MOUNTD_ PORT=4002
- STATD_ PORT= 4003
- LOCKD_ TCPPORT= 4004
- LOCKD_ UDPPORT= 4004
- MOUNTD_ PORT="4002"
- STATD_ PORT= "4003"
- LOCKD_ TCPPORT= "4004"
- LOCKD_ UDPPORT= "4004"
## WEB 服务
@ -726,7 +726,7 @@ iptable -t filter -A INPUT -s 192.168.0.1 -j DROP
| 2 | 密码 | 在旧的unix系统中该字段是用户加密后的密码现在已经不再使用而是将密码放在/etc/shadow中所以此处都只是一个字母X |
| 3 | UID | 系统用来区分不同用户的整数 |
| 4 | GID | 系统用来区分不同用户组的整数 |
| 5 | 说明栏 | 类似于注释 |
| 5 | 说明栏 | 类似于"注释" |
| 6 | 家目录 | 用户登录后,默认所处的目录,即家目录 |
| 7 | 登录SHELL | 用户登录后所使用的SHELL |

View File

@ -104,7 +104,7 @@ lang: ''
- 目前,多数服务器基础桌面计算机均处理启用状态.
> - 嵌套式实验环境
> - "嵌套"式实验环境
> - 在虚拟机中再做虚拟化
- VMware嵌套虚拟化
@ -117,7 +117,7 @@ lang: ''
### 实验环境准备
> - 嵌套 式实验环境
> - "嵌套" 式实验环境
> - VMware Workstation Player或VMware Workstation
> - 创建虚拟机,在此虚拟机上安装KVM

View File

@ -239,7 +239,7 @@ sqlmap.py -u "http://127.0.0.1/vul/sqli/sqli_str.php?name=1&submit=%E6%9F%A5%E8%
### 搜索型注入
由于没有过滤“%”,“%”可以进行匹配任意字符与linux中的”*“类似
由于没有过滤"%""%"可以进行匹配任意字符与linux中的"*"类似
**sqlmap**
@ -265,7 +265,7 @@ sqlmap.py -u "http://127.0.0.1/vul/sqli/sqli_search.php?name=1&submit=%E6%90%9C%
python sqlmap.py -u "http://127.0.0.1/vul/sqli/sqli_x.php?name=1&submit=%E6%9F%A5%E8%AF%A2" --batch -D pikachu -T member --dump
```
### insert/update注入
### "insert/update"注入
注册一下账户然后brup抓包随便选一个变量修改如下
@ -281,11 +281,11 @@ extractvalue() 是mysql对xml文档数据进行查询和修改的xpath函数
updatexml() 是mysql对xml文档数据进行查询的xpath函数
```
### delete注入
### "delete"注入
操作同上在点击删除留言时进行抓包发现有一个id参数可以进行注入不过发现注入的参数中不能出现空格否则空格后面不会进行处理
可以用“+”代替空格
可以用"+"代替空格
```txt
+and+updatexml(1,concat(0x7e,database(),0x7e),1)
@ -293,7 +293,7 @@ updatexml() 是mysql对xml文档数据进行查询的xpath函数
![报错注入2](https://s1.vika.cn/space/2023/08/12/0af26ca25cc440cd87e1683bc22e3942)
### http header注入
### "http header"注入
![http_header注入](https://s1.vika.cn/space/2023/08/12/4f4d58643a944fefa047f5119908366c)
@ -344,7 +344,7 @@ kobe' and substr(database(),1,1)='a'#
![boolean盲注3](https://s1.vika.cn/space/2023/08/12/e4c7a656d5df4108aefea632dbd20f7a)
第二个参数修改爆破字符为a-z ,顺带着添加一个”_”
第二个参数修改爆破字符为a-z ,顺带着添加一个"_"
![boolean盲注4](https://s1.vika.cn/space/2023/08/12/77a6c71a8e894d339f3afd1ad959468f)
@ -383,27 +383,27 @@ sqlmap.py -u "http://127.0.0.1/vul/sqli/sqli_blind_t.php?name=123&submit=%E6%9F%
  输入%df和函数执行添加的%5C被合并成%df%5C。由于GBK是两字节这个%df%5C被MYSQL识别为GBK。导致本应的%df\变成%df%5C。%df%5C在GBK编码中没有对应所以被当成无效字符。
  %DF 会被PHP当中的addslashes函数转义为%DF\' “\”既URL里的%5C,那么也就是说,%DF'会被转成%DF%5C%27倘若网站的字符集是GBKMYSQL使用的编码也是GBK的话就会认为%DF%5C%27是一个宽字符。也就是縗’
  %DF 会被PHP当中的addslashes函数转义为"%DF\'" "\"既URL里的"%5C",那么也就是说,"%DF'"会被转成"%DF%5C%27"倘若网站的字符集是GBKMYSQL使用的编码也是GBK的话就会认为"%DF%5C%27"是一个宽字符。也就是"縗’"
例如http://www.xxx.com/login.php?user=%df or 1=1 limit 1,1%23&pass=
其对应的sql就是
select * fromcms_user where username = ‘運’ or 1=1 limit 1,1# and password=
select * fromcms_user where username = ‘運’ or 1=1 limit 1,1# and password="
```
在’前面加个%df也就可以实现逃逸转义然后burp抓包剩下操作同上
## 0x06 RCE
### execping
### exec"ping"
```txt
127.0.0.1&&dir
#执行完ping指令后同时执行dir指令
```
### execeval
### exec"eval"
```txt
直接输入 phpinfo();
@ -654,7 +654,7 @@ dict://192.168.1.66:80
### SSRF(file_get_content)
利用file_get_content(path)利用传递的参数通过file参数访问内部资源或者跳转到其他服务器页面
利用file_get_content("path")利用传递的参数通过file参数访问内部资源或者跳转到其他服务器页面
```txt
//直接读取内部文件

View File

@ -113,7 +113,6 @@ const jsonLd = {
</div>
<div class="flex w-full rounded-[var(--radius-large)] overflow-hidden relative mb-4">
<div ></div>
<div id="post-container" class="card-base p-6 mb-4 text-black/75 dark:text-white/75 transition" class:list={["card-base z-10 px-6 md:px-9 pt-6 pb-4 relative w-full ", {} ]}>
<Twikoo />
</div>