env.shell doesn't work properly on FreeBSD #1374

Closed
hyperknot opened this Issue Sep 6, 2015 · 8 comments

Projects

None yet

4 participants

@hyperknot

As based on the FAQ, when using Fabric with a FreeBSD host, it needs

env.shell = "/bin/sh -c"

However this doesn't work. Basic run commands are ok, but append and echo $0 and echo $SHELL are not.

code:

env.shell = "/bin/sh -c"

def get_shell():
    run('echo $0')
    run('echo $SHELL')
    append('a', 'b')

output:

[freebsd-virtualbox] run: echo $0
[freebsd-virtualbox] out: csh
[freebsd-virtualbox] out:

[freebsd-virtualbox] run: echo $SHELL
[freebsd-virtualbox] out: /bin/csh
[freebsd-virtualbox] out:

[freebsd-virtualbox] run: echo 'b' >> "$(echo a)"
[freebsd-virtualbox] out: Unmatched ".
[freebsd-virtualbox] out:


Fatal error: run() received nonzero return code 1 while executing!

Requested: echo 'b' >> "$(echo a)"
Executed: /bin/sh -c "echo 'b' >> \"\$(echo a)\""

The fix is to manually change the user's shell with chsh to sh or bash: chsh -s /bin/sh or chsh -s /usr/local/bin/bash

After this and a reconnect Fabric actually works, with the following output:

[freebsd-virtualbox] Executing task 'get_shell'
[freebsd-virtualbox] run: echo $0
[freebsd-virtualbox] out: /bin/sh
[freebsd-virtualbox] out:

[freebsd-virtualbox] run: echo $SHELL
[freebsd-virtualbox] out: /usr/local/bin/bash
[freebsd-virtualbox] out:

[freebsd-virtualbox] run: echo 'b' >> "$(echo a)"

I guess the question is that why doesn't env.shell change the shell when it's called on csh.

@bitprophet
Member

Is this because FreeBSD's /bin/sh is actually cshell? Otherwise I don't quite get what's going on.

Also not sure what your question means exactly, are you asking why Fabric isn't trying to be more dynamic about which shell it selects?

@hyperknot

I'm reporting that Fabric doesn't work on a stock FreeBSD install, even with env.shell = "/bin/sh -c".

For example append('/dev/null', 'test') doesn't work

[freebsd-virtualbox] run: echo 'test' >> "$(echo /dev/null)"
[freebsd-virtualbox] out: Unmatched ".
[freebsd-virtualbox] out:


Fatal error: run() received nonzero return code 1 while executing!

Requested: echo 'test' >> "$(echo /dev/null)"
Executed: /bin/sh -c "echo 'test' >> \"\$(echo /dev/null)\""

The only way Fabric works properly under FreeBSD is if the user's shell is changed with chsh before connecting.

@bitprophet
Member

Strange; even on Linux distros where /bin/sh is actually a limited shell and isn't just a link to bash/fish/whatever, this hasn't been an issue. I assume BSD's /bin/sh is of a pretty different lineage, though.

Re: env.shell not taking effect, I wonder if that has something to do with the sshd involved; for 2.0 we're actually planning to drop the shell wrapping altogether because we found most sshds invoke a shell behind the scenes anyways.

If you do env.use_shell = False, are things any better? If I had to guess, I'd guess that FBSD's sshd (or its packaging of openssh) is using the same, limited shell, so...probably not. But worth trying.

@hyperknot

env.shell does take effect, but somehow only partly. It makes it work, but append still doesn't work.

def test_stock():
    run('uptime')

def test_noshell():
    with settings(use_shell=False):
        run('uptime')
        append('/dev/null', 'test')

def test_sh():
    with settings(shell="/bin/sh -c"):
        run('uptime')
        append('/dev/null', 'test')

test_stock: /bin/bash: Command not found.
test_noshell, test_sh: uptime ok

test_noshell append:

[freebsd-virtualbox] run: echo 'test' >> "$(echo /dev/null)"
[freebsd-virtualbox] out: Illegal variable name.
[freebsd-virtualbox] out:


Fatal error: run() received nonzero return code 1 while executing!

Requested: echo 'test' >> "$(echo /dev/null)"
Executed: echo 'test' >> "$(echo /dev/null)"

test_sh append:

[freebsd-virtualbox] run: echo 'test' >> "$(echo /dev/null)"
[freebsd-virtualbox] out: Unmatched ".
[freebsd-virtualbox] out:


Fatal error: run() received nonzero return code 1 while executing!

Requested: echo 'test' >> "$(echo /dev/null)"
Executed: /bin/sh -c "echo 'test' >> \"\$(echo /dev/null)\""

Possibly BSDploy developers have some experience with this.

@hyperknot

OK, some more information:

with settings(use_shell=False):
    run('yes')

with chsh: csh
image

with chsh: bash
image

with settings(shell="/bin/sh -c"):
    run('yes')

with chsh: csh
image

with chsh: bash
image

with settings(shell='/usr/local/bin/bash -l -c'):
    run('yes')

with chsh: csh
image

with chsh: bash
image

For me the conclusion is something like while chsh is set to csh everything works really differently, than when it's set to bash. It's also weird that when configured to use bash/sh, neither bash nor sh is anywhere visible in ps aux.

@Russell-Jones

What if you do the same kind of thing with "ssh -t" ? e.g. ssh -t
"/usr/local/bin/bash -l -c 'yes'"

Russell

On 15 September 2015 at 00:37, Zsolt Ero notifications@github.com wrote:

OK, some more information:

with settings(use_shell=False):
run('yes')

with chsh: csh
[image: image]
https://cloud.githubusercontent.com/assets/494223/9864334/c92d2e5a-5b48-11e5-9cdf-6acb77dbb3b4.png

with chsh: bash
[image: image]
https://cloud.githubusercontent.com/assets/494223/9864388/5408f964-5b49-11e5-8143-1c436eb4d40c.png

with settings(shell="/bin/sh -c"):
run('yes')

with chsh: csh
[image: image]
https://cloud.githubusercontent.com/assets/494223/9864348/e49409de-5b48-11e5-816f-e57001835928.png

with chsh: bash
[image: image]
https://cloud.githubusercontent.com/assets/494223/9864401/7ec694d6-5b49-11e5-8a25-e1edca0c66fd.png

with settings(shell='/usr/local/bin/bash -l -c'):
run('yes')

with chsh: csh
[image: image]
https://cloud.githubusercontent.com/assets/494223/9864368/24dbdd64-5b49-11e5-9a23-7ffb69f2bd8e.png

with chsh: bash
[image: image]
https://cloud.githubusercontent.com/assets/494223/9864409/9ac3e8c8-5b49-11e5-82ac-1ab5013054f7.png

For me the conclusion is something like while chsh is set to csh
everything works really differently, than when it's set to bash. It's
also weird that when configured to use bash/sh, neither bash nor sh is
anywhere visible in ps aux.


Reply to this email directly or view it on GitHub
#1374 (comment).

@mradziej
mradziej commented Jul 7, 2016

I had similar problems and found a fix: You need to set backslash_quote in csh. This might be a default on some systems and obscuring the problem. See pull request #1483 .Feedback welcome.

@bitprophet
Member

Going to roll this into #1483 too.

@bitprophet bitprophet closed this Jul 19, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment