【问题标题】:how to use sudo command in jenkins exec command如何在 jenkins exec 命令中使用 sudo 命令
【发布时间】:2013-09-26 04:24:44
【问题描述】:

我正在使用 jenkins 运行我的构建。

我的步骤之一是复制某些文件并使用 sudo 将它们放在 /etc/init 中

    <exec command="ssh -A ${host-used} '/etc/init.d/ConvertDaemon stop'" outputProperty="result" escape="false">
    </exec>
    <echo msg="${result}" />

    <exec command="ssh -A ${host-used} 'sudo Console/cake init_runners copy_runners_into_initd'" outputProperty="result" escape="false" />
    <echo msg="${result}" />

${host-used} returns www-data@ip-address

问题是第二个命令。

当我运行第一个命令时,我可以在 jenkins 的控制台日志中看到我的结果。

对于第二个命令,我收到 no tty present 消息

所以我将第二个命令更改为

    <exec command="ssh -t ${host-used} -A ${host-used} 'sudo Console/cake init_runners copy_runners_into_initd'" outputProperty="result" escape="false" />
    <echo msg="${result}" />

我得到一个

 Pseudo-terminal will not be allocated because stdin is not a terminal

我该如何克服这个问题?

更新:

我也试过这个。

    <exec command="ssh -t -t ${host-used} -A ${host-used} 'sudo Console/cake init_runners copy_runners_into_initd'" outputProperty="result" escape="false" />
    <echo msg="${result}" />

我明白了:

bash: www-data@ipaddress: command not found
Connection to ipaddress closed.

我想强调的是,该命令使用正确。但我无法阅读该消息。


更新 2:

有时你会问一个问题,但随后你会意识到你想问的问题并不是你想解决的REAL问题。

这个问题是这样的。

我想要做的就是执行一些由 jenkins 运行的命令并查看命令的打印输出。这些命令恰好需要 sudo。

Jenkins 基本上 ssh 作为另一个用户 www-data 来执行这些命令。

对于需要 sudo 的命令,我无法在 jenkins 中打印结果。

在度过了一个愉快的星期六并提供了一些非常有用的 SO 答案后,我意识到我可以简单地尝试在不使用 sudo 的情况下执行这些命令,而是让 jenkins ssh 作为 root。

成功了。

我将用这种方法来回答这个问题,因为这就是我想要的——在 jenkins 中执行一些命令并查看它们的打印输出。

【问题讨论】:

  • 看起来你可能需要在你的 ssh 命令上添加一个额外的 -t 参数,根据这个问题的答案:stackoverflow.com/questions/7114990/…
  • 我试过了。它失败了。更新了我的问题,@AaronGolden

标签: linux bash shell jenkins


【解决方案1】:

虽然我知道 OP 只是想测试一些东西,但允许任何用户无密码 ssh 访问 root 可能会被安全意识所反对。我发现 igor-chubin 可能是让 jenkins 在this answer 中以提升的权限运行特定命令/脚本的最可靠方法。

【讨论】:

    【解决方案2】:

    Jenkins 无法打印出使用 sudo 执行的某些命令的结果。

    因此,最好的方法是简单地允许 jenkins 以 root 身份 ssh 以执行相同的命令而无需 sudo。

    1. 允许 jenkins 用户以 root 身份 ssh,无需密码。
    2. 阅读this 了解如何在没有密码的情况下进行 ssh 登录。
    3. 然后,像这样编写命令: <exec command="ssh -A ${root-used} 'Console/cake init_runners copy_runners_into_initd'" outputProperty="result" escape="false" /> <echo msg="${result}" />

    请注意,${root-used} 的值应类似于 root@ipaddress

    【讨论】:

    • 很高兴您的工作正常,如果您仍在尝试,请阅读我的更新答案
    • 我仍然是,@vahid。如果有更好更安全的,我会采纳的。
    【解决方案3】:

    如果用于连接的用户是交互式帐户,Jenkins 将无法执行sudo 命令。这可以通过将 sudoer 广告设为非交互式来解决。

    在目标 linux 机器上试试这个命令:

    echo "%sudo ALL=(ALL) NOPASSWD: *command*" >> /etc/sudoers
    

    【讨论】:

    • 您应该改用$ sudo visudo 命令编辑sudoers 文件。
    【解决方案4】:

    正在登录的用户没有可用的命令。

    如果您查看错误,它已连接无法运行命令并已断开连接

    我的意思不是 sudo,我的意思是你在 sudo 之后做了什么

    Console/cake init_runners copy_runners_into_initd
    

    如果您实际上以用户身份 ssh 并运行上述命令,它可能会起作用,但不是通过您的 jenkins 脚本,因为您可能缺少一些环境变量,这些环境变量是在您正常 ssh 时定义的,并且获得一个会话。

    我建议使用所有内容的完整路径,包括:

    哪个sudo

    sudo is /usr/bin/sudo
    

    sudo 的完整路径可以放心,与此无关。

    更新

    你好基姆西亚

    感谢您的回复,现在确认您已修复,我仍然认为您对 sudo 所做的事情缺少一些东西,因为返回消息明确指出找不到命令。在我看来,虽然您运行了 sudo,但您实际所在的路径无法运行控制台/蛋糕,即找不到命令!

    如果您仍然想使用 sudo 路线,可以尝试一些方法,因为我相信安全方面比打开 root ssh 访问更安全。

    1. 使用 -i 运行 sudo 以获取 root 的配置文件,然后实际将目录更改为控制台文件夹和 cake 命令所在的位置。

    1. 难道不能写一个 sudo 所在的 shell 脚本吗
    #!/bin/bash
    function ssh_and_run_cake() { 
    
     echo "Working on $hostname --- $instance --::"
     $ssh -t $hostname "sudo su -i '
        echo \"CD Folder run cake init -----------------\";
        cd /path/to/cakephp/app; 
        Console/cake init_runners copy_runners_into_initd;
        echo \"All done------------------------\";
     '";
    
    }
    
    function rollout_cake() {
    
       #for hostname in ${h[@]}; do
    
    
            hostname="yourhost"
    
            ssh_and_run_cake
      # done
    
    }
    

    推出蛋糕

    并且从 jenkins 网络界面使用执行 shell 脚本,然后应该调用这个脚本并执行你想要的。

    我已经看到 Jenkins 使用这种方法工作得很好

    只要您在第二个函数中定义主机名,就可以更新 shell 脚本。

    然后您需要使用 jenkins Web 前端部署选项来执行 shell 脚本并定义完整路径脚本。脚本应该在 jenkins 服务器的本地文件系统上

    【讨论】:

    • 我尝试将 sudo 重命名为 /usr/bin/sudo。我得到了相同的结果:(
    • 感谢您的回答。但我尝试了一种完全不同的方法,我得到了我想要的。干杯!
    • ssh -t -t -A ${host-used} 出于某种原因这导致我的詹金斯挂了很长时间
    • 如果您仍然想走 sudo 路线,可以尝试一些事情,因为我相信安全方面比打开 root ssh 访问更安全。
    【解决方案5】:

    我认为您不需要指定主机两次。

    <exec command="ssh -t -t -A ${host-used} 'sudo Console/cake init_runners copy_runners_into_initd'" outputProperty="result" escape="false" />
    <echo msg="${result}" />
    

    【讨论】:

    • 我试过这个,詹金斯在这里挂了很长时间
    • @kimsia 它可能真的需要输入。如果它没有得到它需要的任何东西,它可能会永远等待。你可以试试&lt;exec command="ssh -t -t -A ${host-used} 'screen -dm sudo Console/cake init_runners copy_runners_into_initd'" outputProperty="result" escape="false" /&gt;
    • 我试过 ssh -t -t -A ${host-used} 'screen -dm 还是挂了
    • 我试过 ssh -t -t ${host-used} -A ${host-used} 'screen -dm.它没有挂起,但也无法生成结果。
    • 感谢您的回答。但我尝试了一种完全不同的方法,我得到了我想要的。干杯!
    猜你喜欢
    • 2014-05-17
    • 2019-05-29
    • 2014-07-28
    • 1970-01-01
    • 2016-03-19
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 2018-11-17
    相关资源
    最近更新 更多