feat: add nosudo
This commit is contained in:
+53
-51
@@ -20,7 +20,7 @@
|
|||||||
"vim.normalModeKeyBindingsNonRecursive": [
|
"vim.normalModeKeyBindingsNonRecursive": [
|
||||||
{
|
{
|
||||||
"before": ["<space>"],
|
"before": ["<space>"],
|
||||||
"commands": ["vspacecode.space"],
|
"commands": ["vspacecode.space"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"before": [","],
|
"before": [","],
|
||||||
@@ -28,15 +28,15 @@
|
|||||||
"vspacecode.space",
|
"vspacecode.space",
|
||||||
{
|
{
|
||||||
"command": "whichkey.triggerKey",
|
"command": "whichkey.triggerKey",
|
||||||
"args": "m",
|
"args": "m"
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
"vim.visualModeKeyBindingsNonRecursive": [
|
"vim.visualModeKeyBindingsNonRecursive": [
|
||||||
{
|
{
|
||||||
"before": ["<space>"],
|
"before": ["<space>"],
|
||||||
"commands": ["vspacecode.space"],
|
"commands": ["vspacecode.space"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"before": [","],
|
"before": [","],
|
||||||
@@ -44,18 +44,18 @@
|
|||||||
"vspacecode.space",
|
"vspacecode.space",
|
||||||
{
|
{
|
||||||
"command": "whichkey.triggerKey",
|
"command": "whichkey.triggerKey",
|
||||||
"args": "m",
|
"args": "m"
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"before": [">"],
|
"before": [">"],
|
||||||
"commands": ["editor.action.indentLines"],
|
"commands": ["editor.action.indentLines"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"before": ["<"],
|
"before": ["<"],
|
||||||
"commands": ["editor.action.outdentLines"],
|
"commands": ["editor.action.outdentLines"]
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
"workbench.panel.location": "right",
|
"workbench.panel.location": "right",
|
||||||
"gitHistory.hideCommitViewExplorer": true,
|
"gitHistory.hideCommitViewExplorer": true,
|
||||||
@@ -67,16 +67,16 @@
|
|||||||
"sync.gist": "3c4e02a02a0d110622006b8c8b058fa5",
|
"sync.gist": "3c4e02a02a0d110622006b8c8b058fa5",
|
||||||
"go.languageServerFlags": ["-rpc.trace"],
|
"go.languageServerFlags": ["-rpc.trace"],
|
||||||
"[json]": {
|
"[json]": {
|
||||||
"editor.defaultFormatter": "vscode.json-language-features",
|
"editor.defaultFormatter": "vscode.json-language-features"
|
||||||
},
|
},
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"*.html": "html",
|
"*.html": "html",
|
||||||
"*.json": "jsonc",
|
"*.json": "jsonc",
|
||||||
"NOTES.txt": "helm",
|
"NOTES.txt": "helm",
|
||||||
"Dockerfile": "dockerfile",
|
"Dockerfile": "dockerfile"
|
||||||
},
|
},
|
||||||
"[helm]": {
|
"[helm]": {
|
||||||
"editor.defaultFormatter": "redhat.vscode-yaml",
|
"editor.defaultFormatter": "redhat.vscode-yaml"
|
||||||
// "editor.formatOnSave": false // alternatively, force it to leave you alone
|
// "editor.formatOnSave": false // alternatively, force it to leave you alone
|
||||||
},
|
},
|
||||||
"gitlens.codeLens.recentChange.enabled": false,
|
"gitlens.codeLens.recentChange.enabled": false,
|
||||||
@@ -87,19 +87,19 @@
|
|||||||
// "terminal.integrated.shell.osx": "/bin/zsh",
|
// "terminal.integrated.shell.osx": "/bin/zsh",
|
||||||
"editor.fontFamily": "Fira Code, Sarasa Fixed SC Nerd Font, Menlo, Monaco, 'Courier New', monospace",
|
"editor.fontFamily": "Fira Code, Sarasa Fixed SC Nerd Font, Menlo, Monaco, 'Courier New', monospace",
|
||||||
"[javascript]": {
|
"[javascript]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
},
|
},
|
||||||
"search.followSymlinks": false,
|
"search.followSymlinks": false,
|
||||||
"go.autocompleteUnimportedPackages": true,
|
"go.autocompleteUnimportedPackages": true,
|
||||||
"[jsonc]": {
|
"[jsonc]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
},
|
},
|
||||||
"vscode-neovim.mouseSelectionStartVisualMode": true,
|
"vscode-neovim.mouseSelectionStartVisualMode": true,
|
||||||
"go.lintTool": "golangci-lint",
|
"go.lintTool": "golangci-lint",
|
||||||
"go.lintFlags": ["--config=~/.dotfile/golang/golangci.yml"],
|
"go.lintFlags": ["--config=~/.dotfile/golang/golangci.yml"],
|
||||||
"go.liveErrors": {
|
"go.liveErrors": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"delay": 500,
|
"delay": 500
|
||||||
},
|
},
|
||||||
"python.languageServer": "Pylance",
|
"python.languageServer": "Pylance",
|
||||||
"go.overwriteGoplsMiddleware": {},
|
"go.overwriteGoplsMiddleware": {},
|
||||||
@@ -107,20 +107,20 @@
|
|||||||
"[go]": {
|
"[go]": {
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"source.organizeImports": "explicit",
|
"source.organizeImports": "explicit"
|
||||||
},
|
},
|
||||||
"editor.snippetSuggestions": "none",
|
"editor.snippetSuggestions": "none",
|
||||||
"editor.defaultFormatter": "golang.go",
|
"editor.defaultFormatter": "golang.go"
|
||||||
},
|
},
|
||||||
"[go.mod]": {
|
"[go.mod]": {
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"source.organizeImports": "explicit",
|
"source.organizeImports": "explicit"
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
"gopls": {
|
"gopls": {
|
||||||
"usePlaceholders": true,
|
"usePlaceholders": true,
|
||||||
"staticcheck": false,
|
"staticcheck": false
|
||||||
},
|
},
|
||||||
"go.testFlags": ["-v"],
|
"go.testFlags": ["-v"],
|
||||||
"vscode-neovim.neovimExecutablePaths.darwin": "/usr/local/bin/nvim",
|
"vscode-neovim.neovimExecutablePaths.darwin": "/usr/local/bin/nvim",
|
||||||
@@ -136,22 +136,22 @@
|
|||||||
"security.workspace.trust.untrustedFiles": "open",
|
"security.workspace.trust.untrustedFiles": "open",
|
||||||
"workbench.tree.indent": 4,
|
"workbench.tree.indent": 4,
|
||||||
"[html]": {
|
"[html]": {
|
||||||
"editor.defaultFormatter": "vscode.html-language-features",
|
"editor.defaultFormatter": "vscode.html-language-features"
|
||||||
},
|
},
|
||||||
"python.defaultInterpreterPath": "/usr/local/bin/python3",
|
"python.defaultInterpreterPath": "/usr/local/bin/python3",
|
||||||
"[python]": {
|
"[python]": {
|
||||||
"editor.formatOnType": true,
|
"editor.formatOnType": true,
|
||||||
"editor.defaultFormatter": "ms-python.python",
|
"editor.defaultFormatter": "ms-python.python"
|
||||||
},
|
},
|
||||||
"[go][go.mod]": {
|
"[go][go.mod]": {
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"source.organizeImports": "explicit",
|
"source.organizeImports": "explicit"
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
"update.showReleaseNotes": false,
|
"update.showReleaseNotes": false,
|
||||||
"terminal.integrated.defaultProfile.osx": "fish",
|
"terminal.integrated.defaultProfile.osx": "fish",
|
||||||
"extensions.experimental.affinity": {
|
"extensions.experimental.affinity": {
|
||||||
"asvetliakov.vscode-neovim": 1,
|
"asvetliakov.vscode-neovim": 1
|
||||||
},
|
},
|
||||||
"makefile.configureOnOpen": false,
|
"makefile.configureOnOpen": false,
|
||||||
"python.terminal.activateEnvInCurrentTerminal": true,
|
"python.terminal.activateEnvInCurrentTerminal": true,
|
||||||
@@ -159,10 +159,12 @@
|
|||||||
"remote.SSH.defaultForwardedPorts": [],
|
"remote.SSH.defaultForwardedPorts": [],
|
||||||
"remote.SSH.useLocalServer": false,
|
"remote.SSH.useLocalServer": false,
|
||||||
"remote.SSH.connectTimeout": 30,
|
"remote.SSH.connectTimeout": 30,
|
||||||
|
"remote.SSH.localServerDownload": "always",
|
||||||
"remote.SSH.remotePlatform": {
|
"remote.SSH.remotePlatform": {
|
||||||
"box1": "linux",
|
"box1": "linux",
|
||||||
"hx80": "linux",
|
"hx80": "linux",
|
||||||
"hx20": "linux",
|
"hx20": "linux",
|
||||||
|
"pc30": "linux"
|
||||||
},
|
},
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"pylint.enabled": false,
|
"pylint.enabled": false,
|
||||||
@@ -170,50 +172,50 @@
|
|||||||
"python.analysis.packageIndexDepths": [
|
"python.analysis.packageIndexDepths": [
|
||||||
{
|
{
|
||||||
"name": "sklearn",
|
"name": "sklearn",
|
||||||
"depth": 2,
|
"depth": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "matplotlib",
|
"name": "matplotlib",
|
||||||
"depth": 2,
|
"depth": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "scipy",
|
"name": "scipy",
|
||||||
"depth": 2,
|
"depth": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "django",
|
"name": "django",
|
||||||
"depth": 2,
|
"depth": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "flask",
|
"name": "flask",
|
||||||
"depth": 2,
|
"depth": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "fastapi",
|
"name": "fastapi",
|
||||||
"depth": 2,
|
"depth": 2
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
"[shellscript]": {
|
"[shellscript]": {
|
||||||
"editor.defaultFormatter": "foxundermoon.shell-format",
|
"editor.defaultFormatter": "foxundermoon.shell-format"
|
||||||
},
|
},
|
||||||
// "[dockerfile]": {
|
// "[dockerfile]": {
|
||||||
// "editor.defaultFormatter": "foxundermoon.shell-format"
|
// "editor.defaultFormatter": "foxundermoon.shell-format"
|
||||||
// },
|
// },
|
||||||
"[ignore]": {
|
"[ignore]": {
|
||||||
"editor.defaultFormatter": "foxundermoon.shell-format",
|
"editor.defaultFormatter": "foxundermoon.shell-format"
|
||||||
},
|
},
|
||||||
"[properties]": {
|
"[properties]": {
|
||||||
"editor.defaultFormatter": "foxundermoon.shell-format",
|
"editor.defaultFormatter": "foxundermoon.shell-format"
|
||||||
},
|
},
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
// "source.organizeImports": "explicit",
|
// "source.organizeImports": "explicit",
|
||||||
"source.fixAll.eslint": "explicit",
|
"source.fixAll.eslint": "explicit"
|
||||||
},
|
},
|
||||||
"[proto3]": {
|
"[proto3]": {
|
||||||
"editor.defaultFormatter": "zxh404.vscode-proto3",
|
"editor.defaultFormatter": "zxh404.vscode-proto3"
|
||||||
},
|
},
|
||||||
"[dotenv]": {
|
"[dotenv]": {
|
||||||
"editor.defaultFormatter": "foxundermoon.shell-format",
|
"editor.defaultFormatter": "foxundermoon.shell-format"
|
||||||
},
|
},
|
||||||
"typescript.preferences.quoteStyle": "single",
|
"typescript.preferences.quoteStyle": "single",
|
||||||
"javascript.preferences.quoteStyle": "single",
|
"javascript.preferences.quoteStyle": "single",
|
||||||
@@ -221,7 +223,7 @@
|
|||||||
"pretty-formatter.quoteConvert": "single",
|
"pretty-formatter.quoteConvert": "single",
|
||||||
"html.completion.attributeDefaultValue": "singlequotes",
|
"html.completion.attributeDefaultValue": "singlequotes",
|
||||||
"[typescriptreact]": {
|
"[typescriptreact]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
},
|
},
|
||||||
"prettier.jsxSingleQuote": true,
|
"prettier.jsxSingleQuote": true,
|
||||||
"go.buildFlags": ["-tags=wireinject"],
|
"go.buildFlags": ["-tags=wireinject"],
|
||||||
@@ -231,7 +233,7 @@
|
|||||||
"editor.tabSize": 2,
|
"editor.tabSize": 2,
|
||||||
"editor.autoIndent": "advanced",
|
"editor.autoIndent": "advanced",
|
||||||
"diffEditor.ignoreTrimWhitespace": false,
|
"diffEditor.ignoreTrimWhitespace": false,
|
||||||
"editor.defaultColorDecorators": "never",
|
"editor.defaultColorDecorators": "never"
|
||||||
},
|
},
|
||||||
"html.format.unformatted": "",
|
"html.format.unformatted": "",
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
@@ -243,34 +245,33 @@
|
|||||||
"name": "Space (Global Leader)",
|
"name": "Space (Global Leader)",
|
||||||
"type": "bind",
|
"type": "bind",
|
||||||
"command": "vspacecode.space",
|
"command": "vspacecode.space",
|
||||||
"when": "editorTextFocus || explorerViewletVisible || terminalFocus",
|
"when": "editorTextFocus || explorerViewletVisible || terminalFocus"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"keys": "w.t",
|
"keys": "w.t",
|
||||||
"name": "Toggle Terminal",
|
"name": "Toggle Terminal",
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "workbench.action.terminal.toggleTerminal",
|
"command": "workbench.action.terminal.toggleTerminal"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"keys": "w.w",
|
"keys": "w.w",
|
||||||
"name": "Toggle AI Sidebar",
|
"name": "Toggle AI Sidebar",
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "workbench.action.toggleAuxiliaryBar",
|
"command": "workbench.action.toggleAuxiliaryBar"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"keys": "w.e",
|
"keys": "w.e",
|
||||||
"name": "Focus First Editor Group",
|
"name": "Focus First Editor Group",
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "workbench.action.focusFirstEditorGroup",
|
"command": "workbench.action.focusFirstEditorGroup"
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
"[java]": {
|
"[java]": {
|
||||||
"editor.suggest.snippetsPreventQuickSuggestions": false,
|
"editor.suggest.snippetsPreventQuickSuggestions": false
|
||||||
},
|
},
|
||||||
"git.confirmSync": false,
|
"git.confirmSync": false,
|
||||||
"editor.dropIntoEditor.preferences": [],
|
"editor.dropIntoEditor.preferences": [],
|
||||||
"whichkey.bindingOverrides": [],
|
"whichkey.bindingOverrides": [],
|
||||||
"remote.SSH.localServerDownload": "always",
|
|
||||||
"workbench.colorCustomizations": {},
|
"workbench.colorCustomizations": {},
|
||||||
"javascript.format.enable": false,
|
"javascript.format.enable": false,
|
||||||
"typescript.format.enable": false,
|
"typescript.format.enable": false,
|
||||||
@@ -282,8 +283,9 @@
|
|||||||
"ANTHROPIC_DEFAULT_SONNET_MODEL": "MiniMax-M2.1",
|
"ANTHROPIC_DEFAULT_SONNET_MODEL": "MiniMax-M2.1",
|
||||||
"ANTHROPIC_MODEL": "MiniMax-M2.1",
|
"ANTHROPIC_MODEL": "MiniMax-M2.1",
|
||||||
"API_TIMEOUT_MS": "3000000",
|
"API_TIMEOUT_MS": "3000000",
|
||||||
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": 1,
|
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": 1
|
||||||
},
|
},
|
||||||
"claudeCode.preferredLocation": "panel",
|
"claudeCode.preferredLocation": "panel",
|
||||||
"window.autoDetectColorScheme": false,
|
"window.autoDetectColorScheme": false,
|
||||||
|
"vim.disableExtension": true
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -103,7 +103,7 @@ end
|
|||||||
#################################################################
|
#################################################################
|
||||||
# git
|
# git
|
||||||
# alias
|
# alias
|
||||||
alias gitb="git branch --show-current | tr -d '\n' | pbcopy"
|
alias gitb="git branch --show-current | tr -d '\n' | clip-copy.sh"
|
||||||
alias gci="golangci-lint run -c=~/.dotfile/golang/golangci.yml ./..."
|
alias gci="golangci-lint run -c=~/.dotfile/golang/golangci.yml ./..."
|
||||||
alias gmt="go mod tidy"
|
alias gmt="go mod tidy"
|
||||||
alias gtc="go test -gcflags=all=-l -cover ./..."
|
alias gtc="go test -gcflags=all=-l -cover ./..."
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
function pwdc --description 'Copy current directory path to clipboard'
|
||||||
|
set -l dir (pwd -P)
|
||||||
|
if not printf '%s' $dir | clip-copy.sh
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
echo "Copied: "(string replace $HOME '~' $dir)
|
||||||
|
end
|
||||||
Executable
+31
@@ -0,0 +1,31 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Copy stdin to the system clipboard (macOS / Linux X11 / Linux Wayland).
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if command -v pbcopy >/dev/null 2>&1; then
|
||||||
|
pbcopy
|
||||||
|
elif [ "${XDG_SESSION_TYPE:-}" = wayland ] || [ -n "${WAYLAND_DISPLAY:-}" ]; then
|
||||||
|
if command -v wl-copy >/dev/null 2>&1; then
|
||||||
|
wl-copy --no-newline
|
||||||
|
else
|
||||||
|
echo "clip-copy: wl-copy not found (Wayland session)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
elif [ -n "${DISPLAY:-}" ]; then
|
||||||
|
if command -v xclip >/dev/null 2>&1; then
|
||||||
|
xclip -selection clipboard
|
||||||
|
elif command -v xsel >/dev/null 2>&1; then
|
||||||
|
xsel --clipboard --input
|
||||||
|
else
|
||||||
|
echo "clip-copy: xclip or xsel not found (DISPLAY=$DISPLAY)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
elif command -v xclip >/dev/null 2>&1; then
|
||||||
|
xclip -selection clipboard
|
||||||
|
elif command -v xsel >/dev/null 2>&1; then
|
||||||
|
xsel --clipboard --input
|
||||||
|
else
|
||||||
|
echo "clip-copy: no clipboard tool (pbcopy / wl-copy / xclip / xsel)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
Executable
+76
@@ -0,0 +1,76 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 用法:
|
||||||
|
# ./dns-clean.sh # 清理 macOS / Linux 系统 DNS 缓存
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SUDO=""
|
||||||
|
[ "$(id -u)" -ne 0 ] && SUDO="sudo"
|
||||||
|
|
||||||
|
flush_macos() {
|
||||||
|
echo "macOS: 清理 DNS 缓存..."
|
||||||
|
$SUDO dscacheutil -flushcache
|
||||||
|
$SUDO killall -HUP mDNSResponder 2>/dev/null || true
|
||||||
|
$SUDO killall mDNSResponderHelper 2>/dev/null || true
|
||||||
|
echo "macOS DNS 缓存已清理"
|
||||||
|
}
|
||||||
|
|
||||||
|
flush_linux() {
|
||||||
|
local flushed=0
|
||||||
|
|
||||||
|
echo "Linux: 清理 DNS 缓存..."
|
||||||
|
|
||||||
|
if command -v resolvectl &>/dev/null; then
|
||||||
|
if $SUDO resolvectl flush-caches 2>/dev/null; then
|
||||||
|
echo " - systemd-resolved (resolvectl) 缓存已清理"
|
||||||
|
flushed=1
|
||||||
|
fi
|
||||||
|
elif command -v systemd-resolve &>/dev/null; then
|
||||||
|
if $SUDO systemd-resolve --flush-caches 2>/dev/null; then
|
||||||
|
echo " - systemd-resolved (systemd-resolve) 缓存已清理"
|
||||||
|
flushed=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v systemctl &>/dev/null; then
|
||||||
|
if systemctl is-active --quiet nscd 2>/dev/null; then
|
||||||
|
$SUDO systemctl restart nscd
|
||||||
|
echo " - nscd 已重启"
|
||||||
|
flushed=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if systemctl is-active --quiet dnsmasq 2>/dev/null; then
|
||||||
|
$SUDO systemctl restart dnsmasq
|
||||||
|
echo " - dnsmasq 已重启"
|
||||||
|
flushed=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if systemctl is-active --quiet unbound 2>/dev/null; then
|
||||||
|
if command -v rndc &>/dev/null; then
|
||||||
|
$SUDO rndc flush 2>/dev/null && echo " - unbound 缓存已清理" && flushed=1
|
||||||
|
else
|
||||||
|
$SUDO systemctl restart unbound
|
||||||
|
echo " - unbound 已重启"
|
||||||
|
flushed=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$flushed" -eq 0 ]; then
|
||||||
|
echo "未检测到常见 DNS 缓存服务 (systemd-resolved / nscd / dnsmasq / unbound)"
|
||||||
|
echo "若仍有问题,可尝试重启 NetworkManager 或检查本地 DNS 配置"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Linux DNS 缓存已清理"
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$(uname -s)" in
|
||||||
|
Darwin) flush_macos ;;
|
||||||
|
Linux) flush_linux ;;
|
||||||
|
*)
|
||||||
|
echo "错误: 不支持的操作系统: $(uname -s)"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
Executable
+51
@@ -0,0 +1,51 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# 将用户加入 docker 组(免 sudo 使用 docker)
|
||||||
|
# 用法: sudo docker-group <user>
|
||||||
|
# 示例: sudo docker-group xuser
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: sudo docker-group <user>
|
||||||
|
|
||||||
|
将 <user> 加入 docker 组,之后可直接运行 docker(无需 sudo)。
|
||||||
|
|
||||||
|
示例:
|
||||||
|
sudo docker-group xuser
|
||||||
|
|
||||||
|
说明:
|
||||||
|
- 用户需重新登录或 newgrp docker 后生效
|
||||||
|
- 安装 Docker 时 docker-install.sh 只会把当时的 $USER 加入组
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
[[ "${1:-}" == "-h" || "${1:-}" == "--help" ]] && usage
|
||||||
|
[[ $# -eq 1 ]] || usage
|
||||||
|
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
echo "错误: 请使用 sudo 运行,例如: sudo $0 $1"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
user="$1"
|
||||||
|
|
||||||
|
if ! id "$user" &>/dev/null; then
|
||||||
|
echo "错误: 用户不存在: $user"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! getent group docker &>/dev/null; then
|
||||||
|
echo "错误: docker 组不存在,请先安装 Docker(例如运行 docker-install.sh)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if id -nG "$user" | tr ' ' '\n' | grep -qx docker; then
|
||||||
|
echo "用户 $user 已在 docker 组中"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
usermod -aG docker "$user"
|
||||||
|
echo "已将 $user 加入 docker 组"
|
||||||
|
echo "请让用户重新登录,或执行: su - $user -c 'newgrp docker'"
|
||||||
Executable
+97
@@ -0,0 +1,97 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# 为指定用户配置某命令的免密 sudo(写入 /etc/sudoers.d/)
|
||||||
|
# 用法: sudo nosudo <user> <command>
|
||||||
|
# 示例: sudo nosudo xuser docker
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: sudo nosudo <user> <command>
|
||||||
|
|
||||||
|
为 <user> 配置对 <command> 的免密 sudo(NOPASSWD)。
|
||||||
|
|
||||||
|
示例:
|
||||||
|
sudo nosudo xuser docker
|
||||||
|
sudo nosudo xuser /usr/bin/systemctl
|
||||||
|
|
||||||
|
说明:
|
||||||
|
- 每个命令单独一个文件(nosudo-<user>-<命令名>),可多次执行、互不覆盖
|
||||||
|
例如 nosudo xuser kubectl 与 nosudo xuser helm 会各写一条规则,同时生效
|
||||||
|
- 仅允许免密执行解析到的那个可执行文件路径(含子命令参数仍受 sudo 规则约束)
|
||||||
|
- 对 docker,更推荐: sudo docker-group <user>(无需 sudo 即可用 docker)
|
||||||
|
- 删除规则: sudo rm /etc/sudoers.d/nosudo-<user>-<name>
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
[[ "${1:-}" == "-h" || "${1:-}" == "--help" ]] && usage
|
||||||
|
[[ $# -eq 2 ]] || usage
|
||||||
|
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
echo "错误: 请使用 sudo 运行,例如: sudo $0 $*"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -d /etc/sudoers.d ]]; then
|
||||||
|
echo "错误: 未找到 /etc/sudoers.d(当前系统可能不支持此方式)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
user="$1"
|
||||||
|
cmd="$2"
|
||||||
|
|
||||||
|
if ! id "$user" &>/dev/null; then
|
||||||
|
echo "错误: 用户不存在: $user"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$cmd" == /* ]]; then
|
||||||
|
cmd_path="$cmd"
|
||||||
|
else
|
||||||
|
cmd_path="$(command -v "$cmd" 2>/dev/null || true)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$cmd_path" || ! -x "$cmd_path" ]]; then
|
||||||
|
echo "错误: 找不到可执行文件: $cmd"
|
||||||
|
echo "提示: 可先安装该命令,或传入绝对路径,例如 /usr/bin/docker"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
name="$(basename "$cmd_path")"
|
||||||
|
file="/etc/sudoers.d/nosudo-${user}-${name}"
|
||||||
|
|
||||||
|
if [[ -f "$file" ]]; then
|
||||||
|
if grep -qF "NOPASSWD: ${cmd_path}" "$file" 2>/dev/null; then
|
||||||
|
echo "已存在相同规则: $file"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
tmp="$(mktemp)"
|
||||||
|
trap 'rm -f "$tmp"' EXIT
|
||||||
|
|
||||||
|
cat >"$tmp" <<EOF
|
||||||
|
# Managed by nosudo ($0)
|
||||||
|
# user=$user command=$cmd_path
|
||||||
|
${user} ALL=(ALL) NOPASSWD: ${cmd_path}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
if ! visudo -cf "$tmp" >/dev/null; then
|
||||||
|
echo "错误: sudoers 语法校验失败"
|
||||||
|
visudo -cf "$tmp" || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
install -m 0440 -o root -g root "$tmp" "$file"
|
||||||
|
|
||||||
|
echo "已写入: $file"
|
||||||
|
echo "内容: ${user} ALL=(ALL) NOPASSWD: ${cmd_path}"
|
||||||
|
echo ""
|
||||||
|
echo "验证(切换到该用户后):"
|
||||||
|
echo " sudo -u ${user} sudo -n ${cmd_path} version 2>/dev/null || sudo -u ${user} sudo -n ${cmd_path} --help | head -1"
|
||||||
|
if [[ "$name" == "docker" ]]; then
|
||||||
|
echo ""
|
||||||
|
echo "提示: 若希望直接运行 docker(不用 sudo),请执行:"
|
||||||
|
echo " sudo docker-group ${user}"
|
||||||
|
fi
|
||||||
+29
-3
@@ -2,14 +2,40 @@
|
|||||||
|
|
||||||
# 用法:
|
# 用法:
|
||||||
# ./scan-ip.sh # ICMP 扫描本网段在线 IP
|
# ./scan-ip.sh # ICMP 扫描本网段在线 IP
|
||||||
|
# ./scan-ip.sh 10.0.0 # ICMP 扫描指定网段(10.0.0.1-254)
|
||||||
# ./scan-ip.sh 22 # 扫描本网段中 22 端口开放的 IP
|
# ./scan-ip.sh 22 # 扫描本网段中 22 端口开放的 IP
|
||||||
# ./scan-ip.sh 80,443,8080 # 扫描本网段中任一指定端口开放的 IP
|
# ./scan-ip.sh 80,443,8080 # 扫描本网段中任一指定端口开放的 IP
|
||||||
# ./scan-ip.sh 22 10.0.0 # 指定网段前缀(不写则使用本机所在网段)
|
# ./scan-ip.sh 22 10.0.0 # 指定网段前缀 + 端口(顺序不限)
|
||||||
|
# ./scan-ip.sh 10.0.0 22 # 同上
|
||||||
|
|
||||||
PORT_SPEC="$1"
|
|
||||||
PREFIX_ARG="$2"
|
|
||||||
TIMEOUT=1
|
TIMEOUT=1
|
||||||
|
|
||||||
|
is_port_spec() {
|
||||||
|
[[ "$1" =~ ^[0-9]+$ || "$1" =~ ^[0-9]+-[0-9]+$ || "$1" =~ ^[0-9,]+$ ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
is_ip_prefix() {
|
||||||
|
[[ "$1" =~ ^[0-9]{1,3}(\.[0-9]{1,3}){1,3}$ ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
PORT_SPEC=""
|
||||||
|
PREFIX_ARG=""
|
||||||
|
|
||||||
|
if [ -n "$1" ] && is_ip_prefix "$1"; then
|
||||||
|
PREFIX_ARG="$1"
|
||||||
|
[ -n "$2" ] && is_port_spec "$2" && PORT_SPEC="$2"
|
||||||
|
elif [ -n "$1" ]; then
|
||||||
|
is_port_spec "$1" && PORT_SPEC="$1"
|
||||||
|
[ -n "$2" ] && is_ip_prefix "$2" && PREFIX_ARG="$2"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$1" ] && [ -z "$PORT_SPEC" ] && [ -z "$PREFIX_ARG" ]; then
|
||||||
|
echo "错误: 无法识别参数: $1"
|
||||||
|
echo "端口支持: 单端口(22) / 列表(80,443) / 范围(8000-8100)"
|
||||||
|
echo "网段支持: 前缀(10.0.0 或 192.168.1.0)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
if command -v ip &>/dev/null; then
|
if command -v ip &>/dev/null; then
|
||||||
LOCAL_IP=$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d/ -f1 | head -n 1)
|
LOCAL_IP=$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d/ -f1 | head -n 1)
|
||||||
elif command -v ifconfig &>/dev/null; then
|
elif command -v ifconfig &>/dev/null; then
|
||||||
|
|||||||
+13
@@ -14,5 +14,18 @@ else
|
|||||||
echo "[zsh] Oh My Zsh 未安装,请运行: bash ~/.dotfile/script/zsh-init.sh" >&2
|
echo "[zsh] Oh My Zsh 未安装,请运行: bash ~/.dotfile/script/zsh-init.sh" >&2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# 复制当前 git 分支名到剪贴板(macOS / Linux)
|
||||||
|
gitb() {
|
||||||
|
git branch --show-current | tr -d '\n' | clip-copy.sh
|
||||||
|
}
|
||||||
|
|
||||||
|
# 复制当前目录到剪贴板(macOS / Linux)
|
||||||
|
pwdc() {
|
||||||
|
local dir
|
||||||
|
dir="$(pwd -P)"
|
||||||
|
printf '%s' "$dir" | clip-copy.sh || return 1
|
||||||
|
echo "Copied: ${dir/#$HOME/~}"
|
||||||
|
}
|
||||||
|
|
||||||
# 本机私有配置(不纳入 dotfile)
|
# 本机私有配置(不纳入 dotfile)
|
||||||
[[ -f "$HOME/.zshrc.local" ]] && source "$HOME/.zshrc.local"
|
[[ -f "$HOME/.zshrc.local" ]] && source "$HOME/.zshrc.local"
|
||||||
|
|||||||
Reference in New Issue
Block a user