【问题标题】:Some Output Lost in Command Passed to SSH传递给 SSH 的命令中的某些输出丢失
【发布时间】:2017-12-07 19:23:52
【问题描述】:

我正在尝试使用 ssh 命令通过 ssh 连接到服务器并运行我传递给它的useradd 命令。大多数情况下它似乎运行正常(没有产生错误),但/etc/shadow 文件中的散列密码缺少盐(我相信这是缺少的部分。 em>)。

我不确定引用是否不正确。但是在服务器上手动运行这个命令可以正常工作,所以我假设它的扩展搞砸了。?

以下命令在 Bash 脚本中运行...

命令:

ssh user@$host "useradd -d /usr/local/nagios -p $(perl -e 'print crypt("mypassword", "\$6\$salt");') -g nagios nagios && chown -R nagios:nagios /usr/local/nagios"

*当我在 perl 单行内转义双引号时,我得到错误:

在 -e 第 1 行的 EOF 之前的任何位置都找不到字符串终止符 '"'。

用法:useradd [options] LOGIN

知道我在这里做错了什么吗?

【问题讨论】:

    标签: bash ssh parameter-expansion


    【解决方案1】:

    与其将整个命令括在双引号中并确保正确转义其中的所有内容,使用单引号会更加健壮,并根据需要处理嵌入的单引号。 事实上,没有嵌入式单引号可以处理, 仅在 $6$salt 中嵌入文字 $

    ssh "user@$host" 'useradd -d /usr/local/nagios -p $(perl -e "print crypt(q{mypassword}, q{\$6\$salt});") -g nagios nagios && chown -R nagios:nagios /usr/local/nagios'
    

    【讨论】:

    • Perl 方便地为您提供通用引号,因此无需在 Perl sn-p 中使用单引号或双引号。 perl -e 'print crypt(q{mypassword}, qq{$6$salt}});' 并稍加混淆,您甚至可以挤出剩余的空白,因此您根本不需要引用脚本。
    • 感谢@tripleee,这确实允许一些简化
    • 谢谢各位,非常感谢!我从 useradd 返回一个错误,不是错误,而是一个不正确的命令,因为它只是返回 useradd 帮助信息。我试过ssh user@host 'useradd -d /usr/local/nagios -p $(perl -e "print crypt(q{mypassword}, q{$6$salt});")' -g nagios nagios
    • @Matt 它可能不只是输出帮助信息。仔细看看,尤其是前几行。通常这是他们写错误信息的地方。其实我明白了什么是错的。您没有执行我回答中的代码。你没有取消引用$6$salt。因此,这些变量在ssh shell 中可能是空的。如果它们是空的,那就是不合适的盐,crypt 将返回一个空字符串。如果crypt 返回空字符串,那么useradd-p 参数的值将为空,这是无效的(可能是你的错误信息)。
    • @Matt 这里好像有误会。那么$6$salt 不是shell 变量吗?这真的是盐吗?在这种情况下,我们需要以不同的方式引用:ssh "user@$host" 'useradd -d /usr/local/nagios -p $(perl -e "print crypt(q{mypassword}, q{\$6\$salt});") -g nagios nagios && chown -R nagios:nagios /usr/local/nagios'
    【解决方案2】:
    echo "useradd -d /usr/local/nagios -p $(perl -e 'print crypt("mypassword", "\$6\$salt");') -g nagios nagios && chown -R nagios:nagios /usr/local/nagios" > /tmp/tempcommand && scp /tmp/tempcommand root@server1:/tmp && ssh server1 "sh -x /tmp/tempcommand && finger nagios && rm /tmp/tempcommand"
    

    在这种情况下,我总是喜欢在执行命令集的本地/远程服务器上拥有一个本地文件。节省大量“报价调试时间”。我在上面所做的首先将长单行保存到本地文件,“按原样”和“按原样”在本地保存,使用 scp 将其复制到远程服务器并使用 shell 在那里执行它。 更安全的方式(无需复制文件)。再次 - 将其保存在本地并使用 -s 选项将其传递给远程 bash:

    echo "useradd -d /usr/local/nagios -p $(perl -e 'print crypt("mypassword", "\$6\$salt");') -g nagios nagios && chown -R nagios:nagios /usr/local/nagios" > /tmp/tempcommand && echo finger nagios >> /tmp/tempcommand && ssh server1 'bash -s' < /tmp/tempcommand
    

    【讨论】:

    • 欢迎来到 StackOverlfow。那是一条很长的线。你能解释一下里面发生了什么吗? stackoverflow.com/help/how-to-answer
    • @Matt WOW,293 个字符!没有人有时间尝试理解这一点,即使是看起来的 OP。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-21
    • 2013-12-28
    • 2021-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多