<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Tamako Blog</title><description>好きです</description><link>https://tamako-blog.netlify.app/</link><language>en</language><item><title>Bash Shell Practices</title><link>https://tamako-blog.netlify.app/posts/bash-shell-practices/</link><guid isPermaLink="true">https://tamako-blog.netlify.app/posts/bash-shell-practices/</guid><description>一些 shell 脚本实践</description><pubDate>Thu, 22 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;将当前路径所有图片压缩成 webp&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash

# 检查cwebp是否安装
if ! command -v cwebp &amp;amp;&amp;gt; /dev/null; then
    echo &quot;错误：未找到cwebp命令，请先安装WebP工具：&quot;
    echo &quot;Ubuntu/Debian: sudo apt-get install webp&quot;
    echo &quot;MacOS: brew install webp&quot;
    exit 1
fi

# 支持的图片格式（可自行扩展）
# formats=(&quot;jpg&quot; &quot;jpeg&quot; &quot;png&quot; &quot;tiff&quot; &quot;bmp&quot; &quot;gif&quot;)
formats=(&quot;png&quot;)

# 转换质量参数
quality=100

# 计数器
converted=0
skipped=0

echo &quot;开始批量转换图片到WebP格式（质量${quality}）...&quot;

遍历所有支持的图片格式
for ext in &quot;${formats[@]}&quot;; do
    while IFS= read -r -d $&apos;\0&apos; file; do
        # 生成输出文件名
        output=&quot;${file%.*}.webp&quot;
        
        # 跳过已存在的webp文件
        if [[ -f &quot;$output&quot; ]]; then
            echo &quot;跳过已存在文件：$output&quot;
            ((skipped++))
            continue
        fi

        # 执行转换命令
        if cwebp -q $quality &quot;$file&quot; -o &quot;$output&quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then
            echo &quot;成功转换：$file → $output&quot;
            ((converted++))
        else
            echo &quot;转换失败：$file&quot;
            # 删除可能生成的无效文件
            [[ -f &quot;$output&quot; ]] &amp;amp;&amp;amp; rm &quot;$output&quot;
        fi
    done &amp;lt; &amp;lt;(find . -maxdepth 1 -type f -iname &quot;*.${ext}&quot; -print0)
done

# 统计结果
echo &quot;&quot;
echo &quot;转换完成！&quot;
echo &quot;成功转换文件数：${converted}&quot;
echo &quot;跳过已存在文件数：${skipped}&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;创建code命令，使用IDE打开文件&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/zsh

# 0参数  直接vscode .
# 1参数  code $1 =&amp;gt; code vscode / code idea / code goland
# ide 直接打开当前路径
# 2参数  code $1 $2 =&amp;gt; code vscode ddd / code idea ddd / code goland dd
# 先选择ide 在选择路径

# 定义 IDE 命令映射（关联数组）
typeset -A IDE_COMMANDS=(
    [vs]=&quot;open -a &apos;Visual Studio Code&apos;&quot;      # VSCode
    [idea]=&quot;open -a &apos;IntelliJ IDEA&apos;&quot;         # IDEA
    [go]=&quot;open -a &apos;GoLand&apos;&quot;                  # Goland
    [web]=&quot;open -a &apos;WebStorm&apos;&quot;               # WebStorm
    # 添加更多 IDE...
)

# 参数处理逻辑
case $# in
    0)  # 无参数：用 VSCode 打开当前目录
        eval &quot;${IDE_COMMANDS[vs]} .&quot;
        ;;
    1)  # 一个参数：用指定 IDE 打开当前目录
        ide_type=$1
        if [[ -n &quot;${IDE_COMMANDS[$ide_type]}&quot; ]]; then
            eval &quot;${IDE_COMMANDS[$ide_type]} .&quot;
        else
            echo &quot;🔴 错误：未知 IDE 类型 &apos;$ide_type&apos;&quot;
            echo &quot;可用选项: ${(k)IDE_COMMANDS[@]}&quot;
            exit 1
        fi
        ;;
    2)  # 两个参数：用指定 IDE 打开目标路径
        ide_type=$1
        target_path=$2
        if [[ -n &quot;${IDE_COMMANDS[$ide_type]}&quot; ]]; then
            if [[ -d &quot;$target_path&quot; ]]; then
                eval &quot;${IDE_COMMANDS[$ide_type]} &apos;$target_path&apos;&quot;
            else
                echo &quot;🔴 错误：路径不存在 &apos;$target_path&apos;&quot;
                exit 2
            fi
        else
            echo &quot;🔴 错误：未知 IDE 类型 &apos;$ide_type&apos;&quot;
            echo &quot;可用选项: ${(k)IDE_COMMANDS[@]}&quot;
            exit 1
        fi
        ;;
    *)  # 错误参数数量
        echo &quot;🔴 用法:&quot;
        echo &quot;  code              -&amp;gt; 用 VSCode 打开当前目录&quot;
        echo &quot;  code &amp;lt;IDE类型&amp;gt;    -&amp;gt; 用指定 IDE 打开当前目录&quot;
        echo &quot;  code &amp;lt;IDE类型&amp;gt; &amp;lt;路径&amp;gt; -&amp;gt; 用指定 IDE 打开目标路径&quot;
        exit 3
        ;;
esac
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在 &lt;code&gt;bashrc&lt;/code&gt; 或者 &lt;code&gt;zshrc&lt;/code&gt; 配置文件中添加别名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
# For a full list of active aliases, run `alias`.
...
alias code=&quot;$ZSH/scripts/ide-launch.sh&quot;
...
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Webp</title><link>https://tamako-blog.netlify.app/posts/webp/</link><guid isPermaLink="true">https://tamako-blog.netlify.app/posts/webp/</guid><description>An image format for the Web</description><pubDate>Sun, 11 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;What is Webp&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://developers.google.com/speed/webp/docs/using?hl=zh-cn&quot;&gt;Google Webp Official&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://developers.google.com/speed/webp/docs/using&quot;&gt;Developer Guides&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;WebP is a modern image format that provides superior lossless and lossy compression for images on the web. Using WebP, webmasters and web developers can create smaller, richer images that make the web faster.&lt;/p&gt;
&lt;p&gt;WebP lossless images are 26% smaller compared to PNGs. WebP lossy images are 25-34% smaller than comparable JPEG images at equivalent SSIM quality index.&lt;/p&gt;
&lt;h3&gt;WebP Support&lt;/h3&gt;
&lt;p&gt;WebP is natively supported in Google Chrome, Safari, Firefox, Edge, the Opera browser, and by many other tools and software libraries. Developers have also added support to a variety of image editing tools.&lt;/p&gt;
&lt;p&gt;WebP includes the lightweight encoding and decoding library &lt;a href=&quot;https://developers.google.com/speed/webp/docs/api&quot;&gt;&lt;code&gt;libwebp&lt;/code&gt;&lt;/a&gt; and the command line tools &lt;a href=&quot;https://developers.google.com/speed/webp/docs/cwebp&quot;&gt;&lt;code&gt;cwebp&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://developers.google.com/speed/webp/docs/dwebp&quot;&gt;&lt;code&gt;dwebp&lt;/code&gt;&lt;/a&gt; for converting images to and from the WebP format, as well as tools for viewing, muxing and animating WebP images. The full source code is available on the &lt;a href=&quot;https://developers.google.com/speed/webp/download&quot;&gt;download page&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;WebP Converter Download&lt;/h3&gt;
&lt;p&gt;Convert your favorite collection from PNG and JPEG to WebP by downloading the precompiled cwebp conversion tool for &lt;a href=&quot;https://developers.google.com/speed/webp/docs/precompiled&quot;&gt;Linux, Windows or macOS&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Using Libwebp&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;libwebp&lt;/code&gt; codec includes an extensive encoder and decoder API.&lt;/p&gt;
&lt;h3&gt;Using &lt;code&gt;cwebp&lt;/code&gt; to Convert Images to the WebP Format&lt;/h3&gt;
&lt;p&gt;Use cwebp on the command line to convert PNG or JPEG image files to WebP format. You can convert a PNG image file to a WebP image with a quality range of 80 with the command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cwebp -q 80 image.png -o image.webp
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-o string&lt;/code&gt; Specify the name of the output WebP file. If omitted, &lt;code&gt;cwebp&lt;/code&gt; will perform compression but only report statistics.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-q float&lt;/code&gt; Specify the compression factor for RGB channels between 0 and 100. The default is 75.&lt;/p&gt;
&lt;p&gt;In case of lossy compression (default), a small factor produces a smaller file with lower quality. Best quality is achieved by using a value of 100.&lt;/p&gt;
&lt;p&gt;In case of lossless compression (specified by the -lossless option), a small factor enables faster compression speed, but produces a larger file. Maximum compression is achieved by using a value of 100.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-lossless&lt;/code&gt; Encode the image without any loss.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More advanced options information &lt;a href=&quot;https://developers.google.com/speed/webp/docs/cwebp&quot;&gt;reference documentation&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Using &lt;code&gt;dwebp&lt;/code&gt; to Convert Images from the WebP Format&lt;/h3&gt;
&lt;p&gt;Use dwebp on the command line to convert WebP image files to the PNG or PPM format. You can convert a WebP image file, say image.webp to a PNG image with the command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dwebp image.webp -o image.png
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-o string&lt;/code&gt; Specify the name of the output file (as PNG format by default).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More advanced options information &lt;a href=&quot;https://developers.google.com/speed/webp/docs/dwebp&quot;&gt;reference documentation&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Using &lt;code&gt;webpinfo&lt;/code&gt; to view WebP file info&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;webpinfo image.webp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;File: image.webp
RIFF HEADER:
  File size: 944506
Chunk VP8  at offset     12, length 944494
  Width: 8000
  Height: 4300
  Alpha: 0
  Animation: 0
  Format: Lossy (1)
No error detected.
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Vimrc Reference</title><link>https://tamako-blog.netlify.app/posts/vimrc-reference/</link><guid isPermaLink="true">https://tamako-blog.netlify.app/posts/vimrc-reference/</guid><description>vimrc file reference</description><pubDate>Sat, 10 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Tabstop, softtabstop and shiftwidth&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://arisweedler.medium.com/tab-settings-in-vim-1ea0863c5990&quot;&gt;tab setting in vim&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Difference of the value of tabstop, softtabstop and shiftwidth.&lt;/p&gt;
&lt;p&gt;In order to determine how to place whitespace into your file upon receiving one of those commands, Vim refers to the values of the following settings.&amp;lt;br&amp;gt;
为了确定如何在收到这些命令之一时将空格放入文件中，Vim 会参考以下设置的值。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://vimdoc.sourceforge.net/htmldoc/options.html#&apos;tabstop&apos;&quot;&gt;tabstop&lt;/a&gt; — How many columns wide is a tab character worth? Does a &lt;code&gt;\t&lt;/code&gt; take up 4 columns? 2 columns? 8 columns? Changing this value will change how tabs are displayed. Must be greater than 0, as tabs having no width is never desired.&amp;lt;br&amp;gt;
&lt;code&gt;tabstop&lt;/code&gt; — 一个制表符值多少列宽？ &lt;code&gt;\t&lt;/code&gt; 占用 4 列吗？ 2 列？ 8 列？更改此值将更改选项卡的显示方式。必须大于 0，因为不希望制表符没有宽度。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://vimdoc.sourceforge.net/htmldoc/options.html#&apos;shiftwidth&apos;&quot;&gt;shiftwidth&lt;/a&gt; — Referred to for “levels of indentation”, where a level of indentation is shiftwidth columns of whitespace. That is, the shift-left-right commands, the formatting commands, and the behavior of vim with &lt;a href=&quot;http://vimdoc.sourceforge.net/htmldoc/options.html#&apos;cindent&apos;&quot;&gt;cindent&lt;/a&gt; or &lt;a href=&quot;http://vimdoc.sourceforge.net/htmldoc/options.html#&apos;autoindent&apos;&quot;&gt;autoindent&lt;/a&gt; set is determined by this setting. A shift command says “give me one more (or one less) level of indentation”. Formatting commands are more complicated (&lt;code&gt;:help gq&lt;/code&gt; if you’re curious, they basically parse your file and determine how many layers of indentation should be there). So if vim decides that a line needs 3 levels of indentation then it’ll place 3 * shiftwidth columns of whitespace.&amp;lt;br&amp;gt;
&lt;code&gt;shiftwidth&lt;/code&gt; — 称为“缩进级别”，其中缩进级别是空格的 shiftwidth 列。也就是说，左右移命令、格式化命令以及设置了 cindent 或 autoindent 的 vim 的行为都是由该设置决定的。移位命令表示“增加（或减少）一层缩进”。格式化命令更复杂（ &lt;code&gt;:help gq&lt;/code&gt; 如果你好奇的话，它们基本上会解析你的文件并确定应该有多少层缩进）。因此，如果 vim 确定一行需要 3 级缩进，那么它将放置 3*shiftwidth 的空白列。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://vimdoc.sourceforge.net/htmldoc/options.html#&apos;expandtab&apos;&quot;&gt;expandtab&lt;/a&gt; — Unlike the other settings, this one is a Boolean, and quite straightforward. It answers the question: should vim place spaces or tab upon receiving a whitespace command or a &lt;code&gt;tab&lt;/code&gt; keypress.&amp;lt;br&amp;gt;
&lt;code&gt;expandtab&lt;/code&gt; — 与其他设置不同，这是一个布尔值，并且非常简单。它回答了这个问题：vim 在接收到空格命令或 &lt;code&gt;tab&lt;/code&gt; 按键时是否应该放置空格或制表符。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://vimdoc.sourceforge.net/htmldoc/options.html#&apos;softtabstop&apos;&quot;&gt;softtabstop&lt;/a&gt; — Referred to for the &lt;code&gt;tab&lt;/code&gt; key and &lt;code&gt;backspace&lt;/code&gt; key. How much whitespace should be inserted when the &lt;code&gt;tab&lt;/code&gt; key is pressed? And how much whitespace should be removed when the &lt;code&gt;backspace&lt;/code&gt; key is pressed?&amp;lt;br&amp;gt;
&lt;code&gt;softtabstop&lt;/code&gt; — 指 &lt;code&gt;tab&lt;/code&gt; 键和 &lt;code&gt;backspace&lt;/code&gt; 键。按下 &lt;code&gt;tab&lt;/code&gt; 键时应插入多少空格？当按下 &lt;code&gt;backspace&lt;/code&gt; 键时应删除多少空格？&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;By default, softtabstop is disabled, meaning that hitting &lt;code&gt;tab&lt;/code&gt; will add whitespace columns until vim gets to a &lt;code&gt;tabstop&lt;/code&gt; (either 1 &lt;code&gt;\t&lt;/code&gt; character or &lt;code&gt;tabstop&lt;/code&gt; spaces, based on if &lt;code&gt;expandtab&lt;/code&gt; is set). And hitting &lt;code&gt;backspace&lt;/code&gt; will remove 1 character. This default behavior is weird when &lt;code&gt;expandtab&lt;/code&gt; is set, the lack of parallelism feels weird: pressing &lt;code&gt;tab&lt;/code&gt; will add &lt;code&gt;tabstop&lt;/code&gt; characters to your file, but &lt;code&gt;backspace&lt;/code&gt; will only remove 1. People normally want &lt;code&gt;backspace&lt;/code&gt; to remove a tab’s worth of whitespace when they have &lt;code&gt;expandtab&lt;/code&gt; set. So if you’re enabling &lt;code&gt;expandtab&lt;/code&gt; then you should enable &lt;code&gt;softtabstop&lt;/code&gt;.&amp;lt;br&amp;gt;
默认情况下，softtabstop 被禁用，这意味着点击 &lt;code&gt;tab&lt;/code&gt; 将添加空白列，直到 vim 到达 &lt;code&gt;tabstop&lt;/code&gt; （1 个 &lt;code&gt;\t&lt;/code&gt; 字符或 在设置 &lt;code&gt;expandtab&lt;/code&gt; 时 &lt;code&gt;tabstop&lt;/code&gt; 个空格）。点击 &lt;code&gt;backspace&lt;/code&gt; 将删除 1 个字符。设置 &lt;code&gt;expandtab&lt;/code&gt; 时，这种默认行为很奇怪，缺乏并行性感觉很奇怪：按 &lt;code&gt;tab&lt;/code&gt; 会将 &lt;code&gt;tabstop&lt;/code&gt; 字符添加到文件中，但 &lt;code&gt;backspace&lt;/code&gt; 时，人们通常希望 &lt;code&gt;backspace&lt;/code&gt; 删除制表符的空白。因此，如果您启用 &lt;code&gt;expandtab&lt;/code&gt; 那么您应该启用 &lt;code&gt;softtabstop&lt;/code&gt; 。&lt;/p&gt;
&lt;p&gt;Alright! Not too bad. Let’s just review really quickly:&amp;lt;br&amp;gt;
好吧！还不错。让我们快速回顾一下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tabstop&lt;/code&gt; is effectively how many columns of whitespace a &lt;code&gt;\t&lt;/code&gt; is worth.&amp;lt;br&amp;gt;
&lt;code&gt;tabstop&lt;/code&gt; 实际上是 &lt;code&gt;\t&lt;/code&gt; 值得多少列空白。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;shiftwidth&lt;/code&gt; is how many columns of whitespace a “level of indentation” is worth.&amp;lt;br&amp;gt;
&lt;code&gt;shiftwidth&lt;/code&gt; 是“缩进级别”值得多少列空白。&lt;/li&gt;
&lt;li&gt;Setting &lt;code&gt;expandtab&lt;/code&gt; means that you never wanna see a &lt;code&gt;\t&lt;/code&gt; again in your file.&amp;lt;br&amp;gt;
设置 &lt;code&gt;expandtab&lt;/code&gt; 意味着您再也不想在文件中看到 &lt;code&gt;\t&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;softtabstop&lt;/code&gt; is how many columns of whitespace a &lt;code&gt;tab&lt;/code&gt; keypress or a &lt;code&gt;backspace&lt;/code&gt; keypress is worth.&amp;lt;br&amp;gt;
&lt;code&gt;softtabstop&lt;/code&gt; 是 &lt;code&gt;tab&lt;/code&gt; 按键或 &lt;code&gt;backspace&lt;/code&gt; 按键值得多少列空白。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Well, that made it sound simple. But it gets kinda nuanced:&amp;lt;br&amp;gt;
嗯，这听起来很简单。但它有点微妙：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;By default (&lt;code&gt;softtabstop=0&lt;/code&gt;, &lt;code&gt;noexpandtab&lt;/code&gt;), a &lt;code&gt;tab&lt;/code&gt; keypress will give you a &lt;code&gt;\t&lt;/code&gt; character. And a &lt;code&gt;backspace&lt;/code&gt; keypress will remove 1 character.&amp;lt;br&amp;gt;
默认情况下（ &lt;code&gt;softtabstop=0&lt;/code&gt; 、 &lt;code&gt;noexpandtab&lt;/code&gt; ），按 &lt;code&gt;tab&lt;/code&gt; 按键将为您提供 &lt;code&gt;\t&lt;/code&gt; 字符。按下 &lt;code&gt;backspace&lt;/code&gt; 按键将删除 1 个字符。&lt;/li&gt;
&lt;li&gt;If you set &lt;code&gt;expandtab&lt;/code&gt;, then a &lt;code&gt;tab&lt;/code&gt; keypress will give you &lt;code&gt;tabstop&lt;/code&gt; spaces. A &lt;code&gt;backspace&lt;/code&gt; keypress will remove 1 character.&amp;lt;br&amp;gt;
如果您设置 &lt;code&gt;expandtab&lt;/code&gt; ，则按 &lt;code&gt;tab&lt;/code&gt; 按键将为您提供 &lt;code&gt;tabstop&lt;/code&gt; 空格。按下 &lt;code&gt;backspace&lt;/code&gt; 按键将删除 1 个字符。&lt;/li&gt;
&lt;li&gt;If you set &lt;code&gt;softtabstop&lt;/code&gt;, then a &lt;code&gt;tab&lt;/code&gt; keypress will give you &lt;code&gt;softabstop&lt;/code&gt; spaces. A &lt;code&gt;backspace&lt;/code&gt; keypress will remove &lt;code&gt;softabstop&lt;/code&gt; columns of whitespace (or 1 character, if you’re in the middle of a block of text and stuff).&amp;lt;br&amp;gt;
如果您设置 &lt;code&gt;softtabstop&lt;/code&gt; ，则按 &lt;code&gt;tab&lt;/code&gt; 按键将为您提供 &lt;code&gt;softabstop&lt;/code&gt; 空格。按下 &lt;code&gt;backspace&lt;/code&gt; 按键将删除 &lt;code&gt;softabstop&lt;/code&gt; 列空白（或 1 个字符，如果您位于文本块和其他内容的中间）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you understand the abstractions that the designers of vim made, then everything is simple! Here’s how I understand it: enabling &lt;code&gt;softtabstop&lt;/code&gt; says that &lt;code&gt;backspace&lt;/code&gt; and &lt;code&gt;tab&lt;/code&gt; should change of &lt;em&gt;columns of whitespace&lt;/em&gt; instead of &lt;em&gt;characters&lt;/em&gt;. And orthogonally related, &lt;code&gt;shiftwidth&lt;/code&gt; is all about levels of indentation.&amp;lt;br&amp;gt;
如果你理解 vim 设计者所做的抽象，那么一切就变得简单了！我的理解是这样的：启用 &lt;code&gt;softtabstop&lt;/code&gt; 表示 &lt;code&gt;backspace&lt;/code&gt; 和 &lt;code&gt;tab&lt;/code&gt; 应该更改空白列而不是字符。与正交相关的是， &lt;code&gt;shiftwidth&lt;/code&gt; 与缩进级别有关。&lt;/p&gt;
&lt;h2&gt;Vimrc file template&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&quot; 显示行号
set number
&quot; 高亮搜索
set hlsearch
&quot; 高亮自动匹配的括号
set showmatch
&quot; set cursorline
&quot; 显示标尺
set ruler
&quot; 显示输入的命令
set showcmd
&quot; 自动缩进
set autoindent
&quot; 缩进时自动对齐缩进长度
set shiftround
&quot; 输入tab时会转换为空格
set expandtab
&quot; 缩进长度为4
set shiftwidth=4
set tabstop=4 softtabstop=4
&quot; 次数暂时不起作用
set smarttab
&quot; 语法高亮
syntax enable

autocmd FileType go setlocal noexpandtab
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://www.linode.com/docs/guides/introduction-to-vim-customization/&quot;&gt;Introduction To Vim Customization&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>Vim Cheat</title><link>https://tamako-blog.netlify.app/posts/vim-cheat/</link><guid isPermaLink="true">https://tamako-blog.netlify.app/posts/vim-cheat/</guid><description>Use vim in terminal and vscode</description><pubDate>Sat, 10 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://vim.rtorr.com/lang/zh_cn&quot;&gt;Vim Cheat Sheet (rtorr.com)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.barbarianmeetscoding.com/boost-your-coding-fu-with-vscode-and-vim/cheatsheet&quot;&gt;Cheat Sheet (Learn Vim VsCode Ext)&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;basic motion&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;           ↑
     ← h j k l →
         ↓
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;恢复 Normal mode  &lt;code&gt;&amp;lt;ESC&amp;gt;&lt;/code&gt; 、 &lt;code&gt;&amp;lt;CTRL-C&amp;gt;&lt;/code&gt; 或 &lt;code&gt;&amp;lt;CTRL-[&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Cheat for Windows shortkey&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;CTRL-C&amp;gt;&lt;/code&gt; 不再复制，而是返回正常模式。我们在 Vim 中用于复制的命令要简洁得多： &lt;code&gt;y&lt;/code&gt; （用于复制）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;CTRL-V&amp;gt;&lt;/code&gt; 不再粘贴，而是将您带入视觉块模式。同样，我们在 Vim 中用于粘贴的命令不太冗长：只需一个 &lt;code&gt;p&lt;/code&gt; （用于粘贴）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;CTRL-F&amp;gt;&lt;/code&gt; 不再允许您搜索，而是允许您将屏幕向前滚动一页。（front，向前），我们在 Vim 中用于搜索的命令更加触手可及： &lt;code&gt;/{term-i-am-searching-for}&lt;/code&gt; 。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Move Fast Word By Word&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;w&lt;/code&gt;      (&lt;strong&gt;w&lt;/strong&gt;ord) move forward to the beginning of the next word&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;e&lt;/code&gt;      (&lt;strong&gt;e&lt;/strong&gt;nd) move forward to the end of the next word&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;b&lt;/code&gt;      (&lt;strong&gt;b&lt;/strong&gt;ack) move backword to the beginning of the previous word&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ge&lt;/code&gt;     move backword to the end of the previous word&lt;/p&gt;
&lt;hr /&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;W&lt;/code&gt;      (&lt;strong&gt;W&lt;/strong&gt;ord) move forward to the beginning of the next WORD&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;E&lt;/code&gt;      (&lt;strong&gt;E&lt;/strong&gt;nd) move forward to the end of the next WORD&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;B&lt;/code&gt;      (&lt;strong&gt;B&lt;/strong&gt;ack) move backword to the beginning of the pervious WORD&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;gE&lt;/code&gt;     move backword to the end of the previous WORD&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Move To A Special Character In Line&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;f{character}&lt;/code&gt;  (&lt;strong&gt;f&lt;/strong&gt;ind) move forward to the next occurrence of a character in a line&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;t{character}&lt;/code&gt; (un&lt;strong&gt;t&lt;/strong&gt;il) move forward to the next occurrence of a character and place cursor just before it in a line&lt;/p&gt;
&lt;hr /&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;F{character}&lt;/code&gt; (&lt;strong&gt;F&lt;/strong&gt;ind) move backword to the next occurrence of a character in a line&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;T{character}&lt;/code&gt; (un&lt;strong&gt;T&lt;/strong&gt;il) move backword to the next occurrence of a character and place cursor just before it in a line&lt;/p&gt;
&lt;hr /&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;;&lt;/code&gt; go to next occurrnece of {character}&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;,&lt;/code&gt; go to pervious occerrence of {character}&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Move Horizontally Extremely&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;0&lt;/code&gt; move to the first character of a line&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;^&lt;/code&gt; move to the first non-blank character of a line&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;$&lt;/code&gt; move to the end of a line&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;g_&lt;/code&gt; move to the non-blank character at the end of a line&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Move Faster Vertically&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;}&lt;/code&gt; jumps entire paragraphs downwards&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;{&lt;/code&gt; jumps entire paragraphs upwards&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;CTRL-D&lt;/code&gt; move &lt;strong&gt;d&lt;/strong&gt;own half a page by scorlling the page&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;CTRL-U&lt;/code&gt; move &lt;strong&gt;u&lt;/strong&gt;p half a page by scorlling the page&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;High Precision Vertical Motions With Search&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/{pattern}&lt;/code&gt; Search for {pattern} forward. {pattern} is regex&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;?{pattern}&lt;/code&gt; Search for {pattern} backword.&lt;/p&gt;
&lt;hr /&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/&lt;/code&gt; repeat last search forward&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;?&lt;/code&gt; repeat last search backword&lt;/p&gt;
&lt;hr /&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;n&lt;/code&gt; go to next match&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;N&lt;/code&gt; go to pervious match&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Linux Best Practices</title><link>https://tamako-blog.netlify.app/posts/linux-best-practices/</link><guid isPermaLink="true">https://tamako-blog.netlify.app/posts/linux-best-practices/</guid><description>The best practices of linux</description><pubDate>Fri, 09 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;No.1 创建用户并且配置ssh登录&lt;/h2&gt;
&lt;p&gt;预设命题：假设你是一个公司技术负责人，你需要给公司新员工开通服务器账户，并配置好 ssh 登录。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;给 Linux 服务器创建一个新用户，修改新用户创建模板，给新用户自定义好 oh-my-zsh、vim 常用设置。&lt;/li&gt;
&lt;li&gt;给新用户加入指定用户组，授予指定权限（比如 sudo）。&lt;/li&gt;
&lt;li&gt;服务器 sshd 配置设置为仅密钥登录，保证服务器安全性&lt;/li&gt;
&lt;li&gt;生成新用户密钥，并添加到服务器，完成 ssh 密钥登录配置&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;实现：&lt;/p&gt;
&lt;h3&gt;自定义新用户主文件模板&lt;/h3&gt;
&lt;p&gt;Linux 系统中新用户模板位置 &lt;code&gt;/etc/skel/&lt;/code&gt; 主要目标就是自定义这个目录文件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /etc/skel/
ls -lAh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加 &lt;code&gt;.oh-my-zsh&lt;/code&gt; 文件（已经包含了几个常用插件）&lt;/p&gt;
&lt;p&gt;复制 &lt;code&gt;.zshrc&lt;/code&gt; 配置文件，并修改内容&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo cp -r /root/.oh-my-zsh/ /etc/skel/.oh-my-zsh
sudo cp /root/.zshrc /etc/skel/.zshrc
sudo vim .zshrc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;设置所有新用户默认使用 &lt;code&gt;zsh&lt;/code&gt; 。前提：服务器已经安装 &lt;code&gt;zsh&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;修改 &lt;code&gt;/etc/default/useradd&lt;/code&gt; 文件配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo vim /etc/default/useradd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;找到 &lt;code&gt;SHELL=&lt;/code&gt; 行，修改为：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SHELL=/bin/zsh
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;添加新用户并设置群组和密码&lt;/h3&gt;
&lt;p&gt;使用 &lt;code&gt;useradd&lt;/code&gt; 命令添加新用户&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo useradd -m 用户名
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-m&lt;/code&gt; 选项会自动创建用户的主目录，（&lt;code&gt;/home/用户名&lt;/code&gt; ）&lt;/li&gt;
&lt;li&gt;如果不添加 &lt;code&gt;-m&lt;/code&gt; ，需要手动创建主目录。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;设置新用户密码&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo passwd 用户名
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;直接指定用户组&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo useradd -m -G 组名 用户名
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;直接指定用户 ID 和主目录&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo useradd -m -u 1010 -d /自定义路径 用户名
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;直接指定 shell&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo useradd -m -s /bin/bash 用户名
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;验证用户是否创建成功&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;id 用户名
grep 用户名 /etc/passwd
ls -lAh /home/用户名
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;给新用户增加 sudo 权限， 添加新用户到 sudo 用户组&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo usermod -aG sudo 用户名   # Ubuntu/Debian
sudo usermod -aG wheel 用户名  # CentOS/RHEL
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-aG&lt;/code&gt;：表示追加（&lt;code&gt;-a&lt;/code&gt;）到指定组（&lt;code&gt;-G&lt;/code&gt;），避免覆盖现有组。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;删除用户以及其主目录&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo userdel -r 用户名
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;-r&lt;/code&gt; 选项会删除：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用户的主目录，&lt;code&gt;/home/用户名&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;用户的邮件目录， &lt;code&gt;/var/mail/用户名&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;其他和用户相关的文件，比如cron任务，临时文件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以添加 &lt;code&gt;-f&lt;/code&gt; 选项，可以在该用户进程还在运行时强制删除用户，但该进程不会结束，需要 &lt;code&gt;kill&lt;/code&gt; 掉&lt;/p&gt;
&lt;h3&gt;打开服务器 ssh 配置，禁止密码登录&lt;/h3&gt;
&lt;p&gt;修改 sshd 配置文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo vim /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;...

# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication no

...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;解除注释，修改配置项为 &lt;code&gt;no&lt;/code&gt; ，然后重启 &lt;code&gt;sshd&lt;/code&gt; 服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo systemctl restart ssh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;测试配置是否生效&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo sshd -T | grep passwordauthentication
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果输出为 &lt;code&gt;no&lt;/code&gt; ， 表示配置已经加载完成，服务器已经禁用密码登录，只能使用密钥登录&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;配置修改保存并重启服务以后，配置依旧未生效，可能原因：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;某些版本 &lt;code&gt;OpenSSH&lt;/code&gt; 可能存在 &lt;code&gt;/etc/ssh/sshd_config.d/&lt;/code&gt; 配置文件，&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;sudo grep -r &quot;PasswordAuthentication&quot; /etc/ssh/sshd_config.d/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果结果为 &lt;code&gt;yes&lt;/code&gt; 说明这里有配置文件覆盖了之前的配置，修改这里的设置。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;开启了 &lt;code&gt;pam&lt;/code&gt; 需要修改 &lt;code&gt;pam&lt;/code&gt; 配置&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;查看 &lt;code&gt;pam&lt;/code&gt; 中是否有配置接管了 ssh 登录配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo cat /etc/pam.d/sshd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果存在下面类似行，可能会启用密码认证：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;auth       required     pam_password.so
auth       substack     password-auth  # CentOS/RHEL
auth       include      system-auth    # Ubuntu/Debian
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;检查指向的具体配置文件，修改配置，或者注释这里的行。&lt;/p&gt;
&lt;p&gt;或者在 &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; 中强制禁用 &lt;code&gt;pam&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...
UsePAM no
...
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h3&gt;生成密钥，并上传到服务器目录&lt;/h3&gt;
&lt;p&gt;新用户使用 &lt;code&gt;ssh-keygen&lt;/code&gt; 生成密钥&lt;/p&gt;
&lt;p&gt;在可以修改 &lt;code&gt;sshd_config&lt;/code&gt; 的情况下可以直接使用 &lt;code&gt;ssh-copy-id&lt;/code&gt; 直接自动复制到服务器对应位置。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;ssh-copy-id&lt;/code&gt; 是一个快捷脚本，可以把本地 public key 复制 &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; 文件中。但是注意，它需要目前有效验证方式登录到服务器，可以是同用户的其他公钥登录，也可以是密码登录。如果是 root 登录，那么它默认会复制到 root 用户的对应文件中，而不是其他用户的对应文件。可以使用 &lt;code&gt;-t&lt;/code&gt; 修改文件位置。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果使用 root 用户或者其他账户 通过 &lt;code&gt;ssh-copy-id&lt;/code&gt; 复制公钥到服务器时，这时候存在一个问题，他会复制到你当前使用的用户的 &lt;code&gt;$HOME/.ssh/authorized_keys&lt;/code&gt; 文件中，而不是新用户的对应目录，这样新用户依旧无法使用新用户登陆。&lt;/p&gt;
&lt;p&gt;可是使用 &lt;code&gt;-t&lt;/code&gt; 指定目标文件位置，但是主要它需要使用 &lt;code&gt;-f&lt;/code&gt; 强制复制到服务器指定位置，并且需要修改这个脚本生成的 &lt;code&gt;.ssh/authorized_keys&lt;/code&gt; 文件和 &lt;code&gt;.ssh&lt;/code&gt; 文件夹所有权为新用户。&lt;/p&gt;
&lt;p&gt;SSH 对 &lt;code&gt;~/.ssh&lt;/code&gt; 和 &lt;code&gt;authorized_keys&lt;/code&gt; 的权限要求严格：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;~/.ssh&lt;/code&gt; 权限必须为 &lt;code&gt;700&lt;/code&gt;（&lt;code&gt;drwx------&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;authorized_keys&lt;/code&gt; 权限必须为 &lt;code&gt;600&lt;/code&gt;（&lt;code&gt;-rw-------&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;文件所有权为当前目标用户&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;我的实践&lt;/h4&gt;
&lt;p&gt;使用其他账户登录 ssh 服务器&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh myserver
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;进入新用户目录，并创建新文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /home/新用户
mkdir .ssh
touch .ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在本机复制密钥&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat .ssh/xxxxx_id_ed25519.pub | pbcopy
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后手动粘贴到服务器新用户&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;vim /home/新用户/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;修改 &lt;code&gt;.ssh&lt;/code&gt; 和 &lt;code&gt;.ssh/authorized_keys&lt;/code&gt; 文件所有权&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;chown -R 新用户:新用户组 /home/新用户/.ssh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;修改 &lt;code&gt;.ssh&lt;/code&gt; 和 &lt;code&gt;.ssh/authorized_keys&lt;/code&gt; 文件权限&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;chmod 700 /home/新用户/.ssh
chmod 600 /home/新用户/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;测试ssh是否成功登录。&lt;/p&gt;
</content:encoded></item><item><title>SSH and SSH Config</title><link>https://tamako-blog.netlify.app/posts/ssh-and-ssh-config/</link><guid isPermaLink="true">https://tamako-blog.netlify.app/posts/ssh-and-ssh-config/</guid><description>What is SSH ? How we configuration the SSH service ? </description><pubDate>Fri, 09 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;https://www.youtube.com/embed/YS5Zh7KExvE?si=L6s4e5q10To_34Tu&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h2&gt;What is OpenSSH&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;SSH is Secure Shell Protoctl 安全外壳协议&lt;/li&gt;
&lt;li&gt;SSH default prot &lt;code&gt;22&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;OpenSSH is a remote management tool, that gives you access to run commands on another machine.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;First of all&lt;/h3&gt;
&lt;h4&gt;Install&lt;/h4&gt;
&lt;p&gt;On Ubuntu/Debian &lt;code&gt;apt&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt install ssh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But in many cases, ssh and sshd is already installed.&lt;/p&gt;
&lt;h4&gt;Then, Start&lt;/h4&gt;
&lt;p&gt;Start ssh service on systemd. (as server)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl start ssh/sshd
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Ssh and sshd is different. Ssh is the client, sshd is the server.&lt;/p&gt;
&lt;p&gt;In some Linux distributions, the ssh service in systemd is called ssh, and in others it is called sshd, but they actually refer to the daemon process on the ssh server side.&lt;/p&gt;
&lt;p&gt;在一些 linux 发行版本中，ssh 服务叫做 ssh，一些叫做 sshd，但是他们其实指的都是 ssh 服务端的守护进程。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;Basic Use&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;ssh user@ip
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Such As:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh root@192.168.100.1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By default, use password to login.&lt;/p&gt;
&lt;p&gt;When first connect to new server.  ssh will recommind you whether save key fingerprint.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; ssh root@192.168.100.72
 
The authenticity of host &apos;192.168.100.72 (192.168.100.72)&apos; can&apos;t be established.
ED25519 key fingerprint is SHA256:iRUO3p8br5Jhcsd6LkR2pD1W2OxmuoSkALHIFloc8OU.
This host key is known by the following other names/addresses:
    ~/.ssh/known_hosts:13: 192.168.100.12
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added &apos;192.168.100.72&apos; (ED25519) to the list of known hosts.
root@192.168.100.72&apos;s password: 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then 192.168.100.71 and it&apos;s fingerprint will be save in the &lt;code&gt;known_hosts&lt;/code&gt; file. When connect to this ip address again, ssh will auto search in know_hosts file.&lt;/p&gt;
&lt;h5&gt;What is &lt;code&gt;known_hosts&lt;/code&gt; file ?&lt;/h5&gt;
&lt;p&gt;Every time when we connect to a server, it&apos;s going to ask me the first time &quot;Are you sure you want to connect is going to actually show me the fingerprint. And if I say yes, it&apos;s going to save the fingerprint in this file.&lt;/p&gt;
&lt;p&gt;So that way it&apos;s not going to ask me again the next time we go to connect.&lt;/p&gt;
&lt;p&gt;每次链接新服务器时，都会询问是否保存指纹。如果保存，指纹会保存在这个文件中，并且下次登录时，他将不再询问。&lt;/p&gt;
&lt;p&gt;它的作用就是为了安全考虑，当同一个ip地址的指纹发生改变时，&lt;code&gt;ssh&lt;/code&gt; 会提醒你对应ip的指纹已经发生改变，这可以防止你在不知情的情况下出现安全问题。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Once the client verifies and accepts the fingerprint, it is stored in the &lt;code&gt;~/.ssh/known_hosts&lt;/code&gt; file and will be automatically verified when used again.
一旦客户端验证并接受指纹，它就会存储在 &lt;code&gt;~/.ssh/known_hosts&lt;/code&gt; 文件中，并在再次使用时自动进行验证。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;SSH Config&lt;/h2&gt;
&lt;p&gt;Ssh config file is in &lt;code&gt;~/.ssh/config&lt;/code&gt; ,the &lt;code&gt;~&lt;/code&gt; is &lt;code&gt;$HOME&lt;/code&gt; directory. So the file location can also be represented by  &lt;code&gt;$HOME/.ssh/config&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.ssh&lt;/code&gt; directory :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ls -lAh
total 56
-rw-r--r--  1 xrafece  staff   151B Dec 29 19:22 config
-rw-------  1 xrafece  staff   464B Jun 24  2023 id_ed25519_github_xrafece
-rw-r--r--  1 xrafece  staff    98B Jun 24  2023 id_ed25519_github_xrafece.pub
-rw-------  1 xrafece  staff   3.9K Apr 29 10:10 known_hosts
-rw-------  1 xrafece  staff   2.7K Apr 24 16:33 known_hosts.old
-rw-------  1 xrafece  staff   432B Jan 11  2022 podman-machine-default
-rw-r--r--  1 xrafece  staff   116B Jan 11  2022 podman-machine-default.pub
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the config file :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; Host myserver            # ssh server name whatever you want
   Hostname 10.211.55.5   # ip address or domain
   Port 22
   User root              # login user
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then we can use  &lt;code&gt;ssh myserver&lt;/code&gt;  to connect &lt;code&gt;10.211.55.5&lt;/code&gt; use prot &lt;code&gt;22&lt;/code&gt; and user &lt;code&gt;root&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If user is root, on server, we need to change sshd config in &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; .&lt;/p&gt;
&lt;p&gt;Change &lt;code&gt;#PermitRootLogin prohibit-password&lt;/code&gt;  to &lt;code&gt;PermitRootLogin yes&lt;/code&gt; .&lt;/p&gt;
&lt;p&gt;This means permit login ssh on root user.&lt;/p&gt;
&lt;p&gt;这表示允许使用 root 用户登录，原来的 &lt;code&gt;prohibit-password&lt;/code&gt; 表示不允许使用密码登录 root 用户&lt;/p&gt;
&lt;p&gt;When we change ssh config, don&apos;t forget &lt;em&gt;&lt;strong&gt;restart&lt;/strong&gt;&lt;/em&gt; ssh/sshd service.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We can add any amount you want this config item. Such as :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Host myserver
  Hostname 10.211.55.5
  Port 22
  User root
  
Host myserver2           # name unique
  Hostname 10.211.55.6
  Port 22
  User xrafece
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Using SSH Keys&lt;/h2&gt;
&lt;p&gt;Using public/private keys to log in ssh.&lt;/p&gt;
&lt;p&gt;This is important, because it allows we even greater security and also gives we additional convenience.&lt;/p&gt;
&lt;p&gt;In th &lt;code&gt;$HOME/.ssh&lt;/code&gt; directory shown above, there are several files that need attention. Such as &lt;code&gt;id_ed25519_xxxxxxxxxx&lt;/code&gt; and &lt;code&gt;id_ed25519_xxxxxxxxxx.pub&lt;/code&gt; .  The &lt;code&gt;ed25519&lt;/code&gt;  is tht encryption algorithms. First file is the private key, secondly is the public key that name same as first file and end of &lt;code&gt;.pub&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Generate Keys&lt;/h3&gt;
&lt;p&gt;Use &lt;code&gt;ssh-keygen&lt;/code&gt; by itself to generate a brand new key.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh-keygen 

Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/xrafece/.ssh/id_ed25519): /Users/xrafece/.ssh/id_ed25519_pd_ubuntu
Enter passphrase for &quot;/Users/xrafece/.ssh/id_ed25519_pd_ubuntu&quot; (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /Users/xrafece/.ssh/id_ed25519_pd_ubuntu
Your public key has been saved in /Users/xrafece/.ssh/id_ed25519_pd_ubuntu.pub
The key fingerprint is:
SHA256:NOGwgG2OejvymVtBRfYp5EOZgv9aGIPqHXQ1TS06hbA xrafece@Xrafece-MacBook-Air.local
The key&apos;s randomart image is:
+--[ED25519 256]--+
|   +.oOo=..      |
|  o +B+O * .     |
|   *.E* X .      |
|  oo=. * .       |
| o. o=  S        |
|o ....o          |
|....oo           |
|..o=.            |
| o=o             |
+----[SHA256]-----+
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this command :&lt;/p&gt;
&lt;p&gt;The first question is where do we save the key, just press enter to save default location, we need to make sure that we don&apos;t already have a key with the same name before. If we do it&apos;s going to be overwritten which could be very bad, because if that key maybe was our only way into a server.&lt;/p&gt;
&lt;p&gt;The second question is the key passphrase. We can enter the passphrase and again. Now what a passphare is an added layer of security that makes it so that you need to know that passphrase to begin using that key.&lt;/p&gt;
&lt;p&gt;第一个输入的是生成密钥保存的位置，我们要确保没有同名密钥被覆盖。第二个要输入的内容是密钥的密码，该密码保存在本地，它是密钥的又一层安全措施，当密钥被窃取时需要额外输入密码才可以使用。&lt;/p&gt;
&lt;p&gt;Then we see &lt;code&gt;~/.ssh&lt;/code&gt; directory again:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ls -lAh
total 88
-rw-r--r--  1 xrafece  staff   210B Apr 29 20:00 config
-rw-------  1 xrafece  staff   464B Jun 24  2023 id_ed25519_github_xrafece
-rw-r--r--  1 xrafece  staff    98B Jun 24  2023 id_ed25519_github_xrafece.pub
-rw-------  1 xrafece  staff   484B Apr 29 21:08 id_ed25519_pd_ubuntu
-rw-r--r--  1 xrafece  staff   115B Apr 29 21:08 id_ed25519_pd_ubuntu.pub
-rw-------  1 xrafece  staff   4.7K Apr 29 20:13 known_hosts
-rw-------  1 xrafece  staff   4.0K Apr 29 20:02 known_hosts.old
-rw-------  1 xrafece  staff   432B Jan 11  2022 podman-machine-default
-rw-r--r--  1 xrafece  staff   116B Jan 11  2022 podman-machine-default.pub
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We have this file here those two files (&lt;code&gt;id_ed25519_pd_ubuntu&lt;/code&gt; and &lt;code&gt;id_ed25519_pd_ubuntu.pub&lt;/code&gt;) did not exist.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh-keygen -C &quot;comment a message such as name, email&quot; -t rsa
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-C&lt;/code&gt; 添加注释，可以随意填写，默认使用 &lt;code&gt;user@computer name&lt;/code&gt; 建议填写该 ssh 的用途以方便后期进行管理&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-t&lt;/code&gt; means type of key, the possible values are &lt;code&gt;ecdsa&lt;/code&gt;, &lt;code&gt;ecdsa-sk&lt;/code&gt;, &lt;code&gt;ed25519&lt;/code&gt; (the default), &lt;code&gt;ed25519-sk&lt;/code&gt;, or &lt;code&gt;rsa&lt;/code&gt;.  密钥类型（加密算法）可选值从以上几个中选择。
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ed25519&lt;/code&gt; 相比 &lt;code&gt;rsa&lt;/code&gt; 拥有更短的公钥，更安全的算法，更推荐使用。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Name of keys：It is recommended to use &lt;code&gt;xxxx_id_type&lt;/code&gt; or &lt;code&gt;id_type_xxxx&lt;/code&gt; as the key name, which is convenient for checking the key type and purpose.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;More option here: &lt;a href=&quot;https://linux.die.net/man/1/ssh-keygen&quot;&gt;https://linux.die.net/man/1/ssh-keygen&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;Use Keys&lt;/h4&gt;
&lt;p&gt;Then we copy this public key to our server path &lt;code&gt;$HOME/.ssh/authorized_keys&lt;/code&gt; file in a new line.&lt;/p&gt;
&lt;p&gt;Each line in this file is the public key of a key.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat id_ed25519_pd_ubuntu.pub
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ssh root@10.211.55.5
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;vim $HOME/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For me, I use pbcopy comand on my mac :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat id_ed25519_pd_ubuntu.pub | pbcopy
ssh myserver
cd
vim .ssh/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then we need change ssh config, add &lt;code&gt;IdentifyFile&lt;/code&gt; to &lt;code&gt;myserver&lt;/code&gt; item :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Host myserver
  Hostname 10.211.55.5
  Port 22
  User root
  IdentityFile ~/.ssh/id_ed25519_pd_ubuntu
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;If you use default name of ssh key, this step can be omitted, but it is not recommended because the default name is not easy to manage and maintain.&lt;/p&gt;
&lt;p&gt;如果使用默认名称，比如 &lt;code&gt;id_rsa&lt;/code&gt; &lt;code&gt;id_ed25519&lt;/code&gt; 等，这些会包含在默认配置中，所以不再需要修改配置文件指定密钥文件，但是不建议使用这种方式，这样不方便后期对密钥进行管理，除非你只需要一个密钥。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h5&gt;More Better Way&lt;/h5&gt;
&lt;p&gt;We can use command &lt;code&gt;ssh-copy-id&lt;/code&gt;  copy the public key easier.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh-copy-id -i ./id_ed25519_pd_ubuntu.pub myserver
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-i&lt;/code&gt; specify the key file name&lt;/li&gt;
&lt;li&gt;&lt;code&gt;myserver&lt;/code&gt; can also use &lt;code&gt;root@10.211.55.5&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Enter the ssh server user password after the command, and it will copy the specified public key to the &lt;code&gt;authorized_keys&lt;/code&gt; file in the ssh server. Then when you connect to the ssh server, you will use the public key to log in (of course, you need to configure the local ssh config file).&lt;/p&gt;
&lt;p&gt;在命令后输入 ssh 服务器用户密码，它会将指定的公钥复制到 ssh 服务器的 &lt;code&gt;authorized_keys&lt;/code&gt; 文件中。然后在连接 ssh 服务器就会使用公钥登录（当然需要配置好本地 ssh config 文件）。&lt;/p&gt;
&lt;h5&gt;About keys&lt;/h5&gt;
&lt;p&gt;SSH achieves secure transmission through asymmetric encryption. As its named, the public key can be public anywhere.  However, the private key needs to be kept properly. If the private key is leaked, it will be very dangerous to the SSH server. This is also the purpose of adding passphrase operations to the private key to ensure that the private key is not leaked as much as possible.&lt;/p&gt;
&lt;p&gt;ssh 通过不对称加密实现安全传输，公钥如其名称一样，是可以随意公开的。但是私钥需要妥善保管，如果私钥泄露，对 ssh 服务器是很危险。这也是对私钥增加密码操作的目的，尽可能保证私钥不被泄露。&lt;/p&gt;
&lt;h5&gt;Use ssh agent&lt;/h5&gt;
&lt;p&gt;SSH agent will allow you to add the key in memory, and this is especially useful when we connect a server many times.&lt;/p&gt;
&lt;p&gt;First of all, check if it&apos;s running.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ps aux | grep ssh-agent
xrafece          76578   0.0  0.0 426845968    736   ??  S    Thu04PM   0:00.28 /usr/bin/ssh-agent -l
xrafece          70313   0.0  0.0 410059264    144 s000  R+   11:24AM   0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox ssh-agent
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First line means ssh-agent is running on my machine. &lt;strong&gt;If not&lt;/strong&gt; , run this to start ssh agent :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh-agent
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then run :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh-add ./id_ed25519_pd_ubuntu
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mention that this is a &lt;strong&gt;private key&lt;/strong&gt;, not a public key. If we have set a passphrase, enter it next.&lt;/p&gt;
&lt;p&gt;Then we access to server directly , unless shut down the ssh-agent.&lt;/p&gt;
&lt;h2&gt;Configuring OpenSSH&lt;/h2&gt;
&lt;p&gt;This is how to configure the ssh server side.&lt;/p&gt;
&lt;h3&gt;Manage SSH Service On systemd&lt;/h3&gt;
&lt;p&gt;Firsr of all, the &lt;code&gt;status&lt;/code&gt;  is used to view the ssh service status.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl status ssh

● ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (/usr/lib/systemd/system/ssh.service; enabled; preset: enabled)
     Active: active (running) since Wed 2025-04-30 10:07:34 CST; 5h 25min ago
TriggeredBy: ● ssh.socket
       Docs: man:sshd(8)
             man:sshd_config(5)
   Main PID: 76908 (sshd)
      Tasks: 1 (limit: 2206)
     Memory: 3.4M (peak: 19.4M)
        CPU: 593ms
     CGroup: /system.slice/ssh.service
             └─76908 &quot;sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;loaded&lt;/code&gt; display enabled which means that it&apos;s automatically going to start as soon as the server start. If not, we can use &lt;code&gt;enable&lt;/code&gt; to support this.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl enable ssh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the following is to control the start, stop and restart of the ssh service.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl start ssh
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;systemctl restart ssh
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;systemctl stop ssh
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Change Config of SSHd&lt;/h3&gt;
&lt;p&gt;The configuration file is located at &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; .&lt;/p&gt;
&lt;p&gt;This also have a file named &lt;code&gt;/etc/ssh/ssh_config&lt;/code&gt;, &lt;strong&gt;not that&lt;/strong&gt;. That is the ssh client config. That is for global client configuration setting accross the entire distribution. When we use the ssh client it&apos;s actually going to configure itself along with this config file. Our local ssh config file that above will override that. So now we&apos;re not going to focus on that.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;vim /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;...
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We remove the leading &apos;#&apos; sign and change &lt;code&gt;PasswordAuthentication&lt;/code&gt; value &lt;code&gt;yes&lt;/code&gt; to &lt;code&gt;no&lt;/code&gt; which means we can&apos;t use password to login this ssh server.&lt;/p&gt;
&lt;p&gt;在这里禁用使用密码登录选项，增加 ssh 服务器安全性，当然，前提是我们已经配置好密钥登录。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Use Command &lt;code&gt;sshd -T | grep passwordauthentication&lt;/code&gt; to check whether the configuration is effective.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sshd -T&lt;/code&gt; 会显示 SSH 服务的 当前运行时配置。如果它返回 &lt;code&gt;passwordauthentication yes&lt;/code&gt;，说明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1 &lt;code&gt;sshd_config&lt;/code&gt; 中的 &lt;code&gt;PasswordAuthentication&lt;/code&gt; 未被正确设置（可能被注释或覆盖）&lt;/li&gt;
&lt;li&gt;2 PAM 模块强制启用了密码认证（如 &lt;code&gt;/etc/pam.d/sshd&lt;/code&gt; 中有相关配置）&lt;/li&gt;
&lt;li&gt;3 其他 SSH 配置文件覆盖了主配置（如 &lt;code&gt;/etc/ssh/sshd_config.d/*.conf&lt;/code&gt;）&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;There are many more configurations here that can be modified as needed.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;See more: &lt;a href=&quot;https://linux.die.net/man/5/sshd_config&quot;&gt;https://linux.die.net/man/5/sshd_config&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Troubleshotting&lt;/h2&gt;
&lt;p&gt;When we use ssh or config ssh have some trouble, we can try the following ideas.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Firewall&lt;/li&gt;
&lt;li&gt;File permissions&lt;/li&gt;
&lt;li&gt;Analyze logs&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Log files&lt;/h3&gt;
&lt;p&gt;We can take a look at the log files.&lt;/p&gt;
&lt;p&gt;The default of ssh connect log is &lt;code&gt;/var/log/auth.log&lt;/code&gt; ,&lt;/p&gt;
&lt;p&gt;we can use &lt;code&gt;tail -f auth.log&lt;/code&gt; to see what happen when we connect the ssh server.&lt;/p&gt;
&lt;p&gt;Maybe you don&apos;t see that log file in that path. We technically should be using journalctl to follow log files.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;journalctl -u ssh -f
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-u&lt;/code&gt; option is the unit name that just means servive deamon what we want.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-f&lt;/code&gt; option stands for follow mode&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Video: &lt;a href=&quot;https://www.youtube.com/watch?v=YS5Zh7KExvE&quot;&gt;https://www.youtube.com/watch?v=YS5Zh7KExvE&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Page: &lt;a href=&quot;https://tailscale.com/learn/generate-ssh-keys&quot;&gt;https://tailscale.com/learn/generate-ssh-keys&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>JetBrains IDE Initialize Preferences</title><link>https://tamako-blog.netlify.app/posts/jetbrains-ide-initialize-perferences/</link><guid isPermaLink="true">https://tamako-blog.netlify.app/posts/jetbrains-ide-initialize-perferences/</guid><pubDate>Tue, 25 Jul 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Mac OS 和 Windows 环境下对 JetBrains IDE 进行初始选项偏好设置&lt;/p&gt;
&lt;h1&gt;IntelliJ IDEA&lt;/h1&gt;
&lt;h2&gt;Appearance 外观&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./Snipaste_2025-05-20_20-13-20.webp&quot; alt=&quot;appearance&quot; /&gt;&lt;/p&gt;
&lt;p&gt;可以设置 light with light header 主题，让这个界面都保持亮色&lt;/p&gt;
&lt;h2&gt;Presentation Assistant  演示助理（快捷键显示）&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./Snipaste_2025-05-20_20-12-59.webp&quot; alt=&quot;presentation-assistant&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Auto Import 自动导包&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./Snipaste_2025-05-17_20-30-14.webp&quot; alt=&quot;auto-import&quot; /&gt;&lt;/p&gt;
&lt;p&gt;中文界面&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./Snipaste_2025-05-17_20-41-14.webp&quot; alt=&quot;auto-import-zh&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Show Method Separators and WhiteSpaces 显示方法分界线和空格&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./Snipaste_2025-05-17_20-31-12.webp&quot; alt=&quot;show-method-separators-and-whitespace&quot; /&gt;&lt;/p&gt;
&lt;p&gt;中文界面&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./Snipaste_2025-05-17_20-47-51.webp&quot; alt=&quot;show-method-separators-and-whitespace-zh&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Match Case 不区分大小写&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./Snipaste_2025-05-17_20-29-52.webp&quot; alt=&quot;match-case&quot; /&gt;&lt;/p&gt;
&lt;p&gt;中文界面&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./Snipaste_2025-05-17_20-46-05.webp&quot; alt=&quot;match-case-zh&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;File Encodings 文件编码&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./Snipaste_2025-05-17_20-32-14.webp&quot; alt=&quot;file-encodings&quot; /&gt;&lt;/p&gt;
&lt;p&gt;中文界面&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./Snipaste_2025-05-17_20-49-24.webp&quot; alt=&quot;file-encodings-zh&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;File and Code Templates 文件和代码模板&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./Snipaste_2025-05-17_20-33-33.webp&quot; alt=&quot;file-and-code-templates&quot; /&gt;&lt;/p&gt;
&lt;p&gt;中文界面&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./Snipaste_2025-05-17_20-49-40.webp&quot; alt=&quot;file-and-code-templates-zh&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/**
 * @Author ${USER}
 */
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Code and Comment Indent Setting 代码和注释缩进设置&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./Snipaste_2025-05-20_20-13-58.webp&quot; alt=&quot;code-and-comment-indent-setting-1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./Snipaste_2025-05-17_20-35-41.webp&quot; alt=&quot;code-and-comment-indent-setting-2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./Snipaste_2025-05-17_20-36-54.webp&quot; alt=&quot;code-and-comment-indent-setting-3&quot; /&gt;&lt;/p&gt;
&lt;p&gt;中文界面&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./Snipaste_2025-05-17_20-50-26.webp&quot; alt=&quot;code-and-comment-indent-setting-1-zh&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./Snipaste_2025-05-17_20-51-17.webp&quot; alt=&quot;code-and-comment-indent-setting-2-zh&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./Snipaste_2025-05-17_20-53-22.webp&quot; alt=&quot;code-and-comment-indent-setting-3-zh&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Plugins 插件&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Material Theme UI Lite&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;IdeaVim&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Astro&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;GoLand&lt;/h1&gt;
&lt;h2&gt;Auto Import 自动导包&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./image-20230726185727208.webp&quot; alt=&quot;image-20230726185727208&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Match Case 不区分大小写&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./image-20230726190309011.webp&quot; alt=&quot;image-20230726190309011&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Show Method Separators and WhiteSpaces 显示方法分界线和空格&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./image-20230726185956592.webp&quot; alt=&quot;image-20230726185956592&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Comment Setting 注释前添加空格&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./image-20230726190504567.webp&quot; alt=&quot;image-20230726190504567&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Plugins 插件&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Presentation Assistant&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item></channel></rss>