bash 如何在 jenkins exec 命令中使用 sudo 命令

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18922564/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 06:38:29  来源:igfitidea点击:

how to use sudo command in jenkins exec command

linuxbashshelljenkins

提问by Kim Stacks

I am using jenkins to run my builds.

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

One of my steps is to copy over certain files and place them inside /etc/init using sudo

我的步骤之一是复制某些文件并使用 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

The issue is the 2nd command.

问题是第二个命令。

When I run the 1st command, i can see my result printed out in the console log in jenkins.

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

For the 2nd command, I get a no tty presentmessage

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

So I changed the 2nd command to

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

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

I get a

我得到一个

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

How do I overcome this?

我该如何克服?

UPDATE:

更新:

I tried this as well.

我也试过这个。

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

I got:

我有:

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

I want to emphasize that the command is correctly used. BUT I cannot read the message.

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



UPDATE2:

更新2:

There are times when you ask a question, but then you realize the question you want to ask is not the REALquestion you want to solve.

有时您提出问题,但随后您意识到您想问的问题并不是您想要解决的真正问题。

This question is like that.

这个问题是这样的。

All I wanted to do is to execute a few commands run by jenkins and see the print out of the commands. These commands happen to require sudo.

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

Jenkins basically ssh as another user www-data to perform these commands.

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

I was having trouble with printing out the results in jenkins for those commands requiring sudo.

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

Having spent a lovely saturday working on this with some very helpful SO answers, I realized that I could simply try to execute those commands without sudo by having jenkins ssh as root instead.

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

It worked.

有效。

I am going to answer this question with that approach instead because that is all I wanted -- execute some commands inside jenkins and see their print out.

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

采纳答案by Kim Stacks

Jenkins cannot print out the result of certain commands that are executed using sudo.

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

Hence the best way is to simply allow jenkins to ssh as root to perform those same commands without sudo.

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

  1. Allow jenkins user to ssh as root without password required.
  2. Read thison how to have ssh login without password.
  3. Then, write the command like so: <exec command="ssh -A ${root-used} 'Console/cake init_runners copy_runners_into_initd'" outputProperty="result" escape="false" /> <echo msg="${result}" />
  1. 允许 jenkins 用户以 root 身份进行 ssh,无需密码。
  2. 阅读关于如何有ssh登录不需要密码。
  3. 然后,像这样编写命令: <exec command="ssh -A ${root-used} 'Console/cake init_runners copy_runners_into_initd'" outputProperty="result" escape="false" /> <echo msg="${result}" />

Note that ${root-used}should have a value like root@ipaddress

请注意,${root-used}应该有一个值root@ipaddress

回答by V H

The user that is sshing in does not have the command available.

sshing in 的用户没有可用的命令。

If you look at error it connected could not run command and disconnected

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

By this I don't mean sudo I mean what you have done after sudo

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

Console/cake init_runners copy_runners_into_initd

It may be that if you actually ssh in as the user and run the above command it works but not via your jenkins script because it may be that you are missing some environment variables that is defined when you ssh in as per normal and get a session.

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

I would suggest using full paths to everything including:

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

which sudo

哪个须藤

sudo is /usr/bin/sudo

The full path to sudo to rest assured its nothing to do with that.

确保 sudo 的完整路径与此无关。

UPDATED

更新

Hi Kimsia

嗨Kimsia

Thanks for commenting back and now confirming you have a fix, I still think there is something missing from what you have done with sudo since the return message clearly states command not found. To me it would appear that although you ran sudo the path you were actually in could not run console/cake i.e. command not found !

感谢您的回复,现在确认您已修复,我仍然认为您对 sudo 所做的事情中缺少一些东西,因为返回消息明确指出未找到命令。在我看来,虽然您运行了 sudo,但您实际所在的路径无法运行 console/cake ie command not found !

A few things to try if you still wanted to go down the sudo route since I do believe security wise its a lot safer than opening root ssh access.

如果您仍然想走 sudo 路线,可以尝试一些事情,因为我确实相信安全性比打开 root ssh 访问要安全得多。

  1. run sudo with -i to take on root's profile and then actually change directory to where Console folder and cake command reside.
  1. 使用 -i 运行 sudo 以获取 root 的配置文件,然后实际将目录更改为 Console 文件夹和 cake 命令所在的位置。

<exec command="ssh -t -t -A ${host-used} 'sudo -i cd /path/to/cakephp/app; Console/cake init_runners copy_runners_into_initd'" outputProperty="result" escape="false" />

<exec command="ssh -t -t -A ${host-used} 'sudo -i cd /path/to/cakephp/app; Console/cake init_runners copy_runners_into_initd'" outputProperty="result" escape="false" / >

  1. Would it not be possible to write a shell script which sudo's in
  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

}

rollout_cake

#!/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

and from jenkins web interface use the execute shell script which should then call this script and carry out what you want.

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

I have seen Jenkins work away fine with this method

我已经看到詹金斯用这种方法工作得很好

Updated the shell script to work so long as you define hostname in 2nd function.

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

You would then need to use jenkins web front end deploy options to execute shell script and define the fullpath script. The script should be on the local file system of jenkins server

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

回答by konsolebox

I don't think you need to specify your host twice.

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

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

回答by user3444343

Jenkins cannot execute sudocommand if the user used to connect is interactive account. This can be fixed by making the sudoer ad non-interactive.

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

Try this command on target linux box:

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

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

回答by GMeister

Although I know the OP simply wanted to test something, allowing any user passwordless ssh access to root is probably going to be frowned upon by the security conscious. I found that igor-chubin had probably the soundest approach to allowing jenkins to run specific commands/scripts with elevated privileges in this answer.

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