8

I need to use "&&" to execute multiple commands in one step. So I create factory as below:

f1 = factory.BuildFactory()
f1.addStep(shell.ShellCommand, command=["sh", "-c", "pwd", "&&", "cd", "/home/xxx/yyy", "&&", "pwd"])

But during execution it's found that buildbot processes it as below, which makes it impossible to execute

sh -c pwd '&&' cd /home/xxx/yyy '&&' pwd

What I expected is

sh -c pwd && cd /home/xxx/yyy && pwd

Could anyone help me out of this please? Thanks.

LeonH
  • 1,039
  • 2
  • 22
  • 45
Di Liu
  • 111
  • 5

1 Answers1

7

Since you're using /bin/sh anyway just call it with a single string:

f1.addStep(shell.ShellCommand, command="pwd && cd /home/xxx/yyy && pwd")

As documentation says:

The ShellCommand arguments are:

command

a list of strings (preferred) or single string (discouraged) which specifies the command to be run. A list of strings is preferred because it can be used directly as an argv array. Using a single string (with embedded spaces) requires the buildslave to pass the string to /bin/sh for interpretation, which raises all sorts of difficult questions about how to escape or interpret shell metacharacters.

It's not recommended but you'd still need the shell anyway as && is only interpreted within the shell. Calling sh would just be redundant.

konsolebox
  • 72,135
  • 12
  • 99
  • 105
  • I had a try and found that this command with "&&" in it would be interpreted as `'pwd && cd /home/xxx/yyy && pwd'`, not `pwd && cd /home/xxx/yyy && pwd`. So it won't work. I doubt that buildbot treats characters like "&&" in a special way. Thanks anyway. – Di Liu Aug 15 '14 at 04:40
  • 2
    @DiLiu Try passing it not as a single element of an array but as a string. See update. I think I just misinterpreted `a list of strings (preferred) or single string (discouraged)`. – konsolebox Aug 15 '14 at 04:45
  • 1
    You are right. I had a try and your updated command works. Thanks a lot for your great help. – Di Liu Aug 15 '14 at 08:52
  • Doesn't this assume a shell on the slave? How does this behave on a windows build slave? – qneill Mar 20 '15 at 13:56
  • @qneill You should use a list of strings then. `sh` and `pwd` would have to exist on the windows machine. I can only imagine how the software works so perhaps you can try `command=["C:/Path/To/sh.exe", "-c", "pwd && cd /home/xxx/yyy && pwd"]`. If you're trying to make it portable, it would be difficult since even if you decide to use `cmd.exe` over `sh.exe`, the syntax and path forms would be different. It actually depends on how you want to implement your commands. Also, it's already legitimate to post another question about it since it's already about running on a different platform. – konsolebox Mar 21 '15 at 07:57