bash

cd into a directory returns non zero status code


#!/bin/bash -l

source ~/.bashrc

set -e

echo "1. Current dir"
pwd
echo "2. Listing in path ..."
ls
echo "3. Entering dir"
cd bundler
echo "4. Entered"
go@ci-ubuntu-agent-1:/var/lib/go-agent/pipelines/x/src$ bash run.sh
1. Current dir
/var/lib/go-agent/pipelines/x/src
2. Listing in path ...
bundler  run.sh 
3. Entering dir...
go@ci-ubuntu-agent-1:/var/lib/go-agent/pipelines/x/src$ echo $?
1

Why does the cd into the directory return a status code of 1? The directory clearly exists. Only if run via the script the status code is 1. If I directly enter via the command line, status code is 0.

If I remove the -e option and run, the script runs with no issues. What am I missing here?


Solution

  • Found the culprit.

    Using PS4='+$BASH_SOURCE:$LINENO:$FUNCNAME: ' bash -x run.sh as suggested by @pjh, I got the output

    +++/home/go/.nvm/bash_completion:99:: complete -o default -F __nvm nvm
    +run.sh:5:: set -e
    +run.sh:7:: echo '1. Current dir'
    1. Current dir
    +run.sh:8:: pwd
    /home/go
    +run.sh:9:: echo '2. Listing in path ...'
    2. Listing in path ...
    +run.sh:10:: ls
    bundler  package-lock.json  r-libs  run.sh
    +run.sh:11:: echo '3. Entering dir'
    3. Entering dir
    +run.sh:12:: cd bundler
    +/home/go/.gvm/scripts/env/cd:48:cd: __gvm_is_function __gvm_oldcd
    +/home/go/.gvm/scripts/function/_shell_compat:17:__gvm_is_function: local func_name=__gvm_oldcd
    +/home/go/.gvm/scripts/function/_shell_compat:19:__gvm_is_function: [[ x__gvm_oldcd == \x ]]
    +/home/go/.gvm/scripts/function/_shell_compat:22:__gvm_is_function: builtin declare -f __gvm_oldcd
    +/home/go/.gvm/scripts/function/_shell_compat:24:__gvm_is_function: return 0
    +/home/go/.gvm/scripts/env/cd:49:cd: __gvm_oldcd bundler
    +/home/go/.gvm/scripts/env/cd:22:__gvm_oldcd: builtin cd bundler
    +/home/go/.gvm/scripts/env/cd:22:__gvm_oldcd: return 0
    +/home/go/.gvm/scripts/env/cd:52:cd: local dot_go_version dot_go_pkgset rslt
    +/home/go/.gvm/scripts/env/cd:53:cd: local defaults_go_name defaults_go_pkgset
    +/home/go/.gvm/scripts/env/cd:54:cd: local defaults_resolved=false
    +/home/go/.gvm/scripts/env/cd:55:cd: local defaults_hash
    +/home/go/.gvm/scripts/env/cd:55:cd: defaults_hash=()
    +/home/go/.gvm/scripts/env/cd:57:cd: [[ /home/go/.gvm == '' ]]
    +/home/go/.gvm/scripts/env/cd:63:cd: [[ '' -eq 1 ]]
    +/home/go/.gvm/scripts/env/cd:64:cd: defaults_hash=($(__gvm_read_environment_file "${GVM_ROOT}/environments/default"))
    ++/home/go/.gvm/scripts/env/cd:64:cd: __gvm_read_environment_file /home/go/.gvm/environments/default
    ++/home/go/.gvm/scripts/function/read_environment_file:27:__gvm_read_environment_file: [[ -n '' ]]
    ++/home/go/.gvm/scripts/function/read_environment_file:32:__gvm_read_environment_file: local filepath=/home/go/.gvm/environments/default
    ++/home/go/.gvm/scripts/function/read_environment_file:33:__gvm_read_environment_file: local 'regex=^export ([^[:digit:]]+[[:alnum:]_]+);[[:space:]]*([^[:digit:]]+[[:alnum:]_]+=(.*))$'
    ++/home/go/.gvm/scripts/function/read_environment_file:34:__gvm_read_environment_file: local hash
    ++/home/go/.gvm/scripts/function/read_environment_file:34:__gvm_read_environment_file: hash=()
    ++/home/go/.gvm/scripts/function/read_environment_file:36:__gvm_read_environment_file: [[ -z /home/go/.gvm/environments/default ]]
    ++/home/go/.gvm/scripts/function/read_environment_file:36:__gvm_read_environment_file: [[ ! -r /home/go/.gvm/environments/default ]]
    ++/home/go/.gvm/scripts/function/read_environment_file:37:__gvm_read_environment_file: echo ''
    ++/home/go/.gvm/scripts/function/read_environment_file:38:__gvm_read_environment_file: [[ -n '' ]]
    ++/home/go/.gvm/scripts/function/read_environment_file:42:__gvm_read_environment_file: return 1
    

    I saw that for some reason gvm was returning the 1. This is because I have no gvm envir file. But I didnt see why these particular lines of code should even be invoked.

    Following @pjh suggestion that there could be some wrapper on the cd command, I did a comparison of what cd is running between an old machine where this was not a issue and this box.

    Old machine cd:

    (honeymaker_venv) [go@ci-prod1 ~]$ type cd
    cd is a function
    cd ()
    {
        __zsh_like_cd cd "$@"
    }
    

    New machine cd:

    root@ci-ubuntu-agent-1:~# su - go
    go@ci-ubuntu-agent-1:~$ type cd
    cd is a function
    cd ()
    {
        if __gvm_is_function __gvm_oldcd; then
            __gvm_oldcd $*;
        fi;
        local dot_go_version dot_go_pkgset rslt;
        local defaults_go_name defaults_go_pkgset;
        local defaults_resolved=false;
    ...... too big to add here
    

    Note: which cd works differently for redhat(old) machines vs debian(new). It returned empty for the new ubuntu machine. so had to use the type command

    The gvm was replacing cd with its own implementation.

    A little debugging into gvm's cd wrapper led me to this - https://github.com/moovweb/gvm/issues/457

    So I just had to comment out the line in the gvm default load script to not replace cd.

    comment out the below line in $GVM_ROOT/scripts/gvm-default
    #. "$GVM_ROOT/scripts/env/cd" && cd .
    

    The default cd command works all fine now.

    Thanks for the suggestions and debugging help.