Score:1

eval expression within shell script returns exit code 1

sr flag

I am using ubuntu 18.04 to run a shell script, and the eval expression returns an exit code 1:

#!/bin/bash
set -e

export DEBIAN_FRONTEND=noninteractive

git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.10.2
echo -e '\n. $HOME/.asdf/asdf.sh' >> ~/.bashrc
echo -e '\n. $HOME/.asdf/completions/asdf.bash' >> ~/.bashrc

eval "$(cat ~/.bashrc | tail -n +10)"

...

Even if I remove the git clone and the echo right before it won't work, which means the problem is within the .bashrc file. If I use an empty file, or any other file, it works.

This eval hack was recommended here.

And here's the tail -n +10 ~/.bashrc (I just want to ignore the first 10 lines, specially where it says # If not running interactively, don't do anything):

# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth

# append to the history file, don't overwrite it
shopt -s histappend

# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000

# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize

# If set, the pattern "**" used in a pathname expansion context will
# match all files and zero or more directories and subdirectories.
#shopt -s globstar

# make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"

# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
fi

# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
    xterm-color|*-256color) color_prompt=yes;;
esac

# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes

if [ -n "$force_color_prompt" ]; then
    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
        # We have color support; assume it's compliant with Ecma-48
        # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
        # a case would tend to support setf rather than setaf.)
        color_prompt=yes
    else
        color_prompt=
    fi
fi

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt

# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
    ;;
*)
    ;;
esac

# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    alias ls='ls --color=auto'
    #alias dir='dir --color=auto'
    #alias vdir='vdir --color=auto'

    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'
fi

# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'

# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'

# Add an "alert" alias for long running commands.  Use like so:
#   sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

If I run the same eval expression within the command line, and do echo $? it returns 0.

Doing exec bash, source ~/.bashrc or . ~/.bashrc as a substitute of the eval does not work as I am using a non-interactive shell.

Also, I can't remove set -e as I am using packer to build an image and I want to stop the build If I get an error.

Any idea what it could be?

Goal

I am using a tool called packer to build a server image where a run a script to install what I need, including the asdf tool.

I want to be able to install asdf, use it within the script, and then use it later when I launch the server. I am using a systemd service to run a web application that requires some plugins from asdf.

I can source the files (instead of sourcing the whole .bashrc) within the script by doing:

. $HOME/.asdf/completions/asdf.bash
. $HOME/.asdf/asdf.sh

and add the same lines to .bashrc as mentioned here. However, I am not sure I will be able to access asdf later when I launch the server.

terdon avatar
cn flag
Can you explain why you even want to source bashrc? Can't you extract only the relevant parts and add those to your script instead? As you already point out, bashrc isn't supposed to be read by non-interactive shells and here you are forcing one to do so, which seems a strange choice.
soltex avatar
sr flag
I want to source bashrc so I am able to call `asdf` later outside the script. If I source just the `asdf` files it will work within the script, but I will get `asdf: command not found` outside.
soltex avatar
sr flag
Actually, I don't need `asdf` on the current session. I will build a new server from an image, and the `.bashrc` will be modified by then. In that case, I won't need to source the `.bashrc` anymore, correct? Once the server starts, will I be able to find `asdf`?
Esther avatar
es flag
how does sourcing the `.bashrc` help with finding `asdf`? Is it just an alias in `.bash_aliases`? because it doesn't look like the `.bashrc` is modifying `PATH` at all...
terdon avatar
cn flag
@soltex please [edit] your question and add the clarifications there. Explain what the final objective is, and we should be able to figure out a solution. I really doubt that `eval`uating .bashrc is the right thing to do.
soltex avatar
sr flag
@terdon I have updated the question with the final objective. I agree with you, using eval does not look to be the best solution, but I stilll haven't found another one.
soltex avatar
sr flag
btw, I took the eval from here: https://askubuntu.com/questions/64387/cannot-successfully-source-bashrc-from-a-shell-script
terdon avatar
cn flag
So what happens when the server is launched? What user does it run as? What shell does it use? Does the server even have a shell? How would it use these commands? Where do you define the PATH variable for the user owning the server? Sounds like you should be modifying _that_ file, most likely `$serverUser/.profile`.
Esther avatar
es flag
yes, what you have there is equivalent to sourcing the files in the script and then in the .bashrc later.
soltex avatar
sr flag
@terdon I don't know what happens when the server is launched as I haven't tested it yet. If the health-check does not succeed It will break the auto scaling group. That's why I want to make sure before launching the server. The user is the same that runs the script. Yes, the server has a shell. The server will use `mix` through an systemd service which can only be found if `asdf` is accessible.
soltex avatar
sr flag
I will try to source the files instead of sourcing the whole `bashrc` and add the `asdf` path to `bashrc` without sourcing. Then, when I launch the server, I think `asdf` will be accessible. I don't see any other way.
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.