【问题标题】:Running a local script with local files as parameters through ssh通过 ssh 运行以本地文件为参数的本地脚本
【发布时间】:2018-05-07 20:16:46
【问题描述】:

我今天很难处理 ssh 和 bash。我需要运行一个脚本,它的参数是本地文件,通过 ssh 连接运行。这是处理 ssh 连接的脚本:

#!/bin/bash
if [ $# -ne 3 ]
then
    echo "Incorrect number of parameters"
    exit
fi
cat "$3" | while read line; 
do 
    ssh -o ConnectTimeout=5 -i ./private_key as@$line < ./mod_users.sh "$1" "$2"
    if [ $? -ne 0 ]
    then
        echo "$line is not accesible" 
    fi
done

“$2”参数是我正在执行 ssh 的机器中的本地文件。脚本“mod_users.sh”添加或删除了从“$2”读取的一组用户。

我要做的是通过 ssh 执行脚本“mod_users.sh”,并从联网的机器上批量添加或删除用户。此外,如您所见,我将连接的所有机器都包含我的公钥,因此我通过私钥/公钥对进行连接,这样远程机器就不会要求输入密码。

希望这是足够的信息。如果您需要任何额外的东西,请提出要求,我很乐意回答。

编辑:另外,是否可以在远程机器上使用 sudo 运行脚本?

【问题讨论】:

  • ssh ... ./private_key as@$line &lt; ./mod_users.sh "$1" "$2"ssh ... ./private_key as@$line "$1" "$2" &lt;mod_users.sh 完全相同,除了仅限于 bash(POSIX 仅要求 shell 在行尾支持重定向)。这真的是您想要的吗(将 mod_users 脚本的文本作为 SSH 进程的输入提供?)
  • 是的,这正是我想要的,提供文本并在远程机器上执行它,但使用本地文件来获取信息
  • 为什么您的mod_users.sh 需要远程运行?如果您修改它以执行 Sasha 假设您首先想要的操作(使用本地文件生成远程命令,而不是在本地运行命令),这对您的用例有用吗?请注意,在 bash 中安全地生成远程命令需要一些注意——甚至不要echo "useradd $username";相反,printf 'useradd %q\n' "$username" 以确保安全地转义替换的值。
  • 谢谢,我试试

标签: bash ssh


【解决方案1】:

据我了解,mod_users.sh 和 arg $1 是本地文件,mod_users.sh 为远程机器生成命令。

您应该执行以下操作:

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

您也可以在其中添加 sudo:

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

如果您想更安全并为特定命令授予 sudo 权限,请尝试以下操作:

./mod_users.sh "$1" "$2" | sed 's/^/sudo /'| ssh -o ConnectTimeout=5 -i ./private_key as@$line bash

它将在 mod_users.sh 生成的任何行之前插入 sudo。但可能最好的方法是修补 mod_users.sh。

【讨论】:

  • 那行不通。现在它会输出一个错误说“条件二元运算符预期”。我知道它与其他脚本无关,因为它在本地机器上运行良好
  • 你也应该替换 $?如果 [ $? -ne 0 ];你有管道命令,这就是为什么你应该使用 ${PIPESTATUS[1]}。 unix.stackexchange.com/questions/14270/…
【解决方案2】:

如果您将mod_users.sh 更改为接受$2 中文件的文本,而不是文件的名称,并且如果您的远程用户的shell 是bash(不是/bin/sh),你可以这样做:

ssh_args=( -o ConnectTimeout=5 -i ./private_key )
while IFS= read -r line <&3; do 
    printf -v args_q '%q ' "$1" "$(<"$2")"
    if ! ssh "${ssh_args[@]}" "as@$line" "bash -s $args_q" <mod_users.sh; then
        echo "Operation failed for $line" >&2 
    fi
done 3<"$3"

如果您不愿意对磁盘上的文件进行更改,可以将适当的前缀修补到管道中:

script_prefix='
tempfile=$(mktemp -t input.XXXXXX) || exit
trap '$'\'rm -f "$tempfile"\''' EXIT
printf "%s\n" "$2" >"$tempfile" || exit
set -- "$1" "$tempfile"
'

ssh_args=( -o ConnectTimeout=5 -i ./private_key )
while IFS= read -r line <&3; do 
    printf -v args_q '%q ' "$1" "$(<"$2")"
    if ! ssh "${ssh_args[@]}" "as@$line" "bash -s $args_q" \
            < <(printf '%s\n' "$script_prefix"; cat mod_users.sh); then
        echo "Operation failed for $line" >&2 
    fi
done 3<"$3"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多