关于linux:如何在jenkins exec命令中使用sudo命令

how to use sudo command in jenkins exec command

我用詹金斯管理我的建筑。

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

1
2
3
4
5
6
7
8
    <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消息

所以我把第二个命令改为

1
2
    <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}" />

我得到了

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

我如何克服这个问题?

更新:

我也试过了。

1
2
    <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}" />

我得到:

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

我想强调的是命令的使用是正确的。但我看不到留言。

更新2:

有时你会问一个问题,但当你意识到你想问的问题不是你想解决的真正问题时。

这个问题是这样的。

我只想执行詹金斯运行的一些命令,并查看命令的打印输出。这些命令正好需要sudo。

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

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

在花了一个愉快的星期六的时间,用一些非常有用的so答案来解决这个问题之后,我意识到我可以简单地尝试不使用sudo来执行这些命令,而是使用jenkins ssh作为根。

它奏效了。

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


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

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


正在sshing中的用户没有可用的命令。

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

我不是说sudo我是说你在sudo之后做了什么

1
Console/cake init_runners copy_runners_into_initd

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

我建议使用所有路径,包括:

哪一个

1
sudo is /usr/bin/sudo

通往苏多安息之路的完整路径确保了它与此无关。

更新的

嗨,Kimsia

感谢您的评论,现在确认您有一个修复,我仍然认为您所做的sudo有一些遗漏,因为返回消息清楚地表明命令找不到。在我看来,虽然您运行sudo,但实际上所在的路径无法运行console/cake,即找不到命令!

如果你还想沿着sudo路径走,可以尝试一些方法,因为我相信安全性比打开根ssh访问要安全得多。

  • 使用-i运行sudo以获取根目录的配置文件,然后将目录实际更改为console文件夹和cake命令所在的位置。
  • 是否不可能写一个sudo所在的shell脚本?
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    #!/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

    }

    rollout_cake

    从Jenkins Web界面使用execute shell脚本,然后该脚本将调用该脚本并执行您想要的操作。

    我见过詹金斯用这种方法工作得很好

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

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


    虽然我知道OP只是想测试一些东西,但是允许任何用户无密码的ssh访问根目录可能会受到安全意识的限制。我发现,igor chubin可能是允许Jenkins在这个答案中以更高的权限运行特定命令/脚本的最可靠的方法。


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

    在目标Linux设备上尝试此命令:

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


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

    因此,最好的方法就是简单地允许Jenkins以ssh作为根来执行那些没有sudo的命令。

  • 允许Jenkins用户将ssh作为根用户,而不需要密码。
  • 阅读下面的内容,了解如何在没有密码的情况下登录ssh。
  • 然后,编写如下命令:

  • 注意,${root-used}的值应该与root@ipaddress的值相同。