New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

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

Comments

Projects
None yet
4 participants
@hyperknot

hyperknot commented Sep 6, 2015

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

This comment has been minimized.

Member

bitprophet commented Sep 8, 2015

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

This comment has been minimized.

hyperknot commented Sep 8, 2015

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

This comment has been minimized.

Member

bitprophet commented Sep 10, 2015

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

This comment has been minimized.

hyperknot commented Sep 11, 2015

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

This comment has been minimized.

hyperknot commented Sep 14, 2015

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

This comment has been minimized.

Russell-Jones commented Sep 17, 2015

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

This comment has been minimized.

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

This comment has been minimized.

Member

bitprophet commented Jul 19, 2016

Going to roll this into #1483 too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment