postmodern / chruby

Changes the current Ruby
MIT License
2.88k stars 189 forks source link

chruby-exec -- bash: no job control in this shell #290

Open ronen opened 10 years ago

ronen commented 10 years ago

This has been raised before in #119 and #192, but I find it's happening again(?) or still(?). I just started using chruby today; I installed chruby on OS X via homebrew,chruby-exec --version reports chruby version 0.3.8

I've got a script to run some non-interactive tests in various ruby environments. My script creates child processes such as

/usr/bin/env BUNDLE_GEMFILE=path-to-gemfile SHELL=/usr/bin/bash chruby-exec 1.9.3 -- bundle install

and when they run they yield the error message:

bash: no job control in this shell

but aside from that appear to function properly. I don't normally use bash interactively, so my .bashrc is entirely empty except for

source /usr/local/share/chruby/chruby.sh

(Without including that in my .bashrc, I get bash: chruby: command not found)

Since chruby-exec is basically working this isn't critical, but it'd be nice to have clean output.

Thanks!

postmodern commented 10 years ago

What does chruby-exec --version return? This should have been fixed in >= 0.3.6.

ronen commented 10 years ago

It writes chruby version 0.3.8

postmodern commented 10 years ago

I cannot seem to reproduce this with chruby 0.3.8 on my Fedora system.

$ git clone https://github.com/postmodern/test.git
$ cd test/ruby/bundler
$ cat <<EOS > script.sh
#!/usr/bin/env bash
env BUNDLE_GEMFILE=$PWD/Gemfile SHELL=/usr/bin/bash chruby-exec 1.9.3 -- bundle install
EOS
$ chmod +x script.sh
$ ./script.sh
Using rake 10.3.2
Using json 1.8.1
Using bundler 1.6.2
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.

@ronen could you run the scripts/bug_report.sh to collect more environment information?

postmodern commented 10 years ago

@ronen also could you post which chruby-exec and cat $(which chruby-exec). The fact that removing source /path/to/chruby.sh caused chruby-exec to to not find chruby makes me think you might be using an older chruby-exec in another bin/ directory.

ronen commented 10 years ago

Sorry for the delay, I took a detour upgrading to OS X 10.10 Yosemite. Unfortunately the OS upgrade didn't make this issue go away.

The fact that removing source /path/to/chruby.sh caused chruby-exec to to not find chruby makes me think you might be using an older chruby-exec in another bin/ directory.

That's the only chruby-exec in my path, it's one I just installed via homebrew. Here's the details:

$ chruby-exec --version
chruby version 0.3.8
$ which -a chruby-exec
/usr/local/bin/chruby-exec
$ cat $(which chruby-exec)
#!/usr/bin/env bash

source "${0%/*}/../share/chruby/chruby.sh"

case "$1" in
    -h|--help)
        echo "usage: chruby-exec RUBY [RUBYOPTS] -- COMMAND [ARGS...]"
        exit
        ;;
    -V|--version)
        echo "chruby version $CHRUBY_VERSION"
        exit
        ;;
esac

if (( $# == 0 )); then
    echo "chruby-exec: RUBY and COMMAND required" >&2
    exit 1
fi

argv=()

for arg in $@; do
    shift

    if [[ "$arg" == "--" ]]; then break
    else                          argv+=($arg)
    fi
done

if (( $# == 0 )); then
    echo "chruby-exec: COMMAND required" >&2
    exit 1
fi

command="chruby $argv && $*"

if [[ -t 0 ]]; then exec "$SHELL" -i -l -c "$command"
else                exec "$SHELL"    -l -c "$command"
fi
ronen-macbook-pro➜  ~ $

and here's the bug report info:

$ source ~/Downloads/bug_report.sh

## System

    Darwin ronen-macbook-pro 14.0.0 Darwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64 x86_64
    GNU bash, version 3.2.53(1)-release (x86_64-apple-darwin14) [/bin/bash]
    zsh 5.0.7 (x86_64-apple-darwin14.0.0) [/usr/local/bin/zsh]
    ruby 2.0.0p481 (2014-05-08 revision 45883) [universal.x86_64-darwin14] [/usr/bin/ruby]
    chruby version 0.3.8 [/usr/local/bin/chruby-exec]

## Environment

    CHRUBY_VERSION=0.3.8
    SHELL=/usr/local/bin/zsh
    PATH=/Users/ronen/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/share/npm/bin:/usr/texbin:/Users/ronen/current-focus/adobe/sc_sdk/scripts/unix:/Users/ronen/current-focus/adobe/sc_sdk/workers/dependencies/third_party/apache-maven-3.0/bin
    HOME=/Users/ronen
    RUBIES=(/Users/ronen/.rubies/ruby-2.1.2)
    RUBY_ROOT=
    RUBY_VERSION=
    RUBY_ENGINE=
    RUBY_AUTO_VERSION=ruby-2.1.3
    RUBYLIB=
    RUBYOPT=
    RUBYPATH=
    RUBYSHELL=
    GEM_ROOT=
    GEM_HOME=
    GEM_PATH=

## Hooks

    preexec_functions=(omz_termsupport_preexec chruby_auto)
    precmd_functions=(omz_termsupport_precmd _direnv_hook)

## .ruby-version

    ruby-2.1.3

## Aliases

    -='cd -'
    ..='cd ..'
    ...='cd ../..'
    1='cd -'
    2='cd -2'
    3='cd -3'
    4='cd -4'
    5='cd -5'
    6='cd -6'
    7='cd -7'
    8='cd -8'
    9='cd -9'
    _=sudo
    afind='ack-grep -il'
    annotate=bundled_annotate
    be='bundle exec'
    bi=bundle_install
    bl='bundle list'
    bo='bundle open'
    bp='bundle package'
    bu='bundle update'
    cap=bundled_cap
    capify=bundled_capify
    cd..='cd ..'
    cd...='cd ../..'
    cd....='cd ../../..'
    cd.....='cd ../../../..'
    cd/='cd /'
    cucumber=bundled_cucumber
    d='dirs -v | head -10'
    dv='dirs -v'
    foodcritic=bundled_foodcritic
    g=git
    ga='git add'
    gap='git add --patch'
    gb='git branch'
    gba='git branch -a'
    gbr='git branch --remote'
    gc='git commit -v'
    'gc!'='git commit -v --amend'
    gca='git commit -v -a'
    'gca!'='git commit -v -a --amend'
    gcl='git config --list'
    gclean='git reset --hard && git clean -dfx'
    gcm='git checkout master'
    gcmsg='git commit -m'
    gco='git checkout'
    gcount='git shortlog -sn'
    gcp='git cherry-pick'
    gcs='git commit -S'
    gd='git diff'
    gdc='git diff --cached'
    gdt='git difftool'
    gg='git gui citool'
    gga='git gui citool --amend'
    ggpnp='git pull origin $(current_branch) && git push origin $(current_branch)'
    ggpull='git pull origin $(current_branch)'
    ggpur='git pull --rebase origin $(current_branch)'
    ggpush='git push origin $(current_branch)'
    gignore='git update-index --assume-unchanged'
    gignored='git ls-files -v | grep "^[[:lower:]]"'
    git-svn-dcommit-push='git svn dcommit && git push github master:svntrunk'
    gk='gitk --all --branches'
    gl='git pull'
    glg='git log --stat --max-count=10'
    glgg='git log --graph --max-count=10'
    glgga='git log --graph --decorate --all'
    glo='git log --oneline --decorate --color'
    globurl='noglob urlglobber '
    glog='git log --oneline --decorate --color --graph'
    glp=_git_log_prettily
    gm='git merge'
    gmt='git mergetool --no-prompt'
    gp='git push'
    gpoat='git push origin --all && git push origin --tags'
    gr='git remote'
    grba='git rebase --abort'
    grbc='git rebase --continue'
    grbi='git rebase -i'
    grh='git reset HEAD'
    grhh='git reset HEAD --hard'
    grmv='git remote rename'
    grrm='git remote remove'
    grset='git remote set-url'
    grt='cd $(git rev-parse --show-toplevel || echo ".")'
    grup='git remote update'
    grv='git remote -v'
    gsd='git svn dcommit'
    gsps='git show --pretty=short --show-signature'
    gsr='git svn rebase'
    gss='git status -s'
    gst='git status'
    gsta='git stash'
    gstd='git stash drop'
    gstp='git stash pop'
    gsts='git stash show --text'
    gts='git tag -s'
    guard=bundled_guard
    gunignore='git update-index --no-assume-unchanged'
    gunwip='git log -n 1 | grep -q -c "\-\-wip\-\-" && git reset HEAD~1'
    gup='git pull --rebase'
    gvt='git verify-tag'
    gwc='git whatchanged -p --abbrev-commit --pretty=medium'
    gwip='git add -A; git ls-files --deleted -z | xargs -r0 git rm; git commit -m "--wip--"'
    history='fc -l 1'
    irb=bundled_irb
    j=jobs
    jekyll=bundled_jekyll
    kitchen=bundled_kitchen
    knife=bundled_knife
    l='ls -lah'
    la='ls -lAh'
    lf='ls -F'
    ll='ls -lh'
    ls='ls -G'
    lsa='ls -lah'
    md='mkdir -p'
    middleman=bundled_middleman
    nanoc=bundled_nanoc
    please=sudo
    po=popd
    pry=bundled_pry
    pu=pushd
    puma=bundled_puma
    rackup=bundled_rackup
    rainbows=bundled_rainbows
    rake=bundled_rake
    rd=rmdir
    rrm=/bin/rm
    rspec=bundled_rspec
    sc='source ~/.zshrc'
    shotgun=bundled_shotgun
    sidekiq=bundled_sidekiq
    spec=bundled_spec
    spork=bundled_spork
    spring=bundled_spring
    strainer=bundled_strainer
    tailor=bundled_tailor
    taps=bundled_taps
    thin=bundled_thin
    thor=bundled_thor
    unicorn=bundled_unicorn
    unicorn_rails=bundled_unicorn_rails
    which-command=whence
ronen commented 10 years ago

@postmodern no wonder you couldn't reproduce it--turns out it doesn't reproduce easily! I noticed that it works fine from the command line and in other test scripts. Just one particular script was causing trouble. So I simplified down what was happening in that script to trigger the errors. Here's what I found.

$ SHELL=/bin/bash chruby-exec 2.1.3 -- date
bash: chruby: command not found
$
$ SHELL=/bin/bash /bin/bash -c 'chruby-exec 2.1.3 -- date 2>&1 | cat'
bash: no job control in this shell
bash: chruby: command not found
$

And here's the version of bash I'm running:

$ /bin/bash --version
GNU bash, version 3.2.53(1)-release (x86_64-apple-darwin14)
Copyright (C) 2007 Free Software Foundation, Inc.

Is this reproducable on Fedora, or is it some sort of OS X quirk?

BTW knowing what triggers the error I was able to jigger my script to avoid it. So this has become even less of an issue for me. From my perspective, it's fine to just mark this issue as "weird" and let it slide.

postmodern commented 10 years ago

I could do not reproduce your last example:

$ SHELL=`which bash` bash -c 'chruby-exec 2.1.3 -- date 2>&1 | cat'
Fri Oct 24 15:56:22 PDT 2014

However, I use bash as my primary shell, where as you use zsh. Also, Fedora ships bash 4.2, so it could be a bash 3.x issue or something specific to your bash configuration. /cc @havenwood can you reproduce this on your OSX system?

havenwood commented 10 years ago

I was able to reproduce this with OS X's latest system bash 3.2.53(1). It doesn't occur on OS X with bash 4.3.30 so seems to be a bash 3 issue.

JuanitoFatas commented 9 years ago

OS X 10.10.1, bash 4.3

SHELL=`which bash` bash -c 'chruby-exec 2.1.3 -- date 2>&1 | cat'
bash: chruby: command not found
$ chruby-exec --version
chruby version 0.3.9
$ which -a chruby-exec
/usr/local/bin/chruby-exec
/usr/local/bin/chruby-exec
$ cat $(which chruby-exec)
#!/usr/bin/env bash
$ source "${0%/*}/../share/chruby/chruby.sh"

case "$1" in
    -h|--help)
        echo "usage: chruby-exec RUBY [RUBYOPTS] -- COMMAND [ARGS...]"
        exit
        ;;
    -V|--version)
        echo "chruby version $CHRUBY_VERSION"
        exit
        ;;
esac

if (( $# == 0 )); then
    echo "chruby-exec: RUBY and COMMAND required" >&2
    exit 1
fi

argv=()

for arg in "$@"; do
    shift

    if [[ "$arg" == "--" ]]; then break
    else                          argv+=($arg)
    fi
done

if (( $# == 0 )); then
    echo "chruby-exec: COMMAND required" >&2
    exit 1
fi

command="chruby $(printf "%q " "${argv[@]}") && $(printf "%q " "$@")"

if [[ -t 0 ]]; then exec "$SHELL" -i -l -c "$command"
else                exec "$SHELL"    -l -c "$command"
fi

$ source ./bug_report.sh

## System

    Darwin Ana.local 14.0.0 Darwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64 x86_64
    GNU bash, version 4.3.33(1)-release (x86_64-apple-darwin14.1.0) [/usr/local/bin/bash]
    zsh 5.0.5 (x86_64-apple-darwin14.0) [/bin/zsh]
    ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin14] [/Users/Juan/.rubies/ruby-2.2.2/bin/ruby]
    Bundler version 1.9.9 [/Users/Juan/.gem/ruby/2.2.2/bin/bundle]
    chruby version 0.3.9 [/usr/local/bin/chruby-exec]

## Environment

    CHRUBY_VERSION=0.3.9
    SHELL=/usr/local/bin/zsh
    PATH=/Users/Juan/.gem/ruby/2.2.2/bin:/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/gems/2.2.0/bin:/Users/Juan/.rubies/ruby-2.2.2/bin:/usr/local/opt/nvm/v0.10.35/bin:/usr/local/heroku/bin:/Users/Juan/.rubies:/usr/local/bin:/usr/local/sbin:./bin:/Users/Juan/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/calibre.app/Contents/console.app/Contents/MacOS:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/Users/Juan/bin:/usr/texbin:./bin
    HOME=/Users/Juan
    RUBIES=(/Users/Juan/.rubies/jruby-1.7.19 /Users/Juan/.rubies/ruby-2.0.0-p576 /Users/Juan/.rubies/ruby-2.0.0-p598 /Users/Juan/.rubies/ruby-2.0.0-p643 /Users/Juan/.rubies/ruby-2.0.0-p645 /Users/Juan/.rubies/ruby-2.1.4 /Users/Juan/.rubies/ruby-2.1.5 /Users/Juan/.rubies/ruby-2.1.6 /Users/Juan/.rubies/ruby-2.2.0 /Users/Juan/.rubies/ruby-2.2.1 /Users/Juan/.rubies/ruby-2.2.2)
    RUBY_ROOT=/Users/Juan/.rubies/ruby-2.2.2
    RUBY_VERSION=2.2.2
    RUBY_ENGINE=ruby
    RUBY_AUTO_VERSION=ruby-2.2.2
    RUBYLIB=
    RUBYOPT=
    RUBYPATH=
    RUBYSHELL=
    GEM_ROOT=/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/gems/2.2.0
    GEM_HOME=/Users/Juan/.gem/ruby/2.2.2
    GEM_PATH=/Users/Juan/.gem/ruby/2.2.2:/Users/Juan/.rubies/ruby-2.2.2/lib/ruby/gems/2.2.0

## Hooks

    preexec_functions=(omz_termsupport_preexec chruby_auto)
    precmd_functions=(omz_termsupport_precmd)
# chruby config in ~/.zshrc

source /usr/local/share/chruby/chruby.sh
source /usr/local/share/chruby/auto.sh
wryfi commented 8 years ago

Yeah, it seems to me that chruby-exec is basically broken for its intended purpose.

  1. The line source "${0%/*}/../share/chruby/chruby.sh" only seems to work properly if the user's bashrc already sources chruby.sh. Yet if the user is already sourcing chruby.sh, they probably don't need chruby-exec.
  2. The last few lines of the script execute the shell commands from a new shell. So again, unless chruby.sh is already sourced in the users shell rc files, this will fail.

The following patch works for me, and allows any user to successfully run chruby_exec, regardless of whether chruby.sh is sourced in his shell rc file.

--- chruby-0.3.9.orig/bin/chruby-exec   2016-03-18 13:24:36.177096813 -0700
+++ chruby-0.3.9/bin/chruby-exec    2016-03-18 13:27:24.439159869 -0700
@@ -1,6 +1,13 @@
 #!/usr/bin/env bash

-source "${0%/*}/../share/chruby/chruby.sh"
+if [ -f "/usr/share/chruby/chruby.sh" ]; then
+   . /usr/share/chruby/chruby.sh
+elif [ -f "/usr/local/share/chruby/chruby.sh" ]; then
+   . /usr/local/share/chruby/chruby.sh
+else
+   echo "ERROR: could not find chruby in /usr/share or /usr/local/share"
+   exit 1
+fi

 case "$1" in
    -h|--help)
@@ -33,8 +40,5 @@
    exit 1
 fi

-command="chruby $(printf "%q " "${argv[@]}") && $(printf "%q " "$@")"
+chruby $(printf "%q " "${argv[@]}") && $(printf "%q " "$@")

-if [[ -t 0 ]]; then exec "$SHELL" -i -l -c "$command"
-else                exec "$SHELL"    -l -c "$command"
-fi
postmodern commented 8 years ago

@wryfi please see master instead. https://github.com/postmodern/chruby/blob/master/bin/chruby-exec The first source of chruby.sh is just to load $CHRUBY_VERSION. Below we craft a command that checks for chruby, sources chruby.sh if not present, switches to the specific ruby, then exits.