【动机】
与 linux 远程服务器,例如常见的 ECS 通信,不外乎连接,登录(可选是否使用 key),修改 ssh 端口号,上传,下载,运行程序等操作,这些操作如果不用图形界面的程序进行,而是仅仅在客户端控制台上运行命令是可行的,但是需要记住所有的命令细节(或者随时准备翻看自己的“命令笔记”),如何在不使用图形界面的情况下,简化这些操作?
阅读更多:三 linux 远程服务器的常用操作封装【意图】
将所有的需要的命令细节封装起来,以菜单项的形式展示然后运行。例如配置使用密钥登录:
- 核实服务器是否存在公钥文件,如存在责删除脏记录(如果有);
- 检查客户端是否存在密钥文件,不存在则使用 ssh-keygen 生成密钥对;
- 使用 sshpass 结合 ssh-copy-id 复制公钥到远程服务器,即将新的公钥记录重写入服务器公钥文件;
- 确保客户端 ssh 配置文件正确。
将其封装到一个函数 key_enable 中即可。
【实现】
此处仅展示入口脚本 main.sh,完整的打包后的脚本,参见源码下载。
#!/bin/bash
# rely:
# 1. sshpass: 将密码命令
set -e
# global constant:
declare -r __DEBUG__=
declare -r ROOT_DIR_PATH=$(dirname $(readlink -f $0))
declare -r ROOT_DIR_NAME=$(basename $ROOT_DIR_PATH)
declare -r ENTRY_FILE_NAME=${BASH_SOURCE[0]##*/}
declare -r ENTRY_FILE_PATH=$ROOT_DIR_PATH/$ENTRY_FILE_NAME
declare -r TARGET_EXE_NAME=${ENTRY_FILE_NAME%.*}
declare -r CONFIG_FILE_REL_PATH="data/config.json"
declare -r CONFIG_FILE_PATH="$ROOT_DIR_PATH/$CONFIG_FILE_REL_PATH"
declare -r DEFAULT_CONFIG_ROOT="default"
# 根据当前脚本与 library 和 execution 的相对位置, .. 可能有所变化
declare -r LNX_LIB_DIR="$ROOT_DIR_PATH/../../library"
declare -r TARGET_EXE_PATH="$ROOT_DIR_PATH/../../execution/$ROOT_DIR_NAME/$TARGET_EXE_NAME"
# region Sourcing
# 块 source, 详情查看 library/doc/compile.txt
for file in \
$(find $ROOT_DIR_PATH \
-type f -regex .*?\.sh$ \
-not -wholename "$ENTRY_FILE_PATH" ) \
$(find $LNX_LIB_DIR \
-type f -regex .*?\.sh$ ) ; do
source $file
done
# endregion Sourcing
declare __JSON_CONTENT__=$(jq . $CONFIG_FILE_PATH)
[ -z "$__JSON_CONTENT__" ] && error "$json.config 尚未准备好!" && exit 0
__TEST__=
# 如果采用 [ ... ] && ... || ... 的形式, 当 choose_ecs 退出码非 0 时,
# 将继续执行 unit_test_start, 这可能不是需要的
if [ -z "$__TEST__" ]; then
clear
choose_ecs
else
unit_test_start
fi
# [ -z "$__TEST__" ] && choose_ecs || unit_test_start
aop success left "Thanks for your use. Byebye!"
# region Ignored
# 自编译部分, 详情查看 library/doc/compile.txt
# 一般只有 -a 部分需要修改, 即使保存原样, 最多是 error.log 中增加了记录
if [ "$1" ]; then
keep_config_secret
menu "start compiling ..."
cmdline="script2execution
--target-path \"$TARGET_EXE_PATH\"
--attaches \"$CONFIG_FILE_REL_PATH\"
--cmdline-when-over keep_config_secret
--give-up-self-compile
"
perform --prompt "编译中, 请稍候......" --cmdline "$cmdline" -d 0.2
aop "success -e" center "Compiling finished."
# 恢复本地 json 文件
echo $__JSON_CONTENT__ | jq . > $CONFIG_FILE_PATH --tab
fi
#endregion Ignored
文件 config.json,用于保存远程服务器属性,以及脚本用到的变量:
{
"default": {
"sshd": {
"key": {
"filepath": "~/.ssh/authorized_keys"
},
"config": {
"filepath": "/etc/ssh/sshd_config",
"allowpath": "/etc/hosts.allow",
"denypath": "/etc/hosts.deny",
"login": {
"welcome": {
"dirname": "update-motd.d",
"sysparent": "/etc",
"bakparent": "/app/freezone/etc"
}
}
}
},
"ssh": {
"keygen": {
"defaultpath": "~/.ssh",
"dirpath": "/app/freezone/.ssh",
"filenamefmt": "%s_rsa",
"commentfmt": "login to %s ecs",
"configfilename": "hosts"
}
},
"code": {
"reboottimeout": 26,
"cmdtimeout": 10,
"prompt": {
"configerror": "server and (or) client config error, please check these files:",
"tasksuccess": "congratulations! All the work has been done successfully."
},
"deploy": {
"server": {
"app": "/app/freezone/execution",
"lib": "obsoleted"
},
"client": {
"apps": "/mnt/d/Estate/asset/OS/linux/execution/wordpress_in_docker",
"libs": "obsoleted"
}
},
"relies": "bc jq bypy docker rsync"
}
},
"huawei": {
"sshd": {
"config": {
"login": {
// "user": "远程登录服务器使用的用户名待填入",
// "password": "远程登录服务器使用的用户名对应的密码待填入",
"port": {
"default": 22,
// "custom": "自定义的 ssh 登录使用的端口待填入"
},
// "addr": "远程服务器的外网 ip 或者域名待填入"
},
// "title": "远程服务器名称,用于标识服务器待填入"
}
}
},
"ali": {
"sshd": {
"config": {
"login": {
// "user": "远程登录服务器使用的用户名待填入",
// "password": "远程登录服务器使用的用户名对应的密码待填入",
"port": {
"default": 22,
// "custom": "自定义的 ssh 登录使用的端口待填入"
},
// "addr": "远程服务器的外网 ip 或者域名待填入"
},
// "title": "远程服务器名称,用于标识服务器待填入"
}
}
},
"tencent": {
"sshd": {
"config": {
"login": {
// "user": "远程登录服务器使用的用户名待填入",
// "password": "远程登录服务器使用的用户名对应的密码待填入",
"port": {
"default": 22,
// "custom": "自定义的 ssh 登录使用的端口待填入"
},
// "addr": "远程服务器的外网 ip 或者域名待填入"
},
// "title": "远程服务器名称,用于标识服务器待填入"
}
}
}
}
被 // 注释的行,需要根据实际情况修改。
【效果】
完成的基本操作是:
- ssh 端口切换(在自定义端口和标准22号端口之间)
- 启用(停用) ssk key 登录
- 启用(停用)服务器的远程登录欢迎信息
- 上传(下载)脚本或者其他任何文件
- 打开远程终端,在此可以执行以上未包含的操作。
谢谢收看!