首页 问答 脚本有哪些问题?
问题详情
复制代码
user=fxts
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”

版权:言论仅代表个人观点,不代表官方立场。转载请注明出处:https://www.stntk.com/question/244.html

发表评论
暂无评论

还没有评论呢,快来抢沙发~

点击联系客服

在线时间:8:00-16:00

客服QQ

70068002

客服电话

400-888-8888

客服邮箱

70068002@qq.com

扫描二维码

关注微信公众号

扫描二维码

手机访问本站