kns Install (Locking Namespace)
Install fzf
- Source Code Install(Recommend)
# Clone the fzf repository
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
# Run the install script
~/.fzf/install
- apt install
sudo apt install fzf
Edit kns Script
vim kns
#!/bin/sh
# quick Kubernetes Namespace Switcher
# ISC Blendle, 2017
set -eu
if [ ! -x "$(which kubectl 2>/dev/null)" ]; then
echo "please install: kubectl (https://kubernetes.io/docs/tasks/kubectl/install/)" >&2
exit 1
fi
if [ ! -x "$(which fzf 2>/dev/null)" ]; then
echo "please install: fzf (https://github.com/junegunn/fzf)" >&2
exit 1
fi
current="$(kubectl config current-context)"
namespace="$(kubectl config view -o jsonpath="{.contexts[?(@.name == '${current}')].context.namespace}")"
if [ -z "$namespace" ]; then
namespace="default"
fi
selected=$( (kubectl get namespaces -o=jsonpath="{.items[?(@.metadata.name!='$namespace')].metadata.name}" | xargs -n 1; echo $namespace ) | fzf -0 -1 --tac -q "${1:-""}" --prompt "$current> ")
if [ -n "$selected" ]; then
kubectl config set-context "$current" "--namespace=$selected" >/dev/null
echo "Set context namespace to \"$selected\""
fi
Add Exec Permission
chmod +x kns
sudo mv kns /usr/local/bin/kns
Leap Year
为什么要设置闰年
四年一闰
百年不闰
四百年又闰
$$ 回归年 = 365 天 5 小时 48 分 46 秒 \approx 365.2422(天) $$
如果不加以调整,那么经过800年,差距为194天,夏天可以过新年:
$$ 0.2422 \times 800 \ \approx 194(天) $$
如何吸收误差
把这些差距转化为以天为单位:
$$ 5 小时 48 分 46 秒 = a = \frac{10463}{43200} = \frac{1}{4 + \frac{1}{7 + \frac{1}{1 + \frac{1}{3 + \frac{1}{5 + \frac{1}{64}}}}}} \approx 0.242199074(天) $$
由a1
可知每4年加一天比较好一些, 故四年一闰。
$$ a_1 = \frac{1}{4} = 0.25(天) $$
由a2
可知每49年加7天比较好一些。
$$ a_2 = \frac{1}{4 + \frac{1}{7}}= \frac{7}{49} \approx 0.2413793(天) $$
由a3
可知每33年加8天比较好一些,那么99年就是24天,故百年不闰。
$$ a_3 = \frac{1}{4 + \frac{1}{7 + \frac{1}{1}}} = \frac{8}{33} \approx 0.2424242(天) $$
由a
的真实值可知,每43200年应该加10463天,但是按照100年加24天的逻辑来算,43200年才加了10368天。
$$ \frac{24}{100} \times 43200 = 10368(天) $$
与真实值间差距为95天。
$$ 10463 - 10368 = 95(天) $$
因为大约40000年少加100天,所以,大约每400年又加1天,故四百年又闰。
按照现在及的计算逻辑,在这43200年中,一共加的天数是:
$$ 10368 + \frac{1}{400} \times 43200 = 10476(天) $$
比实际多加了
$$ 10476 - 10463 = 13(天) $$
解决办法是每3323年减去一个闰年。
$$ \frac{43200}{13} \approx 3323.0769(年) $$
VS-Code Control Remote Hosts
Configure
ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.1.1
Add ssh config
vim ~/.ssh/config
# 添加以下内容
Host ali
HostName 192.168.1.1
User root
IdentityFile ~/.ssh/id_rsa
Port 22
Install VS-Code Plugin
点击VSCode左下角图标,形似“><”,点击会自动安装。
Linux 2FA Authentication
Prepare
-
Install
Google Authenticator
orMicrosoft Authenticator
in your telephone. -
Install
libpam-google-authenticator
in your Linux.
For Debian/Ubuntu:
sudo apt-get install libpam-google-authenticator -y
For CentOS/RHEL:
sudo yum install epel-release -y
sudo yum install libpam-google-authenticator -y
Configure
- Run
google-authenticator
in your Linux.
google-authenticator
- Configure the settings.
-
Do you want authentication tokens to be time-based (y/n) y
-
Then scan the QR code into your phone:
-
Enter code from app (-1 to skip): -1
-
Do you want me to update your "/home/auther/.google_authenticator" file? (y/n) y
In this file you will find the secret key for your authenticator. When your tokens are lost, you can use these token to login in emergency.
- Do you want to disallow multiple uses of the same authentication token? This restricts you to one login about every 30s, but it increases your chances to notice or even prevent man-in-the-middle attacks (y/n) y
您是否要禁止多次使用同一个身份验证令牌?这会限制您每 30 秒登录一次,但这会增加您注意到甚至阻止中间人攻击的机会 (y/n)
- By default, a new token is generated every 30 seconds by the mobile app. In order to compensate for possible time-skew between the client and the server, we allow an extra token before and after the current time. This allows for a time skew of up to 30 seconds between authentication server and client. If you experience problems with poor time synchronization, you can increase the window from its default size of 3 permitted codes (one previous code, the current code, the next code) to 17 permitted codes (the 8 previous codes, the current code, and the 8 next codes). This will permit for a time skew of up to 4 minutes between client and server. Do you want to do so? (y/n) n
默认情况下,移动应用程序每 30 秒生成一个新令牌。 为了补偿客户端和服务器之间可能出现的时间偏差, 我们允许在当前时间之前和之后生成一个额外的令牌。这允许身份验证服务器和客户端之间的时间偏差最多为 30 秒。如果您遇到时间同步不佳的问题,您可以将窗口从默认的 3 个允许代码(一个前一个代码、当前代码、下一个代码)增加到 17 个允许代码(8 个前一个代码、当前代码和 8 个下一个代码)。这将允许客户端和服务器之间的时间偏差最多为 4 分钟。 你想这样做吗?(是/否)
- If the computer that you are logging into isn't hardened against brute-force login attempts, you can enable rate-limiting for the authentication module. By default, this limits attackers to no more than 3 login attempts every 30s. Do you want to enable rate-limiting? (y/n) y
如果您登录的计算机没有针对暴力登录尝试进行强化,您可以为身份验证模块启用速率限制。 默认情况下,这会将攻击者的登录尝试次数限制为每 30 秒不超过 3 次。 是否要启用速率限制?(是/否)
Modify the configuration file
- Edit the configuration file of PAM, enable 2FA.
sudo vim /etc/pam.d/sshd
Add the following lines to the top of the file.
auth required pam_google_authenticator.so
- Edit the configuration file of SSH, enable 2FA.
sudo vim /etc/ssh/sshd_config
- ChallengeResponseAuthentication
ChallengeResponseAuthentication yes
ChallengeResponseAuthentication 是 SSH 服务端(sshd_config)的一个配置选项,用于控制是否启用 质询-响应认证(Challenge-Response Authentication) 机制。 它允许服务器向客户端发送一个或多个“质询”(例如文本提示、验证码请求等),客户端需正确响应才能完成认证。
- UsePAM
UsePAM yes
若 ChallengeResponseAuthentication yes,必须同时启用 UsePAM yes,否则质询无法通过 PAM 模块传递。
- KbdInteractiveAuthentication
KbdInteractiveAuthentication yes
KbdInteractiveAuthentication:控制是否启用键盘交互认证(UI 交互层)。
- AuthenticationMethods
AuthenticationMethods publickey password keyboard-interactive
使用公钥、密码和验证码的方式进行登陆
- Config overview
UsePAM yes
KbdInteractiveAuthentication yes
ChallengeResponseAuthentication yes
PubkeyAuthentication yes
PasswordAuthentication yes
AuthenticationMethods publickey password keyboard-interactive
#PermitEmptyPasswords no
Restart SSH
sudo sshd -t
sudo systemctl restart sshd
Arch linux Init
Modify pacman mirror
sudo vim /etc/pacman.d/mirrorlist
## China
Server = https://mirrors.aliyun.com/archlinux/$repo/os/$arch
Server = http://mirrors.aliyun.com/archlinux/$repo/os/$arch
Server = https://mirrors.tuna.tsinghua.edu.cn/archlinux/$repo/os/$arch
Server = http://mirrors.tuna.tsinghua.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch
Server = http://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.neusoft.edu.cn/archlinux/$repo/os/$arch
Server = http://mirrors.neusoft.edu.cn/archlinux/$repo/os/$arch
Server = http://mirrors.163.com/archlinux/$repo/os/$arch
Server = http://mirrors.bfsu.edu.cn/archlinux/$repo/os/$arch
Server = https://mirrors.bfsu.edu.cn/archlinux/$repo/os/$arch
sudo vim /etc/pacman.conf
[archlinuxcn]
SigLevel = Optional TrustedOnly
Server = https://mirrors.tuna.tsinghua.edu.cn/archlinuxcn/$arch
Server = https://mirrors.ustc.edu.cn/archlinuxcn/$arch
Server = https://mirrors.aliyun.com/archlinuxcn/$arch
sudo pacman -Syy
sudo pacman -S yay base-devel tree neofetch git
Install firefox
sudo pacman -S firefox
Install font
sudo pacman -S noto-fonts noto-fonts-cjk noto-fonts-emoji noto-fonts-extra ttf-dejavu ttf-liberation
Modify locale
sudo vim /etc/locale.gen
zh_CN.UTF-8 UTF-8
su
locale-gen && echo LANG=zh_CN.UTF-8 > /etc/locale.conf
exit
Install google-pinyin input method
sudo pacman -S archlinuxcn-keyring
sudo pacman -S fcitx5-im
sudo pacman -S fcitx5-chinese-addons
sudo pacman -S fcitx5-qt fctitx5-gtk fcitx5-lua
Modify environment
sudo vim /etc/environment
GTK_IM_MODULE=fcitx
QT_IM_MODULE=fcitx
XMODIFIERS=@im=fcitx
SDL_IM_MODULE=fcitx
GLFM_IM_MODULE=ibus
Fix japan-font problem
Ref:Arch 简体中文本地化
Create a new file named 64-language-selector-prefer.conf.
cd /etc/fonts/conf.d/ && \
sudo vim 64-language-selector-prefer.conf
Add the following code:
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<alias>
<family>sans-serif</family>
<prefer>
<family>Noto Sans CJK SC</family>
<family>Noto Sans CJK TC</family>
<family>Noto Sans CJK JP</family>
</prefer>
</alias>
<alias>
<family>monospace</family>
<prefer>
<family>Noto Sans Mono CJK SC</family>
<family>Noto Sans Mono CJK TC</family>
<family>Noto Sans Mono CJK JP</family>
</prefer>
</alias>
</fontconfig>
Auth fprint login
Ref:Arch 添加指纹登陆
sudo pacman -S fprintd
Edit system-local-login
file in /etc/pam.d/
.
sudo vim /etc/pam.d/system-local-login
Add following lines at the top of the file:
auth sufficient pam_unix.so try_first_pass likeauth nullok
auth sufficient pam_fprintd.so
Edit kde
file in /etc/pam.d/
.
sudo vim /etc/pam.d/kde
Add following lines at the top of the file:
auth sufficient pam_unix.so try_first_pass likeauth nullok
auth sufficient pam_fprintd.so
Keyboard Layout
Switch to colemak layout.
setxkbmap us -variant colemak
Switch to QWERTY
layout.
setxkbmap us; xset -r 66
Disable Hibernate When Close Laptop
Edit Conf File
sudo gedit /etc/systemd/logind.conf
Modify Line
HandleLidSwitch=ignore
Restart Service
sudo systemctl restart systemd-logind
Ollama Service Discovery
Editing the systemd service file
sudo vim /etc/systemd/system/ollama.service
Add ENV under [Service] Item
[Service]
Environment="OLLAMA_HOST=0.0.0.0"
Reload and Restart
sudo systemctl daemon-reload
sudo systemctl restart ollama
ZSH
zsh is a shell that can be used as a replacement for bash.
Installation
https://github.com/ohmyzsh/ohmyzsh/wiki/Installing-ZSH
sudo apt install zsh
Configuration
chsh -s $(which zsh) $USER
Make it works, you can logout
system and relogin again.
Zsh & Oh-my-zsh
Git repo
https://github.com/ohmyzsh/ohmyzsh
Installation
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
The default location is ~/.oh-my-zsh
(hidden in your home directory, you can access it with cd ~/.oh-my-zsh
)
Manual Installation
If you want to change the location, you can do so by setting the ZSH
environment variable before installing:
Firstly, install the install script:
wget https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh
Secondly, setting the install path run the install script, if you want to install oh-my-zsh to $HOME/awesome-shell/oh-my-zsh
:
ZSH="$HOME/awesome-shell/oh-my-zsh" sh install.sh
Powerlevel10K
https://github.com/romkatv/powerlevel10k.git
Installation
- Clone repo into oh-my-zsh custom themes path:
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k
- Modify
.zshrc
:
ZSH_THEME="powerlevel10k/powerlevel10k"
- Exit terminal and reopen it.
Zsh-autosuggestions
https://github.com/zsh-users/zsh-autosuggestions/blob/master/INSTALL.md
Installation
- Clone this repository into
$ZSH_CUSTOM/plugins
(by default~/.oh-my-zsh/custom/plugins
)
git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
- Add the plugin to the list of plugins for Oh My Zsh to load (inside
~/.zshrc
):
plugins=(
# other plugins...
zsh-autosuggestions
)
Zsh-autocomplete
https://github.com/marlonrichert/zsh-autocomplete
Installation
- Clone this repository into
$ZSH_CUSTOM/plugins
(by default~/.oh-my-zsh/custom/plugins
)
git clone --depth 1 -- https://github.com/marlonrichert/zsh-autocomplete.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autocomplete
- Add the plugin to the list of plugins for Oh My Zsh to load (inside
~/.zshrc
):
plugins=(
# other plugins...
zsh-autocomplete
)
Zsh-syntax-highlighting
https://github.com/zsh-users/zsh-syntax-highlighting
Installation
-
- Clone this repository into
$ZSH_CUSTOM/plugins
(by default~/.oh-my-zsh/custom/plugins
)
- Clone this repository into
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
- Add the plugin to the list of plugins for Oh My Zsh to load (inside
~/.zshrc
):
plugins=(
# ...
zsh-syntax-highlighting
)
Zsh-you-should-use
Installation
- Clone the repo into your oh-my-zsh plugins directory.
git clone https://github.com/MichaelAquilina/zsh-you-should-use.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/you-should-use
- Add
you-should-use
to the list of plugins in your~/.zshrc
file.
plugins=(
# other plugins...
you-should-use
)
Zsh-ollama-completion
https://github.com/Katrovsky/zsh-ollama-completion
Installation
- Clone this repository into
$ZSH_CUSTOM/plugins
(by default~/.oh-my-zsh/custom/plugins
)
git clone https://github.com/Katrovsky/zsh-ollama-completion.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/ollama
- Add the plugin to the list of plugins for Oh My Zsh to load (inside
~/.zshrc
):
plugins=(
# ...
ollama
)
Auto-Venv
Auto-activate Virtual Environments in Python Projects
- Clone this repository into
$ZSH_CUSTOM/plugins
(by default~/.oh-my-zsh/custom/plugins
)
git clone https://github.com/lxp731/auto-venv $ZSH_CUSTOM/plugins/auto-venv
- Add
auto-venv
to the plugins array in your~/.zshrc
file
plugins=(
...
auto-venv
)
FZF Hotkey
Auto-activate Virtual Environments in Python Projects
- Clone this repository into
$ZSH_CUSTOM/plugins
(by default~/.oh-my-zsh/custom/plugins
)
git clone https://github.com/lxp731/fzf-hotkey $ZSH_CUSTOM/plugins/fzf-hotkey
- Add
fzf-hotkey
to the plugins array in your~/.zshrc
file
plugins=(
...
fzf-hotkey
)
FZF
Official Website
Install
# Clone the fzf repository
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
# Run the install script
~/.fzf/install
Setting .bashrc
A basic example, to show how to link progress with fzf.
# add a alias to change git branch
alias gcb="git branch | fzf --preview 'git show --color=always {-1}' \
--bind 'enter:become(git checkout {-1})' \
--height 60% --layout reverse"
Then, setting ENV vars of fzf, unlock advanced function.
# fzf init
eval "$(~/.fzf/bin/fzf --bash)"
[ -f ~/.fzf.bash ] && source ~/.fzf.bash
Default fzf self build-in Ctrl+R to display history cmd, Ctrl+T to show files and dirs of local path, Alt+C to exec cd
cmd. Well, you can rewrite these function.
# CTRL-Y to copy the command into clipboard using pbcopy
export FZF_CTRL_R_OPTS="
--bind 'ctrl-y:execute-silent(echo -n {2..} | pbcopy)+abort'
--color header:italic
--header 'Press CTRL-Y to copy command into clipboard'
--height 80% --layout reverse"
# Preview file content using bat (https://github.com/sharkdp/bat)
export FZF_CTRL_T_OPTS="
--walker-skip .git,node_modules,target
--preview 'batcat -n --color=always {}'
--bind 'ctrl-/:change-preview-window(down|hidden|)'
--height 80% --layout reverse"
# Print tree structure in the preview window
export FZF_ALT_C_OPTS="
--walker-skip .git,node_modules,target
--preview 'tree -C {}'
--height 80% --layout reverse"
# ripgrep->fzf->vim [QUERY]
# sudo apt install -y ripgrep
rfv() (
RELOAD='reload:rg --column --color=always --smart-case {q} || :'
OPENER='if [[ $FZF_SELECT_COUNT -eq 0 ]]; then
vim {1} +{2} # No selection. Open the current line in Vim.
else
vim +cw -q {+f} # Build quickfix list for the selected items.
fi'
fzf --disabled --ansi --multi \
--bind "start:$RELOAD" --bind "change:$RELOAD" \
--bind "enter:become:$OPENER" \
--bind "ctrl-o:execute:$OPENER" \
--bind 'alt-a:select-all,alt-d:deselect-all,ctrl-/:toggle-preview' \
--delimiter : \
--preview 'batcat --style=full --color=always --highlight-line {2} {1}' \
--preview-window '~4,+{2}+4/3,<80(up)' \
--query "$*"
)
In fzf model, you can press Esc to quit fzf model.
FZF Replace Bash Completion
Github Repo
https://github.com/lincheney/fzf-tab-completion
Install Script
mkdir -p ~/.fzf/shell && \
wget -O ~/.fzf/shell/fzf-bash-completion.sh \
https://raw.githubusercontent.com/lincheney/fzf-tab-completion/refs/heads/master/bash/fzf-bash-completion.sh
Modify .bashrc
cat >> ~/.bashrc << EOF
# use fzf replace system completion
source ~/.fzf/shell/fzf-bash-completion.sh
bind -x '"\t": fzf_bash_completion'
EOF
source ~/.bashrc
FZF Integrate Git
Github Repo
https://github.com/junegunn/fzf-git.sh
Install
mkdir -p ~/.fzf/shell && \
cd ~/.fzf/shell && \
wget https://raw.githubusercontent.com/junegunn/fzf-git.sh/refs/heads/main/fzf-git.sh
Modify .bashrc
cat >> ~/.bashrc << EOF
# fzf integrade git
source ~/.fzf/shell/fzf-git.sh
EOF
source ~/.bashrc
CI & CD
Overview
CI/CD, which stands for continuous integration and continuous delivery/deployment, aims to streamline and accelerate the software development lifecycle.
Continuous integration (CI) refers to the practice of automatically and frequently integrating code changes into a shared source code repository. Continuous delivery and/or deployment (CD) is a 2 part process that refers to the integration, testing, and delivery of code changes. Continuous delivery stops short of automatic production deployment, while continuous deployment automatically releases the updates into the production environment.
Why is CI/CD important?
CI/CD helps organizations avoid bugs and code failures while maintaining a continuous cycle of software development and updates.
As apps grow larger, features of CI/CD can help decrease complexity, increase efficiency, and streamline workflows.
Because CI/CD automates the manual human intervention traditionally needed to get new code from a commit into production, downtime is minimized and code releases happen faster. And with the ability to more quickly integrate updates and changes to code, user feedback can be incorporated more frequently and effectively, meaning positive outcomes for end users and more satisfied customers overall.
Classic CI/CD Script
variables:
$CI_REGISTRY: habor.dcits.auto
$CI_REGISTRY_IMAGE: liuxp731/webui
stages:
- test
- build
- deploy
run_test:
stage: test
image: python:3.9-slim-buster
before_script:
- apt-get update && apt-get install -y make
script:
- make test
build_image:
stage: build
image: docker:20.10.16
services:
- docker:20.10.16-dind
variables:
DOCKER_TLS_CERTDIR: "/certs"
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
deploy:
stage: deploy
before_script:
- chmod 400 $SSH_KEY
script:
- ssh -o StrictHostKeyChecking=no -i $SSH_KEY $SSH_USER@$SSH_HOST "
docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY &&
docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA &&
docker ps -a | xargs docker stop | xargs docker rm &&
docker run -dit -p 5000:5000 $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
"
Jenkins CI
Jenkins Variables
Jenkins 提供了许多内置变量,可以用来生成唯一的镜像标签。常用的变量包括:
-
BUILD_ID:当前构建的唯一 ID。
-
BUILD_NUMBER:当前构建的编号(每次构建递增)。
-
GIT_COMMIT:当前 Git 提交的 SHA-1 哈希值(前 7 位即可)。
-
BRANCH_NAME:当前 Git 分支的名称。
Classic Jenkinsfile Example
pipeline {
environment {
// DOCKER_IMAGE_TAG = "${env.GIT_COMMIT.substring(0, 7)}"
DOCKER_IMAGE_TAG = "0.${env.BUILD_NUMBER}"
DOCKER_IMAGE = "harbor.frombyte.auto/library/my-nginx:${DOCKER_IMAGE_TAG}"
REGISTRY_CREDENTIAL = '53464224-8c68-45a8-adb1-e8974d14e122'
}
agent {
node {
label 'rancher'
}
}
stages {
stage('Check Tools Version') {
steps {
sh 'git --version'
sh 'docker --version'
}
post {
failure {
echo "Error: Failed to check tools version!"
}
}
}
stage('Prepare') {
steps {
sh '''
if [ ! -d "automation" ]; then
git clone https://gitea.tryanks.com/burgess/automation.git
cd automation
else
cd automation
git fetch --all
git reset --hard origin/main
fi
'''
}
post {
failure {
echo "Error: Failed to prepare the repository!"
}
}
}
stage('Build') {
steps {
sh 'cd automation && docker build -t ${DOCKER_IMAGE} .'
}
post {
failure {
echo "Error: Failed to build the Docker image!"
}
}
}
stage('Push') {
steps {
withCredentials([usernamePassword(
credentialsId: "${REGISTRY_CREDENTIAL}",
usernameVariable: 'HARBOR_USERNAME',
passwordVariable: 'HARBOR_PASSWORD'
)]) {
sh '''
docker login -u ${HARBOR_USERNAME} -p ${HARBOR_PASSWORD} harbor.frombyte.auto
docker push ${DOCKER_IMAGE}
docker logout
'''
}
}
post {
failure {
echo "Error: Failed to push the Docker image!"
}
}
}
}
post {
always {
sh 'docker rmi ${DOCKER_IMAGE} || true'
}
failure {
echo "Pipeline failed! Check the logs for more details."
}
success {
echo "Pipeline succeeded!"
}
}
}
ENV Variable Setting
In Linux, environment variables are used to store information that can be used by programs when they are executed. They play a important role in Linux system.
.bashrc Configuration
# 设置shell命令查找
set -o vi
# 设置Ctrl+L清屏
bind -x '"\C-l":clear'
# helm complete
source <(helm completion bash)
source <(kubectl completion bash)
# alias kubectl & setting completion
alias k=kubectl
complete -o default -F __start_kubectl k
# highlight version cat
alias dog='highlight -O ansi'
# more high-level cat
alias cat='batcat'
# fzf change git branch
alias gcb="git branch | fzf --preview 'git show --color=always {-1}' \
--bind 'enter:become(git checkout {-1})' \
--height 60% --layout reverse"
# Auto-activate uv venv
PROJECT_PATH=""
CURRENT_PATH=""
auto_activate() {
local NEW_PATH=$(pwd)
# 只有在路径改变时才进行检查
if [[ "$NEW_PATH" != "$CURRENT_PATH" ]]; then
CURRENT_PATH="$NEW_PATH"
if [[ -z "$PROJECT_PATH" ]]; then
if [ -d ".venv" ]; then
source .venv/bin/activate
PROJECT_PATH="$CURRENT_PATH"
fi
else
if [[ "$CURRENT_PATH" == "$PROJECT_PATH"* ]]; then
return
else
if [[ -n "$VIRTUAL_ENV" ]]; then
deactivate
fi
PROJECT_PATH=""
fi
fi
fi
}
PROMPT_COMMAND=auto_activate
Modify .user-dirs.dirs
Update the Contents
XDG_DESKTOP_DIR="$HOME/desktop"
XDG_DOCUMENTS_DIR="$HOME/document"
XDG_DOWNLOAD_DIR="$HOME/download"
XDG_MUSIC_DIR="$HOME/music"
XDG_PICTURES_DIR="$HOME/picture"
XDG_PUBLICSHARE_DIR="$HOME/public"
XDG_TEMPLATES_DIR="$HOME/template"
XDG_VIDEOS_DIR="$HOME/video"
Update the Folder Names of Home Path
mv 桌面/ desktop
mv 文档/ document
mv 下载/ download
mv 音乐/ music
mv 图片/ picture
mv 公共/ public
mv 模板/ template
mv 视频/ video
Reboot
reboot
Vim Plugin Manager
Official Website
https://github.com/junegunn/vim-plug?tab=readme-ov-file
Install vim-plug
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
Modify .vimrc
Add the following content:
call plug#begin('~/.vim/plugged')
" List your plugins here
Plug 'tpope/vim-sensible'
call plug#end()
You can add any plugins in the middle of call plug.
Reload the file or restart Vim, then you can:
:PlugInstall
to install the plugins:PlugUpdate
to install or update the plugins:PlugDiff
to review the changes from the last update:PlugClean
to remove plugins no longer in the list
Vim Tips
Add Contents in Lines Head
- In normal mode, press
Ctrl-v
into visual-block mode. - Select the lines you want to add contents, press
I
to enter insert mode. - Edit the contents, press
Esc
to exit insert mode, and else lines will be added automatically.
Add Contents in Lines Tail
- In normal mode, press
g
andv
, that will help us to select all contents in the file. - Then press
$
to jump to the end of the line. PressA
to enter insert mode. - Edit the contents, press
Esc
to exit insert mode, and else lines will be added automatically.
Vim Record and Playback
- In normal mode, press
q
anda
to start recording.(a means the name of the recording, you can use any letter) - Then press
i
to enter insert mode, and edit the contents. - Press
Esc
to exit insert mode, and pressq
to stop recording. - In normal mode, press
@
anda
to playback the recording.
Note: When you ending the recording, ensure you cursor is at the head of the next line. Certainly, you can use
10@a
to playback the recording 10 times.
Force Save File
Sometimes, you may edit a file in vim, but you don't use sudo
. However, you need not to edit it again. You can use fllowing command to save the file:
:w !sudo tee %
Jump Quickly
-
In normal mode, press
Ctrl-o
to jump to the previous position. PressCtrl-i
to jump to the next position. Samely, they can jump each other between two files. -
In normal mode, press
gf
to jump to the file which the cursor is pointing to. -
In normal mode, press
gx
to open the url which the cursor is pointing to.
Confgure .vimrc
My .vimrc
"===
"===编写脚本自动插入
"===
function AddTitleForShell()
call append(0,"#!/bin/bash")
call append(1,"# **********************************************************")
call append(2,"# * Author : Burgess Leo")
call append(3,"# * Email : liuxp731@qq.com")
call append(4,"# * Create time : ".strftime("%Y-%m-%d %H:%M"))
call append(5,"# * Filename : ".expand("%:t"))
call append(6,"# * Description : ")
call append(7,"# **********************************************************")
endfunction
autocmd BufNewFile *.sh call AddTitleForShell()
"===
"===Sync my plugins setting
"===
if empty(glob('~/.vim/autoload/plug.vim'))
silent !curl -fLo ~/.vim/autoload/plug.vim --create-dirs
\ https://raw.githubusercontent.com/lxp731/topazleaves/refs/heads/main/src/mdbook-files/plug.vim
autocmd VimEnter * PlugInstall --sync | source $MYVIMRC
endif
"===
"===System Setting
"===
let mapleader=" "
set nocompatible
set showcmd
set mouse=a
set clipboard=unnamed
vnoremap Y :w !xclip -i -sel c<CR>
filetype on
filetype indent on
filetype plugin on
filetype plugin indent on
"set laststatus=2
set autochdir
set dictionary+=/usr/share/dict/words
"autocmd InsertLeave * write
"autocmd FocusLost * if &modified | write | endif
"===
"===Open the vimrc anytime
"===
noremap <LEADER>rc :e ~/.vimrc<CR>
map <LEADER>fd /\(\<\w\+\>\)\_s*\1
"===
"===Show command autocomplete
"===
set wildignore=log/**,node_modules/**,target/**,tmp/**,*.rbc
set wildmenu
set wildmode=longest,list,full
"===
"===Search Setting
"===
set hlsearch
exec "nohlsearch"
set incsearch
set ignorecase
set smartcase
"===
"===Code Display
"===
set encoding=UTF-8
syntax on
set number
set relativenumber
set cursorline
let &t_ut=''
"===
"===Tab behavior
"===
set expandtab
set tabstop=2
set shiftwidth=2
set softtabstop=2
set list
set listchars=tab:▸\ ,trail:▫
set scrolloff=5
"===
"===Prevent auto line split
"===
set tw=0
set wrap
set indentexpr=
set backspace=indent,eol,start
set foldmethod=indent
set foldlevel=99
"===
"===快捷键映射
"===
nnoremap <LEADER><CR> :nohlsearch<CR>
nnoremap s <nop>
nnoremap S :w<CR>
nnoremap R :source $MYVIMRC<CR>
nnoremap XX :q!<CR>
nnoremap j k
nnoremap k j
nnoremap = nzz
nnoremap - Nzz
nnoremap W 5w
nnoremap B 5b
nnoremap <C-j> :belowright term<CR>
"===
"===Edit mode shortkey
"===
inoremap <C-z> <C-o>u
inoremap <C-l> <C-o>o
inoremap <C-S-k> <Esc>ddi
inoremap <C-y> <Esc>:normal! yyp<CR>a
inoremap <C-s> <Esc>:w<CR>i
"===
"===Line Moving
"===
nnoremap <A-Down> ddp
nnoremap <A-Up> dd2kp
inoremap <A-Up> <Esc>ddkPgi
inoremap <A-Down> <Esc>ddjPgi
"===
"===Words spell Checking
"===
map <LEADER>pl :set spell!<CR>
nnoremap <C-x> ea<C-x>s
inoremap <C-x> <Esc>ea<C-x>s
"===
"===分割窗口
"===
nnoremap sl :set splitright<CR>:vsplit<CR>
nnoremap snl :set nosplitright<CR>:vsplit<CR>
nnoremap sk :set splitbelow<CR>:split<CR>
nnoremap snk :set nosplitbelow<CR>:split<CR>
nnoremap <LEADER>l <C-w>l
nnoremap <LEADER>h <C-w>h
nnoremap <LEADER>j <C-w>k
nnoremap <LEADER>k <C-w>j
nnoremap <C-Up> :res +2<CR>
nnoremap <C-Down> :res -2<CR>
nnoremap <C-Left> :vertical resize-2<CR>
nnoremap <C-Right> :vertical resize+2<CR>
map <LEADER>sv <C-w>t<C-w>H
map <LEADER>sh <C-w>t<C-w>K
"===
"===Tab Management
"===
nnoremap th :tabprevious<CR>
nnoremap tl :tabnext<CR>
nnoremap to :tabclose<CR>
nnoremap tq :tabfirst<CR>
nnoremap tp :tablast<CR>
" Insert mode mappings
"inoremap tl <C-O>:tabnext<CR>
"inoremap th <C-O>:tabprevious<CR>
"inoremap tq <C-O>:tabfirst<CR>
"inoremap tp <C-O>:tablast<CR>
"===
"===保存VIM光标位置
"===
augroup remember_last_cursor_position
autocmd!
autocmd BufWritePost * mkview
autocmd BufReadPost * if line("'\"") > 0 && line("'\"") <= line("$") | exe "normal g`\"" | endif
augroup END
"===
"===VIM 插件管理器
"===
call plug#begin('~/.vim/plugged')
Plug 'sheerun/vim-polyglot'
Plug 'connorholyday/vim-snazzy'
" File navigation
Plug 'preservim/nerdtree'
Plug 'Xuyuanp/nerdtree-git-plugin'
" Taglist
Plug 'preservim/tagbar'
" Error checking
Plug 'dense-analysis/ale'
" Auto Complete
Plug 'Valloric/YouCompleteMe'
" Undo Tree
Plug 'mbbill/undotree'
" Other visual enhancement
Plug 'nathanaelkane/vim-indent-guides'
Plug 'itchyny/vim-cursorword'
" Git
Plug 'rhysd/conflict-marker.vim'
Plug 'tpope/vim-fugitive'
Plug 'mhinz/vim-signify'
Plug 'gisphm/vim-gitignore', { 'for': ['gitignore', 'vim-plug'] }
" HTML, CSS, JavaScript, PHP, JSON, etc.
Plug 'elzr/vim-json'
Plug 'hail2u/vim-css3-syntax'
Plug 'spf13/PIV', { 'for' :['php', 'vim-plug'] }
Plug 'gko/vim-coloresque', { 'for': ['vim-plug', 'php', 'html', 'javascript', 'css', 'less'] }
Plug 'pangloss/vim-javascript', { 'for' :['javascript', 'vim-plug'] }
Plug 'mattn/emmet-vim'
" Python
Plug 'vim-scripts/indentpython.vim'
Plug 'linux-cultist/venv-selector.nvim'
" Markdown
Plug 'iamcco/markdown-preview.nvim', { 'do': { -> mkdp#util#install_sync() }, 'for' :['markdown', 'vim-plug'] }
Plug 'dhruvasagar/vim-table-mode', { 'on': 'TableModeToggle' }
Plug 'vimwiki/vimwiki'
" Bookmarks
Plug 'kshenoy/vim-signature'
" Other useful utilities
Plug 'terryma/vim-multiple-cursors'
Plug 'junegunn/goyo.vim' " distraction free writing mode
Plug 'tpope/vim-surround' " type ysks' to wrap the word with '' or type cs'` to change 'word' to `word`
Plug 'godlygeek/tabular' " type ;Tabularize /= to align the =
Plug 'gcmt/wildfire.vim' " in Visual mode, type i' to select all text in '', or type i) i] i} ip
Plug 'scrooloose/nerdcommenter' " in <space>cc to comment a line
" Dependencies
Plug 'MarcWeber/vim-addon-mw-utils'
Plug 'kana/vim-textobj-user'
Plug 'fadein/vim-FIGlet'
" commenter
Plug 'preservim/nerdcommenter'
call plug#end()
"===
"===Snazzy Setting
"===
map <LEADER>c1 :set background=dark<CR>:colorscheme snazzy<CR>:AirlineTheme drak<CR>
map <LEADER>c2 :set background=light<CR>:colorscheme sorbet<CR>:AirlineTheme dark<CR>
let g:SnazzyTransparent = 1
color sorbet
"color snazzy
"color slate
"color desert
"color industry
"color evening
"color habamax
"color peachpuff
"color elflord
"color pablo
"color murphy
"color lunaperche
"color koehler
"===
"===NERDTree Setting
"===
"Start NERDTree when Vim starts with a directory argument.
autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 1 && isdirectory(argv()[0]) && !exists('s:std_in') |
\ execute 'NERDTree' argv()[0] | wincmd p | enew | execute 'cd '.argv()[0] | endif
"Close the tab if NERDTree is the only window remaining in it.
autocmd BufEnter * if winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | quit | endif
nnoremap <C-t> :NERDTreeToggle<CR>
"nnoremap <C-n> :NERDTree<CR>
"nnoremap <C-f> :NERDTreeFind<CR>
"nnoremap <leader>n :NERDTreeFocus<CR>
" ===
" === NERDTree-git
" ===
"let g:NERDTreeGitStatusUseNerdFonts = 1
let g:NERDTreeGitStatusIndicatorMapCustom = {
\ 'Modified' :'✹',
\ 'Staged' :'✚',
\ 'Untracked' :'✭',
\ 'Renamed' :'➜',
\ 'Unmerged' :'═',
\ 'Deleted' :'✖',
\ 'Dirty' :'✗',
\ 'Ignored' :'☒',
\ 'Clean' :'✔︎',
\ 'Unknown' :'?',
\ }
" ===
" === Tagbar
" ===
" nmap <F8> :TagbarToggle<CR>
"===
"===ALE
"===
" let g:ale_fixers = {
" \ '*': ['remove_trailing_lines', 'trim_whitespace'],
" \ 'javascript': ['eslint'],
" \}
" let g:ale_fix_on_save = 1
" call deoplete#custom#option('sources', {
" \ '_': ['ale', 'foobar'],
" \})
" let g:ale_completion_enabled = 1
"===
"===Markdown Preview
"===
let g:mkdp_auto_start = 0
let g:mkdp_auto_close = 1
let g:mkdp_refresh_slow = 0
let g:mkdp_command_for_global = 0
let g:mkdp_open_to_the_world = 0
let g:mkdp_open_ip = ''
let g:mkdp_browser = ''
let g:mkdp_echo_preview_url = 0
let g:mkdp_browserfunc = ''
let g:mkdp_preview_options = {
\ 'mkit': {},
\ 'katex': {},
\ 'uml': {},
\ 'maid': {},
\ 'disable_sync_scroll': 0,
\ 'sync_scroll_type': 'middle',
\ 'hide_yaml_meta': 1
\ }
let g:mkdp_markdown_css = ''
let g:mkdp_highlight_css = ''
let g:mkdp_page_title = '「${name}」'
let g:mkdp_port = '3001'
let g:mkdp_theme = 'light' "dark OR light
" combine preview window
" ensure to set let g:mkdp_auto_close = 0 if you have enable this option
let g:mkdp_combine_preview = 0
" auto refetch combine preview contents when change markdown buffer
" only when g:mkdp_combine_preview is 1
let g:mkdp_combine_preview_auto_refresh = 1
noremap mp :MarkdownPreview<CR>
noremap ms :MarkdownPreviewStop<CR>
"===
"===MarkdownEdit
"===
autocmd Filetype markdown inoremap ,1 #<Space><Enter><++><Esc>kA
autocmd Filetype markdown inoremap ,2 ##<Space><Enter><++><Esc>kA
autocmd Filetype markdown inoremap ,3 ###<Space><Enter><++><Esc>kA
autocmd Filetype markdown inoremap ,4 ####<Space><Enter><++><Esc>kA
autocmd Filetype markdown inoremap ,5 #####<Space><Enter><++><Esc>kA
autocmd Filetype markdown inoremap ,6 ######<Space><Enter><++><Esc>kA
autocmd Filetype markdown inoremap ,f <Esc>/<++><CR>:nohlsearch<CR>c4l
autocmd Filetype markdown inoremap ,b **** <++><Esc>F*hi
autocmd Filetype markdown inoremap ,i ** <++><Esc>F*i
autocmd Filetype markdown inoremap ,s ~~~~ <++><Esc>F~hi
autocmd Filetype markdown inoremap ,d `` <++><Esc>F`i
autocmd Filetype markdown inoremap ,c ```<Enter><++><Enter>```<Enter><Enter><++><Esc>4kA
autocmd Filetype markdown inoremap ,a [](<++>) <++><Esc>F[a
autocmd Filetype markdown inoremap ,p  <++><Esc>F[a
function! CreateTable(num_cols)
let col_str = repeat('|<++>', a:num_cols) . '|'
let separator = repeat('|:----:', a:num_cols) . '|'
let result = col_str . "\n" . separator . "\n" . col_str
return result
endfunction
autocmd Filetype markdown inoremap ,t2 <Esc>i<C-R>=CreateTable(2)<CR><Esc>^3klc5l
autocmd Filetype markdown inoremap ,t3 <Esc>i<C-R>=CreateTable(3)<CR><Esc>^3klc5l
autocmd Filetype markdown inoremap ,t4 <Esc>i<C-R>=CreateTable(4)<CR><Esc>^3klc5l
autocmd Filetype markdown inoremap ,t5 <Esc>i<C-R>=CreateTable(5)<CR><Esc>^3klc5l
autocmd Filetype markdown inoremap ,t6 <Esc>i<C-R>=CreateTable(6)<CR><Esc>^3klc5l
" autocmd Filetype markdown inoremap ,t3 \|<++>\|<++>\|<++>\|<Enter>\|:----:\|:----:\|:----:\|<Enter>\|<++>\|<++>\|<++>\|<Enter><Esc>3klc4l
" autocmd Filetype markdown inoremap ,t2 \|<++>\|<++>\|<Enter>\|:----:\|:----:\|<Enter>\|<++>\|<++>\|<Enter><Esc>3klc4l
function! CreateMarkdownRow(num_cols)
let col_str = repeat('|<++>', a:num_cols) . '|'
return col_str
endfunction
autocmd Filetype markdown inoremap ,l2 <Esc>o<C-R>=CreateMarkdownRow(2)<CR><Esc>^lc5l
autocmd Filetype markdown inoremap ,l3 <Esc>o<C-R>=CreateMarkdownRow(3)<CR><Esc>^lc5l
autocmd Filetype markdown inoremap ,l4 <Esc>o<C-R>=CreateMarkdownRow(4)<CR><Esc>^lc5l
autocmd Filetype markdown inoremap ,l5 <Esc>o<C-R>=CreateMarkdownRow(5)<CR><Esc>^lc5l
autocmd Filetype markdown inoremap ,l6 <Esc>o<C-R>=CreateMarkdownRow(6)<CR><Esc>^lc5l
" autocmd Filetype markdown inoremap ,l2 \|<++>\|<++>\|
" autocmd Filetype markdown inoremap ,l3 \|<++>\|<++>\|<++>\|
autocmd Filetype markdown inoremap <C-s> <C-o>:w<CR>
"===
"===UndoTree
"===
nnoremap <F5> :UndotreeToggle<CR>
"===
"===vim-surround
"===
" objects: word(iw), line(s), tag(t)
" opretion: add, remove, change
" add: ys[objects] [Mark]
" remove: ds [Mark]
" change: cs [src_Mark], [dst_Mark]
"===
"===nerdcommenter
"===
let g:NERDCreateDefaultMappings = 1
let g:NERDSpaceDelims = 1
let g:NERDCompactSexyComs = 1
let g:NERDDefaultAlign = 'left'
let g:NERDAltDelims_java = 1
let g:NERDCustomDelimiters = { 'c': { 'left': '/**','right': '*/' } }
let g:NERDCommentEmptyLines = 1
let g:NERDTrimTrailingWhitespace = 1
let g:NERDToggleCheckAllLines = 1
NERD-Tree
Install NERDTree
Add Plug 'preservim/nerdtree'
to your .vimrc
, For example:
Plug 'preservim/nerdtree'
Reopen a Vim window and type :PlugInstall
to install NERDTree.
Setting Shortcut Keys
Edit .vimrc
and add the following code:
nnoremap <leader>n :NERDTreeFocus<CR>
nnoremap <C-n> :NERDTree<CR>
nnoremap <C-t> :NERDTreeToggle<CR>
nnoremap <C-f> :NERDTreeFind<CR>
<leader>n
: Default<leader>
is\
. Change the foucus from file to NERDTree.<C-n>
: Open NERDTree.<C-t>
: Open or Close NERDTree.<C-f>
: Open/
in NERDTree.
Auto-Open NERDTree when Vim starts with a directory argument
Add the following code to your .vimrc
:
" Start NERDTree when Vim starts with a directory argument.
autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 1 && isdirectory(argv()[0]) && !exists('s:std_in') |
\ execute 'NERDTree' argv()[0] | wincmd p | enew | execute 'cd '.argv()[0] | endif
"Close the tab if NERDTree is the only window remaining in it.
autocmd BufEnter * if winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | quit | endif
More details at VimAwesome or NERDTree.
Rendering
NerdTree-Git
Github Repo
https://github.com/Xuyuanp/nerdtree-git-plugin
Install
Plug 'Xuyuanp/nerdtree-git-plugin'
let g:NERDTreeGitStatusShowCounts = 1
let g:NERDTreeGitStatusIndicatorMapCustom = {
\ 'Modified' :'✹',
\ 'Staged' :'✚',
\ 'Untracked' :'✭',
\ 'Renamed' :'➜',
\ 'Unmerged' :'═',
\ 'Deleted' :'✖',
\ 'Dirty' :'✗',
\ 'Ignored' :'☒',
\ 'Clean' :'✔︎',
\ 'Unknown' :'?',
\ }
Install Nerd Fonts
Rendering
YouCompleteMe
Github Repo
https://github.com/ycm-core/YouCompleteMe
https://vimawesome.com/plugin/youcompleteme
Installation
Plug 'Valloric/YouCompleteMe'
After :PlugInstall
, if you use vim-plug
cd ~/.vim/plugged/YouCompleteMe
python3 install.py
If failed, according to tips, install cmake
or cmake3
.
Slove GLIBCXX_3.4.32
not found
sudo apt update
sudo apt install libstdc++6
strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep GLIBCXX
Generally, you can find GLIBCXX_3.4.32 in your system. Next, just copy libstdc++.so.6*
to default path that in error log.
sudo cp /usr/lib/x86_64-linux-gnu/libstdc++.so.6* /home/knight/miniconda3/lib/
Rendering
Vim Support System Clipboard
Check Vim version
vim --version | grep clipboard
Output:
knight@Lenovo:~$ vim --version | grep "clipboard"
-clipboard +keymap +printer +vertsplit
+ex_extra +mouse_netterm +syntax -xterm_clipboard
-clipboard
-xterm_clipboard
means that vim not support system clipboard.
Remove vim
Uninstall vim if you have installed.
sudo apt remove vim && sudo apt autoremove
Install vim-gtk3
sudo apt install vim-gtk3
Check Vim version again
vim --version | grep clipboard
Output:
knight@Lenovo:~$ vim --version | grep clipboard
+clipboard +keymap +printer +vertsplit
+ex_extra +mouse_netterm +syntax +xterm_clipboard
Confirem the key value is +clipboard
or +xterm_clipboard
.
Edit .vimrc
set clipboard=unnamedplus
The last you can use "*y
to copy the text to system clipboard.
Use Xclip
sudo apt install xclip
Modify .vimrc
vnoremap Y :w !xclip -i -sel c<CR>
Then you can select some contents in visual mode, and press Y
. Finally, you can use <Ctrl-v>
to paste it anywhere.
Useful Scripts
In Linux, you can use some scripts to do some repetitive tasks.
Switch Node Version
sudo vim hexo_start_stop.sh
sudo chmod +x hexo_start_stop.sh
#!/bin/bash
# 检查参数
if [ "$#" -ne 1 ]; then
echo "Usage: $0 start|stop"
exit 1
fi
# 定义变量
NODE_V12_DIR="/home/knight/node/node-v12/bin"
NODE_V20_DIR="/home/knight/node/node-v20/bin"
NODE_BIN="/usr/bin/node"
NODE_LOCAL_BIN="/usr/local/bin/node"
NPM_BIN="/usr/bin/npm"
NPM_LOCAL_BIN="/usr/local/bin/npm"
NPX_BIN="/usr/bin/npx"
NPX_LOCAL_BIN="/usr/local/bin/npx"
# HEXO_LOCAL_BIN="/usr/local/bin/hexo"
# 根据参数执行相应的操作
case "$1" in
start)
# 更新符号链接到 Node v12
sudo ln -sf "$NODE_V12_DIR/node" "$NODE_BIN"
sudo ln -sf "$NODE_V12_DIR/node" "$NODE_LOCAL_BIN"
sudo ln -sf "$NODE_V12_DIR/npm" "$NPM_BIN"
sudo ln -sf "$NODE_V12_DIR/npm" "$NPM_LOCAL_BIN"
sudo ln -sf "$NODE_V12_DIR/npx" "$NPX_BIN"
sudo ln -sf "$NODE_V12_DIR/npx" "$NPX_LOCAL_BIN"
# sudo ln -sf "$NODE_V12_DIR/hexo" "$HEXO_LOCAL_BIN"
echo "Node, NPM, and NPX links updated to Node v12."
;;
stop)
# 更新符号链接到 Node v20
sudo ln -sf "$NODE_V20_DIR/node" "$NODE_BIN"
sudo ln -sf "$NODE_V20_DIR/node" "$NODE_LOCAL_BIN"
sudo ln -sf "$NODE_V20_DIR/npm" "$NPM_BIN"
sudo ln -sf "$NODE_V20_DIR/npm" "$NPM_LOCAL_BIN"
sudo ln -sf "$NODE_V20_DIR/npx" "$NPX_BIN"
sudo ln -sf "$NODE_V20_DIR/npx" "$NPX_LOCAL_BIN"
# sudo rm -rf "$HEXO_LOCAL_BIN"
echo "Node, NPM, and NPX links updated to Node v20."
;;
*)
echo "Invalid argument. Usage: $0 start|stop"
exit 1
;;
esac
exit 0
Control Docker Proxy Up/Down
sudo vim docker_proxy_start_stop.sh
sudo chmod +x docker_proxy_start_stop.sh
#!/bin/bash
# Define paths
CONF_FILE="/etc/systemd/system/docker.service.d/http-proxy.conf"
BACKUP_CONF_FILE="/etc/systemd/system/docker.service.d/http-proxy.conf.bak"
# Function to enable proxy
enable_proxy() {
# Check if the current configuration file is already the backup
if [ -f "$CONF_FILE" ] && cmp --silent "$CONF_FILE" "$BACKUP_CONF_FILE"; then
echo "Proxy configuration is already enabled."
else
# Move the backup configuration to the active configuration file
sudo mv "$BACKUP_CONF_FILE" "$CONF_FILE"
# Reload systemd manager configuration
sudo systemctl daemon-reload
# Restart Docker service
sudo systemctl restart docker.service
echo "Proxy configuration enabled."
fi
}
# Function to disable proxy
disable_proxy() {
# Check if the current configuration file is the original
if [ -f "$CONF_FILE" ] && ! cmp --silent "$CONF_FILE" "$BACKUP_CONF_FILE"; then
# Move the active configuration file to the backup
sudo mv "$CONF_FILE" "$BACKUP_CONF_FILE"
# Reload systemd manager configuration
sudo systemctl daemon-reload
# Restart Docker service
sudo systemctl restart docker.service
echo "Proxy configuration disabled."
else
echo "Proxy configuration is already disabled."
fi
}
# Check the command argument
case $1 in
start)
enable_proxy
;;
stop)
disable_proxy
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
;;
esac
exit 0
Push Docker Images to Private Registry
Tips:When install images, you need open the proxy, but you must close it before push.
Extract Images Name to File
From the Helm's values.yaml, extract the images name and tag to images.tmp.
Usage:get_images.sh values-nginx.yaml
#!/bin/bash
# **********************************************************
# * Author : Burgess Leo
# * Email : liuxp731@qq.com
# * Create time : 2024-09-13 16:06
# * Filename : get_images.sh
# * Description : Extracts Docker image names and tags from a YAML file and writes them to images.tmp
# **********************************************************
# 检查是否传入文件名作为参数
if [ "$#" -ne 1 ]; then
echo "用法: $0 <values-nginx.yaml>"
exit 1
fi
# 从命令行参数获取文件名
input_file="$1"
# 清空或创建 images.tmp 文件
> images.tmp
while read -r line; do
if [[ $line == *"repository:"* ]]; then
repository=$(echo $line | cut -d':' -f2 | xargs)
elif [[ $line == *"tag:"* ]]; then
tag=$(echo $line | cut -d':' -f2 | xargs)
# 将结果写入 images.tmp 文件
echo "$repository:$tag" >> images.tmp
fi
done < "$input_file"
Pull Docker Images
Install all dcoker images in images.tmp file, one by one. If you have else docker images_list file, you can use it instead, just confirm every lines only has one docker image name.
Usage:pull_images.sh images.tmp
#!/bin/bash
# **********************************************************
# * Author : Burgess Leo
# * Email : liuxp731@qq.com
# * Create time : 2024-09-13 16:34
# * Filename : pull_images.sh
# * Description : Pull images from Internet
# **********************************************************
# 检查是否传入文件名作为参数
if [ "$#" -ne 1 ]; then
echo "用法: $0 <images.tmp>"
exit 1
fi
# 从命令行参数获取文件名
input_file="$1"
# 读取文件并拉取每个镜像
while read -r image; do
if [ -n "$image" ]; then
echo "正在拉取镜像: $image"
docker pull "$image"
fi
done < "$input_file"
Rename Docker Images
The modified image names will be saved in the new_images.tmp
file. And you can modify the private_registry
to change the registry you want to push to.
Usage:update_images.sh images.tmp
#!/bin/bash
# **********************************************************
# * Author : Burgess Leo
# * Email : liuxp731@qq.com
# * Create time : 2024-09-13 16:06
# * Filename : update_and_tag_images.sh
# * Description : Updates image paths and tags Docker images based on a specified file
# **********************************************************
# 检查是否传入文件名作为参数
if [ "$#" -ne 1 ]; then
echo "用法: $0 <images.tmp>"
exit 1
fi
# 从命令行参数获取文件名
input_file="$1"
output_file="new_images.tmp"
private_registry="192.167.3.18/"
# 创建或清空输出文件
> "$output_file"
# 处理文件内容并执行 docker tag 命令
while IFS= read -r original_image; do
# 检查行是否为空
if [[ -n "$original_image" ]]; then
# 在镜像名称前加上私有仓库地址
new_image_name="${private_registry}${original_image}"
# 输出正在标记的镜像信息
echo "正在标记镜像: docker tag $original_image $new_image_name"
# 执行 docker tag 命令
docker tag "$original_image" "$new_image_name"
# 将新的镜像名称写入输出文件
echo "$new_image_name" >> "$output_file"
fi
done < "$input_file"
echo "所有镜像已成功标记并保存到 $output_file"
After Tag docker images, you must check the
new_images_name.tmp
, ensure the image names are correct. And you must confirm about projects created in your private harbor.
Push Images
Push images to a remote registry. This script reads a list of image names from a file named "new_images.tmp", and pushes them to a remote registry.
Usage:push_images.sh new_images.tmp
#!/bin/bash
# **********************************************************
# * Author : Burgess Leo
# * Email : liuxp731@qq.com
# * Create time : 2024-09-14 09:01
# * Filename : push_images.sh
# * Description : Push Docker images to a registry
# **********************************************************
# 检查是否传入文件名作为参数
if [ "$#" -ne 1 ]; then
echo "用法: $0 <images.tmp>"
exit 1
fi
# 从命令行参数获取文件名
images_file="$1"
target_registry="192.167.3.18/library/"
# 遍历images.tmp文件中的每一行
while IFS= read -r line; do
# 检查行是否为空
if [ -z "$line" ]; then
continue
fi
# 打印操作信息
echo "正在推送镜像: $line"
# 推送镜像
docker push "$line"
done < "$images_file"
echo "所有指定的镜像已被推送。"
Delete Images from Local
Delete images from local.
Usage:delete_images.sh new_images.tmp
#!/bin/bash
# **********************************************************
# * Author : Burgess Leo
# * Email : liuxp731@qq.com
# * Create time : 2024-09-14 09:02
# * Filename : delete_images.sh
# * Description : Delete images that pushed
# **********************************************************
# 检查是否有参数传递
if [ $# -ne 1 ]; then
echo "Usage: $0 <path-to-file>"
exit 1
fi
# 指定包含镜像名称的文件路径
images_file="$1"
# 检查文件是否存在
if [ ! -f "$images_file" ]; then
echo "Error: File '$images_file' not found."
exit 1
fi
# 逐行读取文件中的镜像名称
while IFS= read -r image; do
# 删除镜像,忽略不存在的镜像
if docker rmi "$image" &>/dev/null; then
echo "Image $image has been deleted."
else
echo "Image $image does not exist or could not be deleted."
fi
done < "$images_file"
echo "All listed images have been processed."
ALL IN ONE
Merge all the above scripts into one.
#!/bin/bash
# **********************************************************
# * Author : Burgess Leo
# * Email : liuxp731@qq.com
# * Create time : 2024-09-13 16:06
# * Filename : all_in_one.sh
# * Description : Pull images
# **********************************************************
# 欢迎信息
echo "欢迎使用 Docker 镜像管理脚本!"
echo ""
# 菜单函数
print_menu() {
echo "*********************************************************"
echo "* *"
echo "* 1. Get images from Helm yaml files. *"
echo "* *"
echo "* 2. Pull images from docker hub to local. *"
echo "* *"
echo "* 3. Docker tag images you need to change. *"
echo "* *"
echo "* 4. Push images to your private docker registry. *"
echo "* *"
echo "* 5. Delete images from local. *"
echo "* *"
echo "* 6. cat images.tmp. *"
echo "* *"
echo "* 7. cat new_images.tmp. *"
echo "* *"
echo "* 8. About. *"
echo "* *"
echo "* 0. Exit. *"
echo "* *"
echo "*********************************************************"
}
# 主循环
while true; do
print_menu
read -p "请输入功能数字: " choice
case $choice in
1)
read -p "请输入 Helm yaml 文件路径: " yaml_file
if [ ! -f "$yaml_file" ]; then
echo "错误: 文件 '$yaml_file' 不存在."
else
> images.tmp
while read -r line; do
if [[ $line == *"repository:"* ]]; then
repository=$(echo $line | cut -d':' -f2 | xargs)
elif [[ $line == *"tag:"* ]]; then
tag=$(echo $line | cut -d':' -f2 | xargs)
echo "$repository:$tag" >> images.tmp
fi
done < "$yaml_file"
echo "已从 '$yaml_file' 中提取镜像并保存到 'images.tmp',由于 Helm yaml 文件可能包含重复的镜像以及失效的 Tag 名称,请手动检查 images.tmp 文件。"
fi
;;
2)
read -p "请输入 images.tmp 文件路径 (默认: images.tmp): " images_file
images_file=${images_file:-images.tmp} # 设置默认值
if [ ! -f "$images_file" ]; then
echo "错误: 文件 '$images_file' 不存在."
else
while IFS= read -r image || [ -n "$image" ]; do # 修复读取逻辑以处理没有换行的情况
if [ -n "$image" ]; then
echo "正在拉取镜像: $image"
docker pull "$image"
fi
done < "$images_file"
echo "所有镜像已成功拉取."
fi
;;
3)
read -p "请输入 images.tmp 文件路径 (默认: images.tmp): " images_file
images_file=${images_file:-images.tmp} # 设置默认值
if [ ! -f "$images_file" ]; then
echo "错误: 文件 '$images_file' 不存在."
else
output_file="new_images.tmp"
header="192.167.3.18/"
> "$output_file"
while IFS= read -r original_image || [ -n "$original_image" ]; do # 修复读取逻辑以处理没有换行的情况
# 在每一行前添加私有镜像仓库地址
new_image_name="${header}${original_image}"
echo "正在标记镜像: docker tag $original_image $new_image_name"
docker tag "$original_image" "$new_image_name"
echo "$new_image_name" >> "$output_file"
done < "$images_file"
if [ -s "$output_file" ]; then # 检查输出文件是否非空
echo "所有镜像已成功标记并保存到 '$output_file'."
else
echo "警告: '$output_file' 文件为空,未能标记任何镜像."
fi
fi
;;
4)
read -p "请输入 new_images.tmp 文件路径 (默认: new_images.tmp): " images_file
images_file=${images_file:-new_images.tmp} # 设置默认值
if [ ! -f "$images_file" ]; then
echo "错误: 文件 '$images_file' 不存在."
else
while IFS= read -r line || [ -n "$line" ]; do # 修复读取逻辑以处理没有换行的情况
if [ -z "$line" ]; then continue; fi
echo "正在推送镜像: $line"
docker push "$line"
done < "$images_file"
echo "所有指定的镜像已被推送."
fi
;;
5)
read -p "请输入包含要删除的镜像名称的文件路径 (默认: new_images.tmp): " images_file
images_file=${images_file:-new_images.tmp} # 设置默认值
if [ ! -f "$images_file" ]; then
echo "错误: 文件 '$images_file' 不存在."
else
while IFS= read -r image || [ -n "$image" ]; do # 修复读取逻辑以处理没有换行的情况
if docker rmi "$image" &>/dev/null; then
echo "镜像 $image 已被删除."
else
echo "镜像 $image 不存在或无法删除."
fi
done < "$images_file"
echo "所有列出的镜像已被处理."
fi
;;
6)
cat images.tmp
;;
7)
cat new_images.tmp
;;
8)
# 打印关于信息
cat << 'EOF'
_..._ 666
.' '. _
/ .-""-\ _/ \
.-| /:. | | |
| \ |:. /.-'-./
| .-'-;:__.' =/
.'= *=|NASA _.='
/ _. | ;
;-.-'| \ |
/ | \ _\ _\
\__/'._;. \==' ==\
\ \ |
/ / /
/-._/-._/
lxp \ `\ \
`-._/._/
EOF
;;
0)
echo "退出程序。再见!"
exit 0
;;
*)
echo "无效的选择,请重新输入."
;;
esac
# 打印分隔行以提高可读性,并重新显示菜单
printf "\n\n\n"
done
Ubuntu Software
Collection of useful software for Ubuntu.
-
The best choice for Chinese input. Although Sougou Input is aviailable, it will make your system slow, especially when you restart your system.
-
Based on wine, it can be used to install wechat on Ubuntu. In spite of defects, it is a good choice for Chinese users.
-
After clash for windows, it is recommended to use clash verge.
-
An incrediable tool of split-screen.
sudo apt install -y vim-gtk3 highlight bat ripgrep tree net-tools nmap
Install Google-PinYin
On Ubuntu, Google-PinYin based on Fcitx. So install Fcitx firstly.
sudo apt install fcitx
Configure Fcitx
im-config
Install Google-PinYin
sudo apt install fcitx-googlepinyin
Running Fcitx
fcitx-config-gtk3
Wechat Install
Install Deepin Repository
wget -O- https://deepin-wine.i-m.dev/setup.sh | sh
Install Wechat
sudo apt install com.qq.weixin.deepin
解决统信应用解压失败的问题
sudo vim /opt/deepinwine/tools/run_v4.sh
# find this line
7z x "$APPDIR/$APPTAR" -o"$1"
# update it following line
7z x "$APPDIR/$APPTAR" -o"$1" || true
Remove Wechat
sudo apt remove com.qq.weixin.deepin
Delete Deepin Repository
sudo rm /etc/apt/sources.d.list/deepin-wine.i-m.dev.list
Tencent Official Wechat
- Download
wget https://dldir1v6.qq.com/weixin/Universal/Linux/WeChatLinux_x86_64.deb
Install Clash-Verge
clash-verge Project Github
https://github.com/clash-verge-rev/clash-verge-rev
Sloved Error of "clash-verge 依赖于 libwebkit2gtk-4.0-37."
sudo vim /etc/apt/sources.list.d/ubuntu.sources
# 添加以下内容
Types: deb
URIs: http://br.archive.ubuntu.com/ubuntu/
Suites: jammy
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
sudo apt update
Sloved Error of starting "clash-verge" but no display window
vim /usr/share/applications/clash-verge.desktop
# 将 Exec 改为:
Exec=env WEBKIT_DISABLE_COMPOSITING_MODE=1 clash-verge
Clash For Linux
Github Repo
https://github.com/wnlen/clash-for-linux.git
Installation
git clone https://github.com/wnlen/clash-for-linux.git
Modify .env
The CLASH_URL
is your subscription address, and the CLASH_SECRET
is your password, when you login with web, you will use it.
Start Clash
sudo bash start.sh
As show tips, exec cmds.
Else CMD
- Close clash
sudo bash shutdown.sh
- Close proxy
proxy-off
Install Docker
Install Official Docker GPG Key
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
Add Official Docker Repo
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Update Package Lists
sudo apt-get update
Install Docker
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Well, you can access https://download.docker.com/ and download the .deb
file manually.
Such Path: https://download.docker.com/linux/ubuntu/dists/focal/pool/stable/amd64/
Crack Pycharm
Edit vmoptions
vim /pycharm/install/path/bin/pycharm64.vmoptions
Add following options to the end of the file
-javaagent:/jar-package/path/jetbra/ja-netfilter.jar=jetbrains
--add-opens=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED
--add-opens=java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED
Activation Code
YQLSN55KLT-eyJsaWNlbnNlSWQiOiJZUUxTTjU1S0xUIiwibGljZW5zZWVOYW1lIjoi5rC45LmF5Zyw5Z2AIHd3d8K3YWppaHVvwrdjb20iLCJsaWNlbnNlZVR5cGUiOiJQRVJTT05BTCIsImFzc2lnbmVlTmFtZSI6IiIsImFzc2lnbmVlRW1haWwiOiIiLCJsaWNlbnNlUmVzdHJpY3Rpb24iOiIiLCJjaGVja0NvbmN1cnJlbnRVc2UiOmZhbHNlLCJwcm9kdWN0cyI6W3siY29kZSI6IkdPIiwicGFpZFVwVG8iOiIyMDI1LTAzLTExIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSUzAiLCJwYWlkVXBUbyI6IjIwMjUtMDMtMTEiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IkRNIiwicGFpZFVwVG8iOiIyMDI1LTAzLTExIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJDTCIsInBhaWRVcFRvIjoiMjAyNS0wMy0xMSIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiUlNVIiwicGFpZFVwVG8iOiIyMDI1LTAzLTExIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSU0MiLCJwYWlkVXBUbyI6IjIwMjUtMDMtMTEiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUEMiLCJwYWlkVXBUbyI6IjIwMjUtMDMtMTEiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IkRTIiwicGFpZFVwVG8iOiIyMDI1LTAzLTExIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSRCIsInBhaWRVcFRvIjoiMjAyNS0wMy0xMSIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiUUEiLCJwYWlkVXBUbyI6IjIwMjUtMDMtMTEiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IlJDIiwicGFpZFVwVG8iOiIyMDI1LTAzLTExIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSU0YiLCJwYWlkVXBUbyI6IjIwMjUtMDMtMTEiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUk0iLCJwYWlkVXBUbyI6IjIwMjUtMDMtMTEiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IklJIiwicGFpZFVwVG8iOiIyMDI1LTAzLTExIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJEUE4iLCJwYWlkVXBUbyI6IjIwMjUtMDMtMTEiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IkRCIiwicGFpZFVwVG8iOiIyMDI1LTAzLTExIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJEQyIsInBhaWRVcFRvIjoiMjAyNS0wMy0xMSIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiUFMiLCJwYWlkVXBUbyI6IjIwMjUtMDMtMTEiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IlJSIiwicGFpZFVwVG8iOiIyMDI1LTAzLTExIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSU1YiLCJwYWlkVXBUbyI6IjIwMjUtMDMtMTEiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiV1MiLCJwYWlkVXBUbyI6IjIwMjUtMDMtMTEiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IlBTSSIsInBhaWRVcFRvIjoiMjAyNS0wMy0xMSIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJQQ1dNUCIsInBhaWRVcFRvIjoiMjAyNS0wMy0xMSIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJBSUwiLCJwYWlkVXBUbyI6IjIwMjUtMDMtMTEiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IlJTIiwicGFpZFVwVG8iOiIyMDI1LTAzLTExIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IkRQIiwicGFpZFVwVG8iOiIyMDI1LTAzLTExIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBEQiIsInBhaWRVcFRvIjoiMjAyNS0wMy0xMSIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJQUlIiLCJwYWlkVXBUbyI6IjIwMjUtMDMtMTEiLCJleHRlbmRlZCI6dHJ1ZX1dLCJtZXRhZGF0YSI6IjAyMjAyNTAyMTJQUEFNMDA2MDA1QSIsImhhc2giOiI2NjM5MzE5MS8wOjc2MDEyODIxNCIsImdyYWNlUGVyaW9kRGF5cyI6NywiYXV0b1Byb2xvbmdhdGVkIjpmYWxzZSwiaXNBdXRvUHJvbG9uZ2F0ZWQiOmZhbHNlLCJ0cmlhbCI6ZmFsc2UsImFpQWxsb3dlZCI6dHJ1ZX0=-HhxiOkGKCb3ymp+pacIhMlNE/54EGAr0LE2Qu7IBbQFZjk144sEBxR8JB3ZXyp6L1S5ruxTVpORLqQXLBrfH5m3Y7llwnp0DXPrvFLmPnYU1GnROYxpdGWZO3Tl8DpYu4uFQEY1AWkZXcy4TonPGkChktneR/7Z04tKapCFMbomkuEGb8d73c3Sviv40j1QbhKRaBlGhUUFcto9oJPl7cUf/i8Tz9FQgqdZvxpWtFgK7IeDh2N2b5AJvKH6UJadPjLYeI55r6aRNnvdyQHRTUmWvvSRO3CxNGdEeOp5YPR7pdUStvigYD+0Ww6lUuv4BB5BRY26ale5djLaBHoL7BA==-MIIETDCCAjSgAwIBAgIBETANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTI0MDkyMDEyMTEyN1oXDTI2MDkyMjEyMTEyN1owHzEdMBsGA1UEAwwUcHJvZDJ5LWZyb20tMjAyNDA5MjAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7SH/XcUoMwkDi8JJPzXWWHWFdOZdrP2Dqkz2W8iUi650cwz2vdPEd0tMzosLAj7ifkFEHUyiuEcL//q9d9Op7ZsV23lpPXX8tFMLFwugoQ9D8jDLT/XP9pp/YukWkKF5jpNbaCvsVQkDdYkArBkYvhH3aN4v9BkEsXahfgLLOPe4IG2FDJNf9R4to9V1vt+m2UVJB0zV4a/sVMKUZLgqKmKKKOKoLrE3OjBlZlb+Q0z2N5dsW0hDEVRFGmBUAbHN/mp44MMMvEIFKfoLIGpgic92P2O6uFh75PI7mcultL6yuR48ajErx8CjjQEGOSnoq/8hD+yVE+6GW2gJa2CPvAgMBAAGjgZkwgZYwCQYDVR0TBAIwADAdBgNVHQ4EFgQUb5NERj05GyNerQ/Mjm9XH8HXtLIwSAYDVR0jBEEwP4AUo562SGdCEjZBvW3gubSgUouX8bOhHKQaMBgxFjAUBgNVBAMMDUpldFByb2ZpbGUgQ0GCCQDSbLGDsoN54TATBgNVHSUEDDAKBggrBgEFBQcDATALBgNVHQ8EBAMCBaAwDQYJKoZIhvcNAQELBQADggIBALq6VfVUjmPI3N/w0RYoPGFYUieCfRO0zVvD1VYHDWsN3F9buVsdudhxEsUb8t7qZPkDKTOB6DB+apgt2ZdKwok8S0pwifwLfjHAhO3b+LUQaz/VmKQW8gTOS5kTVcpM0BY7UPF8cRBqxMsdUfm5ejYk93lBRPBAqntznDY+DNc9aXOldFiACyutB1/AIh7ikUYPbpEIPZirPdAahroVvfp2tr4BHgCrk9z0dVi0tk8AHE5t7Vk4OOaQRJzy3lST4Vv6Mc0+0z8lNa+Sc3SVL8CrRtnTAs7YpD4fpI5AFDtchNrgFalX+BZ9GLu4FDsshVI4neqV5Jd5zwWPnwRuKLxsCO/PB6wiBKzdapQBG+P9z74dQ0junol+tqxd7vUV/MFsR3VwVMTndyapIS+fMoe+ZR5g+y44R8C7fXyVE/geg+JXQKvRwS0C5UpnS5FcGk+61b0e4U7pwO20RlwhEFHLSaP61p2TaVGo/TQtT/fWmrtV+HegAv9P3X3Se+xIVtJzQsk8QrB/w52IB3FKiAKl/KRn1egbMIs4uoNAkqNZ9Ih2P1NpiQnONFmkiAgeynJ+0FPykKdJQbV3Mx44jkaHIif4aFReTsYX1WUBNu/QerZRjn4FVSHRaZPSR5Oi82Wz0Nj7IY9ocTpLnXFrqkb/Kt3S6B9s2Kol3Lr1ElYA
Start Pycharm like VS-Code
Modify pycharm.sh
Generally pycharm.sh is located at /pycharm/install/path/bin/pycharm.sh
.
Add > /dev/null 2>&1 &
to the end of the file. Make sure the file looks like this:
com.intellij.idea.Main \
"$@" \
> /dev/null 2>&1 &
Create a link file
sudo ln -sf /pycharm/install/path/bin/pycharm.sh /usr/local/bin/pycharm
Then, you can start Pycharm by typing pycharm
in the terminal.
knight@Lenovo:~/workspace/game_of_thrones$ pycharm .
knight@Lenovo:~/workspace/game_of_thrones$
Tmux
Installation
sudo apt install -y tmux
Install Tmux Plugins Manager
https://github.com/tmux-plugins/tpm
git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
Create .tmux.conf File
This is my personal tmux config file.
### tmux.conf
# system setting
set -g default-terminal "tmux-256color"
set -g mouse on
# rebind prefix key
unbind C-b
set -g prefix 'C-d'
set -g mode-keys vi
# reload configuration
# bind R source-file ~/.tmux.conf \; display '~/.tmux.conf Reloaded!'
# windows behaver
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on
#setw -g automatic-rename on
# display options
set -g set-titles on
set -g display-panes-time 2000
# window navigation
unbind n
unbind p
unbind x
bind -n C-o previous-window
bind -n C-p next-window
bind -n C-n new-window -c "#{pane_current_path}"
bind -n C-q kill-pane
# split windows
unbind %
unbind \"
bind l split-window -h -c "#{pane_current_path}"
bind k split-window -v -c "#{pane_current_path}"
bind h split-window -hb -c "#{pane_current_path}"
bind j split-window -vb -c "#{pane_current_path}"
# windows size adjusting
bind -n M-f resize-pane -Z
bind -n M-j resize-pane -U 5
bind -n M-k resize-pane -D 5
bind -n M-h resize-pane -L 5
bind -n M-l resize-pane -R 5
# cursor-moving setting
unbind o
unbind \;
bind -T root C-Left select-pane -L
bind -T root C-Right select-pane -R
bind -T root C-Up select-pane -U
bind -T root C-Down select-pane -D
# pane-moving setting
bind < swap-pane -U
bind > swap-pane -D
# tmux plugins
run '~/.tmux/plugins/tmux/catppuccin.tmux'
set -g @catppuccin_flavor 'frappe' # latte | frappe | mocha | macchiato
set -g @catppuccin_window_status_style "rounded" # basic | rounded | slanted | custom | none
set -g @catppuccin_window_number_color "#{@thm_fg}"
set -g @catppuccin_window_current_number_color "#{@thm_green}"
set -g status-left ""
set -g status-right ""
set -g status-right-length 100
set -g @yank_action 'copy-pipe' # or 'copy-pipe-and-cancel' for the default
set -g status-right "#{net_speed} "
set -g @net_speed_interfaces "enp2s0 wlp3s0"
set -g @net_speed_format "%8s %8s "
set -agF status-right "#{E:@catppuccin_status_cpu}"
set -agF status-right "#{E:@catppuccin_status_weather}"
set-option -g @tmux-weather-interval 10
set -gq @catppuccin_weather_color "#ea999c"
set-option -g @tmux-weather-location "BeiJing"
set -ag status-right "#{E:@catppuccin_status_date_time}"
set -g "@catppuccin_date_time_text" " %m-%d %H:%M"
# set -ag status-right "#{E:@catppuccin_status_session}"
# set -ag status-right "#{E:@catppuccin_status_application}"
# set -ag status-right "#{E:@catppuccin_status_gitmux}"
# set -ag status-right "#{E:@catppuccin_status_load}"
# set -ag status-right "#{E:@catppuccin_status_pomodoro_plus}"
# set -ag status-right "#{E:@catppuccin_status_kube}"
# set -ag status-right "#{E:@catppuccin_status_up_time}"
# set -ag status-right "#{E:@catppuccin_status_user}"
# set -g status-right '#[fg=#{@thm_crust},bg=#{@thm_teal}] : #S '
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-yank'
set -g @plugin 'tmux-plugins/tmux-sensible'
set -g @plugin 'tmux-plugins/tmux-cpu'
set -g @plugin 'tmux-plugins/tmux-net-speed'
set -g @plugin 'xamut/tmux-weather'
set -g @plugin 'catppuccin/tmux#v2.1.1'
run '~/.tmux/plugins/tpm/tpm'
Install Nerd Font
- Clone Repo to install
Get script of install Nerd fonts. After many attempts, Font Meslo
performed best.
git clone --depth 1 https://github.com/ryanoasis/nerd-fonts.git && \
cd nerd-fonts/ && \
./install.sh Meslo
- Use script to install (Recommend)
wget https://raw.githubusercontent.com/mcarvalho1/Simple-NerdFonts-Downloader/c7854dae2153aa199277926bed4b992488b65a3d/nf_downloader.sh
nf_downloader.sh default will install all fonts, remember to modify it. The fonts will save in
~/.local/share/fonts
.
Create WindTerm Desktop Entry
[Desktop Entry]
Name=WindTerm
Comment=A professional cross-platform SSH/Sftp/Shell/Telnet/Serial terminal
GenericName=Connect Client
Exec=/home/knight/windTerm/WindTerm_2.6.1/WindTerm
Type=Application
Icon=/home/knight/windTerm/WindTerm_2.6.1/windterm.png
StartupNotify=false
StartupWMClass=Code
Categories=Application;Development
Actions=new-empty-window
Keywords=windterm
[Desktop Action new-empty-window]
Name=New Empty Window
Exec=/home/knight/windTerm/WindTerm_2.6.1/WindTerm
Icon=/home/knight/windTerm/WindTerm_2.6.1/windterm.png
Asciiquarium Command Install
Ubuntu
sudo apt-get install -y perl libcurses-perl wget
wget http://search.cpan.org/CPAN/authors/id/K/KB/KBAUCOM/Term-Animation-2.4.tar.gz
wget http://www.robobunny.com/projects/asciiquarium/asciiquarium.tar.gz
tar -xf Term-Animation-2.4.tar.gz
tar -xf asciiquarium.tar.gz
cd Term-Animation-2.4/ && perl Makefile.PL && make && sudo make install
cd ../asciiquarium_1.1/
cp asciiquarium /usr/local/bin
sudo chmod +x /usr/local/bin/asciiquarium
asciiquarium
Centos
cd /opt
yum install -y wget
wget http://search.cpan.org/CPAN/authors/id/K/KB/KBAUCOM/Term-Animation-2.4.tar.gz
tar xf Term-Animation-2.4.tar.gz
yum install perl-Curses.x86_64 -y
yum install perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker -y
cd /opt/Term-Animation-2.4/ && perl Makefile.PL
make
make install
cd /opt
wget http://www.robobunny.com/projects/asciiquarium/asciiquarium.tar.gz
tar -zxvf asciiquarium.tar.gz
cd asciiquarium_1.1/
cp asciiquarium /usr/local/bin
chmod +x /usr/local/bin/asciiquarium
asciiquarium
使用 frp
Project Official Website
https://github.com/fatedier/frp
SSH Service
The server configuration
vim frps.toml
bindPort = 5432 # frp 建立通讯的端口
auth.token = "123456"
The Client configuration
vim frpc.toml
serverAddr = "123.00.00.01"
serverPort = 5432 # frp 建立通讯的端口
auth.token = "123456"
[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 10086 # frp 映射的端口,VPS需要打开的端口
FTP Service
The Server configuration
vim frps.toml
bindPort = 5432
auth.token = "123456"
The Client configuration
vim frpc.toml
serverAddr = "123.00.00.01"
serverPort = 5432
auth.token = "123456"
[[proxies]]
name = "test_static_file"
type = "tcp"
localPort = 21
remotePort = 10086
[proxies.plugin]
type = "static_file"
# 本地文件目录,对外提供访问
localPath = "/your/local/path"
# URL 中的前缀,将被去除,保留的内容即为要访问的文件路径
stripPrefix = "static"
httpUser = "user"
httpPassword = "password"
systemctl Configuration
- frps | Server configuration
sudo vim /etc/systemd/system/frps.service
[Unit]
# 服务名称,可自定义
Description = frp server
After = network.target syslog.target
Wants = network.target
[Service]
Type = simple
# 启动frps的命令,需修改为您的frps的安装路径
ExecStart = /root/frp/frps -c /root/frp/config.toml
[Install]
WantedBy = multi-user.target
reload daemon and start service
sudo systemctl daemon-reload
sudo systemctl enable --now frps
- frpc | Client configuration
sudo vim /etc/systemd/system/frpc.service
[Unit]
Description=FRPC Client Service
After=network.target
[Service]
User=knight
Group=knight
Type=simple
ExecStart=/home/knight/frp/frpc -c /home/knight/frp/config.toml
Restart=on-failure
RestartSec=5s
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=frpc
[Install]
WantedBy=multi-user.target
reload daemon and start service
sudo systemctl daemon-reload
sudo systemctl enable --now frpc
Entertainment
Install KODI
sudo apt install software-properties-common
sudo add-apt-repository -y ppa:team-xbmc/ppa
sudo apt install kodi
Install TMM
https://www.tinymediamanager.org/download/
qBittorrent Enhanced
https://github.com/c0re100/qBittorrent-Enhanced-Edition/releases
LX Music
https://github.com/lyswhut/lx-music-desktop/releases
All Kinds of Proxy Setting
In china, you can't access to the real Internet directly. So you have to use some proxy in some software.
Configure System Proxy
Edit a Script
sudo vim /etc/profile.d/proxy.sh
#!/bin/bash
set_proxy() {
# set proxy config via profile.d - should apply for all users
export http_proxy="http://127.0.0.1:7890/"
export https_proxy="http://127.0.0.1:7890/"
export ftp_proxy="http://127.0.0.1:7890/"
export no_proxy="127.0.0.1,localhost"
# For curl
export HTTP_PROXY="http://127.0.0.1:7890/"
export HTTPS_PROXY="http://127.0.0.1:7890/"
export FTP_PROXY="http://127.0.0.1:7890/"
export NO_PROXY="127.0.0.1,localhost"
echo "Proxy has been set."
}
unset_proxy() {
# unset proxy config
unset http_proxy
unset https_proxy
unset ftp_proxy
unset no_proxy
# For curl
unset HTTP_PROXY
unset HTTPS_PROXY
unset FTP_PROXY
unset NO_PROXY
echo "Proxy has been unset."
}
case $1 in
set)
set_proxy
;;
unset)
unset_proxy
;;
*)
echo "Usage: source $0 {set|unset}"
;;
esac
Add Exec Permission
sudo chmod +x /etc/profile.d/proxy.sh
Apply Setting
source /etc/profile.d/proxy.sh
Confirm ENV
env | grep -i proxy
Setting Docker Mirror Acceleration
Edit Conf File
sudo vim /etc/docker/daemon.json
Add Lines
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://docker.xuanyuan.me",
"https://docker.wanpeng.life",
"https://docker.imgdb.de"
]
}
Reload Daemon & Restart Docker
sudo systemctl daemon-reload
sudo systemctl restart docker
Configure Docker Proxy
Edit Conf File
sudo mkdir -p /etc/systemd/system/docker.service.d && \
sudo vim /etc/systemd/system/docker.service.d/http-proxy.conf
Add Lines
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
Reload Daemon & Restart Docker
sudo systemctl daemon-reload
sudo systemctl restart docker
Configure Container Proxy
Edit Conf File
vim ~/.docker/config.json
Add Lines
{
"proxies":
{
"default":
{
"httpProxy": "http://172.17.0.1:7890",
"httpsProxy": "http://172.17.0.1:7890",
"noProxy": "*.<domain>,127.0.0.0/8"
}
}
}
Reload Daemon & Restart Docker
sudo systemctl daemon-reload
sudo systemctl restart docker
Configure K3S Proxy
-
/etc/systemd/system/k3s.service.env
-
/etc/systemd/system/k3s-agent.service.env
HTTP_PROXY=http://your-proxy.example.com:8888
HTTPS_PROXY=http://your-proxy.example.com:8888
NO_PROXY=127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
Funny Docker Projects
Collected some funny docker projects here. If you want to try, confirm you install docker and docker-compose first.
-
You can chat with your local ollama models in browser. It's provide history management and session management.
-
A music player with a beautiful UI. You can deploy it on your own server.
OpenWeb-UI
open-webui Official Website
Docker Deployment
version: '3'
services:
open-webui:
image: ghcr.io/open-webui/open-webui:main
container_name: open-webui
ports:
- "3000:8080"
volumes:
- open-webui:/app/backend/data
# restart: always
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
open-webui:
Docker deploy open-webui needs to configure ollama Service Discovery, or ollama can't discern local models.
Yesplaymusic
Official Website
https://github.com/qier222/YesPlayMusic
Docker Deployment
version: '3.9'
services:
yesplaymusic:
image: fogforest/yesplaymusic
container_name: yesplaymusic
restart: always
ports:
- "7900:80"