vars=' servers=("192.168.1.2") user=fxts source=/app/manager target=/rg/ sourceFile=lpaList targetFile=lppaList cmdFile=a.sh startFile=run.sh ' strFormat=' remoteCMD(){ cd ${target} cp ${targetFile} ${targetFile}.$(date +%F) cat ${sourceFile} >> ${targetFile} /usr/bin/bash ${cmdFile} cd sbin pkill -f nginx out=$(/usr/bin/bash ${startFile} start) if echo $out |grep "emerg";then exit 3 fi } ' jserver=172.17.69.1 tserver=172.17.86.21 ssh -o ConnectTimeout=10 ${user}@${jserver} " ssh \"${user}@$tserver\" \" eval ${vars} eval ${strFormat} \" " 执行后终端卡在172.17.86.21,退不出来
#!/bin/bash # --- 本地解析的部分 --- target="/rg" startFile="run.sh" backup_time=$(date +%F) # 本地时间戳 # --- 构造脚本:本地变量已展开,远程命令保留 \$ --- script=" set -x cd $target cp lppaList lppaList.$backup_time cat lpaList >> lppaList /usr/bin/bash a.sh cd sbin pkill -f nginx || true out=\$(/usr/bin/bash ../$startFile start) # \$ 让远程执行 if echo \"\$out\" | grep -q emerg; then exit 3 fi " # --- 安全发送到远程 --- ssh deploy@web01 "bash -c $(printf '%q' "$script")"
或
# 本地变量 target="/rg" startFile="run.sh" # 注意:远程要执行的命令中,如果本身有 $(比如 awk '{print $1}'),需要写成 \$ ssh user@remote bash <<EOF set -x cd $target cp file file.$(date +%F) # ← 这个 $(...) 在本地执行 out=\$(/usr/bin/bash $startFile start) # ← \$ 防止本地执行,让远程执行 if echo "\$out" | grep -q emerg; then exit 3 fi EOF
或
#!/bin/bash # 定义变量和函数(用单引号,防止本地展开) vars=' servers=("192.168.1.2") user=fxts source=/app/manager target=/rg/ sourceFile=lpaList targetFile=lppaList cmdFile=a.sh startFile=run.sh ' strFormat=' remoteCMD(){ cd "${target}" cp "${targetFile}" "${targetFile}.$(date +%F)" cat "${sourceFile}" >> "${targetFile}" /usr/bin/bash "${cmdFile}" cd sbin pkill -f nginx || true out=$(/usr/bin/bash "${startFile}" start) if echo "$out" | grep -q "emerg"; then exit 3 fi } remoteCMD # 👈 别忘了调用! ' jserver=172.17.69.1 tserver=172.17.86.21 user=fxts # 构造要在 tserver 上执行的完整脚本 full_script="$vars"$'\n'"$strFormat" # 通过跳板机执行:本地 -> jserver -> tserver ssh -o ConnectTimeout=10 "${user}@${jserver}" \ "ssh \"${user}@${tserver}\" \"bash -c \$(printf '%q' '$full_script')\""
或
#!/bin/bash # ============================== # 1. 在本地定义配置变量(集中管理) # ============================== USER="fxts" SOURCE="/app/manager" TARGET="/rg/" SOURCE_FILE="lpaList" TARGET_FILE="lppaList" CMD_FILE="a.sh" START_FILE="run.sh" # ============================== # 2. 在本地定义要执行的函数逻辑(纯字符串) # 注意:使用单引号,内部用 \$ 防止本地展开 # ============================== define_remote_function() { cat <<'EOF' remoteCMD() { cd "${TARGET}" cp "${TARGET_FILE}" "${TARGET_FILE}.$(date +%F)" cat "${SOURCE_FILE}" >> "${TARGET_FILE}" /usr/bin/bash "${CMD_FILE}" cd sbin pkill -f nginx || true out=$(/usr/bin/bash "${START_FILE}" start 2>&1) if echo "$out" | grep -q "emerg"; then exit 3 fi } EOF } # ============================== # 3. 构造完整的远程脚本(变量声明 + 函数 + 调用) # ============================== build_remote_script() { cat <<EOF # --- 变量定义(由本地注入) --- USER='$USER' SOURCE='$SOURCE' TARGET='$TARGET' SOURCE_FILE='$SOURCE_FILE' TARGET_FILE='$TARGET_FILE' CMD_FILE='$CMD_FILE' START_FILE='$START_FILE' # --- 函数定义 --- $(define_remote_function) # --- 执行 --- remoteCMD EOF } # ============================== # 4. 通用执行函数:通过跳板机执行到目标服务器 # ============================== deploy_to_target() { local jserver="$1" local tserver="$2" local remote_script remote_script=$(build_remote_script) ssh -o ConnectTimeout=10 "${USER}@${jserver}" \ "ssh \"${USER}@${tserver}\" \"bash -c \$(printf '%q' '$remote_script')\"" } # ============================== # 5. 多次调用(复用同一套变量和函数) # ============================== deploy_to_target "172.17.69.1" "172.17.86.21" deploy_to_target "172.17.69.1" "172.17.86.22" deploy_to_target "172.17.70.1" "172.17.87.10"
或
# 第一次:上传变量配置 config_script=$(cat <<'EOF' servers=("192.168.1.2") user=fxts source=/app/manager target=/rg/ sourceFile=lpaList targetFile=lppaList cmdFile=a.sh startFile=run.sh EOF ) ssh -o ConnectTimeout=10 "${user}@${jserver}" \ "ssh \"${user}@${tserver}\" 'echo $(printf '%q' "$config_script") > /tmp/deploy.conf'" # 后续任意次数使用: ssh -o ConnectTimeout=10 "${user}@${jserver}" \ "ssh \"${user}@${tserver}\" bash" <<'EOF' source /tmp/deploy.conf # 现在可以直接用 $target, $startFile 等 cd "$target" ... EOF
或
# 生成完整脚本(含变量赋值)
cat > /tmp/deploy.sh <<EOF
target="/rg"
targetFile="lppaList"
sourceFile="lpaList"
cmdFile="a.sh"
startFile="run.sh"
remoteCMD(){
cd "\${target}"
cp "\${targetFile}" "\${targetFile}.\$(date +%F)"
cat "\${sourceFile}" >> "\${targetFile}"
/usr/bin/bash "\${cmdFile}"
cd sbin
pkill -f nginx
out=\$(/usr/bin/bash "\${startFile}" start)
if echo "\$out" | grep -q "emerg"; then
exit 3
fi
}
remoteCMD
EOF
# 上传并执行
scp /tmp/deploy.sh "${user}@${tserver}:/tmp/"
ssh "${user}@${tserver}" "bash /tmp/deploy.sh"