You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:通过SSH运行携带本地文件参数的本地脚本遇问题

解决SSH远程执行脚本时传递本地文件参数的问题

我来帮你拆解下当前遇到的问题,然后给出几个可行的解决方案:

原脚本的核心问题分析

你当前的写法:

ssh -o ConnectTimeout=5 -i ./private_key as@$line < ./mod_users.sh "$1" "$2"

存在两个关键问题:

  1. "./mod_users.sh" 通过标准输入传递给SSH,远程机器会执行这个脚本,但后面的 "$1" 和 "$2" 是本地Shell解析的参数——远程机器拿到的只是本地的$1值和本地文件名($2),但远程机器上根本没有这个本地文件,所以脚本执行时会报错找不到文件。
  2. SSH的标准输入已经被./mod_users.sh占用了,没办法同时把本地文件的内容传递给远程脚本。

解决方案1:先上传文件到远程,再执行脚本(最可靠,适合大文件)

这种方法的思路是先用scp把本地文件传到远程机器的临时目录,然后让远程脚本使用这个远程路径作为参数,执行完成后可以删除临时文件。修改后的脚本如下:

#!/bin/bash
if [ $# -ne 3 ]
then
    echo "Incorrect number of parameters"
    exit 1
fi

# 定义本地文件路径和远程临时文件路径
LOCAL_FILE="$2"
REMOTE_TEMP_FILE="/tmp/$(basename "$LOCAL_FILE")"

cat "$3" | while read line; do
    # 第一步:上传本地文件到远程临时目录
    scp -o ConnectTimeout=5 -i ./private_key "$LOCAL_FILE" as@$line:"$REMOTE_TEMP_FILE"
    if [ $? -ne 0 ]; then
        echo "$line: Failed to upload local file"
        continue
    fi

    # 第二步:远程执行脚本,传入参数和远程临时文件路径
    ssh -o ConnectTimeout=5 -i ./private_key as@$line "./mod_users.sh" "$1" "$REMOTE_TEMP_FILE"
    if [ $? -ne 0 ]; then
        echo "$line: Failed to access or script execution failed"
    else
        # 可选:脚本执行成功后删除远程临时文件
        ssh -o ConnectTimeout=5 -i ./private_key as@$line "rm -f $REMOTE_TEMP_FILE"
    fi
done

优点:

  • 适合任何大小的文件,不会因为内容特殊字符出问题
  • 逻辑清晰,排查问题简单

解决方案2:把文件内容作为参数传递(适合小文件)

如果你的本地文件内容不大,且没有太多特殊字符(比如换行、引号),可以直接把文件内容读入变量,作为参数传递给远程脚本:

#!/bin/bash
if [ $# -ne 3 ]
then
    echo "Incorrect number of parameters"
    exit 1
fi

# 读取本地文件内容到变量
FILE_CONTENT=$(cat "$2")

cat "$3" | while read line; do
    # 把文件内容作为参数传递给远程脚本
    ssh -o ConnectTimeout=5 -i ./private_key as@$line "./mod_users.sh" "$1" "$FILE_CONTENT"
    if [ $? -ne 0 ]; then
        echo "$line is not accessible or script failed"
    fi
done

注意事项:

  • 如果文件包含特殊字符(比如换行、双引号、反斜杠),可能会导致参数解析错误,这时候可以用base64编码来避免:
    # 本地编码文件内容
    FILE_CONTENT=$(base64 "$2")
    
    # 远程脚本里需要解码使用:
    # echo "$2" | base64 -d > temp_file
    

解决方案3:通过SSH多路复用优化性能(可选)

如果你的目标机器很多,每次SSH和SCP都建立新连接会很慢,可以开启SSH多路复用,复用同一个连接来传输文件和执行命令,提升效率:

在脚本开头添加以下配置(或者写在~/.ssh/config里):

# 开启SSH连接复用
SSH_OPTIONS="-o ConnectTimeout=5 -i ./private_key -o ControlMaster=auto -o ControlPath=/tmp/ssh-%r@%h:%p -o ControlPersist=60s"

然后后续的scp和ssh都使用$SSH_OPTIONS:

scp $SSH_OPTIONS "$LOCAL_FILE" as@$line:"$REMOTE_TEMP_FILE"
ssh $SSH_OPTIONS as@$line "./mod_users.sh" "$1" "$REMOTE_TEMP_FILE"

这样所有针对同一机器的操作都会复用同一个SSH连接,节省连接建立的时间。

内容的提问来源于stack exchange,提问作者Enrique Torres

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:39:42