跳到主要内容

3 篇博文 含有标签「ssh」

查看所有标签

· 阅读需 5 分钟
He Wei

SSH 登录后执行 zip 命令

公司阿里云 Windows 服务器上的日志需要每个月归档一下,以前都是手动操作,最近感觉太麻烦,于是研究了一下自动化的方案,因此有了这篇文章。

万事不决问 Kimi,这篇文章的主要思路和解决方案都是 Kimi 给出的,谨表谢意。

最开始给出的方案是 ssh -t ecs '...',经过研究,ssh -t 会为命令创建一个伪终端,这样命令就可以在远程服务器上以交互模式运行。

之前给另一个前端项目写的命令是调用 rm 来删除文件,这个命令在 Windows 服务器上能运行,说明调用的是服务器上的 git bash 带的命令。

但是 git bash 默认不带 zip 命令,于是搜索 git bash zip command pass variable 这组关键词之后,看到了 How to add man and zip to "git bash" installation on Windows 这篇文章,按照文章里的方法,给 git bash 安装了 zip 命令。

虽然 zip 命令安装成功了,但是执行 ssh -t ecs 'zip ...' 的时候,既不会报错,也不会执行命令。

经过研究,发现命令是没问题的,只不过 -t 参数加上之后会让命令无法执行。

于是干脆去掉这个参数,直接执行 ssh ecs '...',这样命令就能正常执行了。

将前一个月的年份和月份作为变量传递

由于需要归档的是服务器上前一个月各网站的 IIS 日志,所以需要将前一个月的年份和月份作为变量传递给远程服务器上的命令。

结合 Kimi 和 Cursor 给出的方案,最终用下面的代码实现了需求:

# 获取上一个月的年份和月份
# 即使本月是 1 月,上一个月也会自动计算为前一年的 12 月
YYYY=$(date -d "$(date) -1 month" "+%Y")
YY=$(date -d "$(date) -1 month" "+%y")
MM=$(date -d "$(date) -1 month" "+%m")

拿到了年份和月份,在 bash 中就可以用 ${YYYY}${YY}${MM} 的方式来使用了。

将指定目录下匹配规则的文件进行压缩

这个需求很简单,指定目录下的目标文件名符合 u_exYYMMDD.log 的格式,这样的文件可以用 u_ex${YY}${MM}* 的方式来匹配。

因为需要压缩后删除源文件,所以用 zip -m 参数来压缩。

另外压缩时不需要带上文件的目录结构,所以用 -j 参数。

这样完整的 zip 命令就是 zip -mj ${ZIP_FILE} ${LOG_DIR}/u_ex${YY}${MM}*

将多个目录下的文件压缩到多个对应的目录中

IIS 为每个网站创建的日志目录格式是 W3SVC1W3SVC2 这种,而自己用来存放压缩后的每个月日志的目录格式是 W3SVC1_aaaaW3SVC2_bbbb 这种,所以需要将每个网站的日志压缩到对应的目录中。

问了一下 kimi,给出了下面的方案,很好用。

declare -A websites
websites["W3SVC2"]="aaaa"
websites["W3SVC3"]="bbbb"
......

然后就可以用下面的语句来遍历这个数组,执行压缩命令了。

for index in "${!websites[@]}"; do
ZIPFILE_DIR="/path/of/archive/${index}_${websites[$index]}"
LOG_DIR="/path/of/logs/${index}"
ZIP_FILE="${ZIPFILE_DIR}/${YYYY}-${MM}.zip"

# 构建压缩命令
# -m 表示压缩后删除源文件
# -j 表示压缩时不带目录结构
CMD="ssh ecs1 \"zip -mj ${ZIP_FILE} ${LOG_DIR}/u_ex${YY}${MM}*\""

# 执行压缩命令
echo ""
echo "正在归档网站 ${websites[$index]} $YYYY年$MM月的日志..."
eval $CMD
done

总结

  • ssh ecs '...' 的方式执行命令,命令中需要用到变量时,需要用 ${...} 的方式来获取。
  • declare -A 的方式来定义数组,用 websites["W3SVC1"]="aaaa" 的方式来给数组赋值,用 websites[$index] 的方式来获取数组的值。
  • for index in "${!websites[@]}"; do ... done 的方式来遍历数组。
  • eval 的方式来执行命令。
  • zip -mj ${ZIP_FILE} ${LOG_DIR}/u_ex${YY}${MM}* 的方式来压缩并删除源文件。

· 阅读需 1 分钟
He Wei

无效命令

  1. rm + Windows 格式的路径 ssh -t ecs1 "'rm -r e:\upcweb\uppbook\yd\_nuxt\*'"

有效命令

  1. rm + Linux 格式的路径 ssh -t ecs1 "'rm -r /e/upcweb/uppbook/yd/_nuxt/*'"

注意:按照 这里 的说明,需要执行的命令先用双引号包裹,然后再用单引号包裹,这样才能成功执行。

· 阅读需 3 分钟
He Wei

需求

由于现在的项目分布在不同的 GitHub 账号下,如果在本地的 Git 全局配置中记录其中一个 GitHub 账号的信息,那么在与 GitHub 同步另一个账号下的项目时,每次都会弹出烦人的对话框,询问要选择哪个 GitHub 账号进行同步。

解决过程

上网搜索了一下,得知 GitHub 官方就提供这种解决方案。

简单来说就是在本地新建一个 SSH key,把私钥添加到本地的 ssh-agent,再把公钥添加到 GitHub 对应的账号下面。然后用 GitHub 项目的 SSH 链接来 fork 项目,之后在与 GitHub 同步项目的时候,就不会弹出烦人的对话框了。

新建 SSH key

参考 Generating a new SSH key and adding it to the ssh-agent,在 ~\.ssh 目录下面执行命令 ssh-keygen -t ed25519 -C "your_email@example.com" 一路回车,按默认设置来即可。

如果不按默认设置来,手动修改了生成的 SSH key 的名称,那么在后面将私钥添加到本地的 ssh-agent 这一步时会失败。

将私钥添加到 ssh-agent

执行 Adding your SSH key to the ssh-agent 这里的步骤即可。

将公钥添加到 GitHub

Adding a new SSH key to your GitHub account 这里的流程来即可。

测试 SSH 配置是否有效

Testing your SSH connection 这里的步骤操作即可。

如果报错,可以先在官方文档的 Troubleshooting SSH 这一节查找对应报错信息。

有时候因为众所周知的网络原因,执行测试命令失败,可以按照 这里 的方法配置一下 SSH,然后再测试,应当就 OK 了。

注意

有时候将一台电脑上生成的 SSH key 复制到另一台电脑上,再按照上面的流程配置,发现不能用。那就按照上面的流程重新生成新的 SSH key,再把公钥添加到 GitHub 即可。