how to echo $(command) into bash profile - bash

I am trying to append eval "$(rbenv init -)" to my bash profile
(I am trying to follow this instruction)
# Load rbenv automatically by appending
# the following to ~/.bash_profile:
eval "$(rbenv init -)"
This is part of an automated process so I don't have access to a GUI or can't use an editor. but when I echo the command $(rbenv init -) gets executed and append bunch of stuff. How can I echo it as plain text?
this is what I have now
ec2-user#ip-172-31-46-129 ~ % cat /tmp/install-rbenv.sh
+-zsh:41> cat /tmp/install-rbenv.sh
#!/bin/bash
sudo -i -u buildkite-agent bash << EOF
echo "export RUBY_CONFIGURE_OPTS=\"--with-openssl-dir=$(brew --prefix openssl#1.1)\"" >> /Users/buildkite-agent/.bash_profile
echo 'eval "$(rbenv init -)"' >> /Users/buildkite-agent/.bash_profile
EOF
echo "Done"
running it
ec2-user#ip-172-31-46-129 ~ % . /tmp/install-rbenv.sh
+-zsh:42> . /tmp/install-rbenv.sh
+/tmp/install-rbenv.sh:6> brew --prefix openssl#1.1
+/tmp/install-rbenv.sh:6> rbenv init -
+/tmp/install-rbenv.sh:6> sudo -i -u buildkite-agent bash
+/tmp/install-rbenv.sh:10> echo Done
Done
checking the bash profile
ec2-user#ip-172-31-46-129 ~ % sudo su - buildkite-agent
+-zsh:43> sudo su - buildkite-agent
rbenv: no such command `sh-'
-bash: eval: line 31: syntax error near unexpected token `rehash'
-bash: eval: line 31: ` rehash|shell)'
The default interactive shell is now zsh.
To update your account to use zsh, please run `chsh -s /bin/zsh`.
For more details, please visit https://support.apple.com/kb/HT208050.
ip-172-31-46-129:~ buildkite-agent$ cat ~/.bash_profile
export RUBY_CONFIGURE_OPTS="--with-openssl-dir=/usr/local/opt/openssl#1.1"
eval "export PATH="/Users/ec2-user/.rbenv/shims:${PATH}"
export RBENV_SHELL=zsh
source /usr/local/Cellar/rbenv/1.1.2/libexec/../completions/rbenv.zsh
command rbenv rehash 2>/dev/null
rbenv() {
local command
command="${1:-}"
if [ "$#" -gt 0 ]; then
shift
fi
case "$command" in
rehash|shell)
eval "$(rbenv "sh-$command" "$#")";;
*)
command rbenv "$command" "$#";;
esac
}"

Apparently you don't want to use an editor to edit your .bash_profile file or you are afraid you will got trapped inside vi :-D
Put the text you want to append to the file in apostrophes and it will go verbatim to the file. The shell does not do any expansion in the arguments that are wrapped in apostrophes.
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
That's all.

Use apostrophes around the first EOF, i.e. 'EOF' instead of EOF. bash distinguishes between the two and won't evaluate stuff if you use the apostrophe version.
> bash << EOF > test.sh
echo '$(date)'
EOF
> cat test.sh
Mon 12 Apr 2021 08:08:53 PM CEST
> bash << 'EOF' > test.sh
echo '$(date)'
EOF
> cat test.sh
$(date)

Related

How can I echo a shell command as a string

I want place the following string into my .zshrc file using the command line
eval "$(docker exec -it <abc-123>)"
I've tried:
echo "eval "$(docker exec -it <abc-123>)"" >> .zshrc
and every other ` and ' combination
The result I want is to have my .zshrc file execute
eval "$(docker exec -it <abc-123>)"
much like it does for homebrew
eval "$(/opt/homebrew/bin/brew shellenv)"
I just want to be able to write to my .zshrc file using echo. How can I achieve this?
echo 'eval "$(docker exec -it <abc-123>)"' >> .zshrc
Will add
eval "$(docker exec -it <abc-123>)"
at the end of your .zshrc file
A here doc can print a string verbatim, without quoting issues:
cat <<"EOF" >> .zshrc
eval "$(docker exec -it <abc-123>)"
EOF
In this case, you could do echo 'eval "$(docker exec -it <abc-123>)"' >> .zshrc, provided <abc-123> doesn't contain a single quote (').

Making bash script continue after exec $SHELL

I'm making a bash script that would install rbenv and ruby.
cd
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
exec $SHELL
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
exec $SHELL
rbenv install $rubyVersion
rbenv global $rubyVersion
But when the exec $SHELL is called the bash process is replaced by new bash process and the script stops (of course).
How can I make the script to continue?
It appears that you're trying to achieve multiple objectives by modifying the .bashrc file then calling exec $SHELL. Neither of those actions will modify the shell-in-which-this-script-is-running. To modify the current shell, you want to "source" the .bashrc file. Use the "dot notation" instead of calling exec $SHELL:
. ~/.bashrc
Good luck with this one!
replace exec $SHELL lines with "$SHELL" lines or completely remove those lines

pyenv installation script: need help understanding what it does

One of the steps to install pyenv requires typing the following into a terminal:
echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.bash_profile
While I understand what echo -e and >> ./bash_profile do, I do not really understand what is going on inside the quotations marks.
After running the command above, my bash_profile now has the following:
if command -v pyenv 1>/dev/null 2>&1; then
eval "$(pyenv init -)"
fi
Question: Could you explain what this code does? Is my interpretation of what is happening (see below) correct?
Interpretation:
command -v takes the name of a command and outputs its description, if the command given does not exist nothing is outputted; thus command -v pyenv will output the description pyenv if it is available (which will be if you installed pyenv), otherwise it will not show anything
the 1>/dev/null takes the output of the command -v pyenv and throws it away
What is the purpose for 2>&1?
Why do we need the eval inside the if block? Can't we just run pyenv init - directly?
Thanks for helping!

macOS Sierra: ${TAIL} is not working in zsh

I was trying to execute some bash scripts in zsh (oh-my-zsh). I found ${TAIL} is not working in zsh.
bash:
bash-3.2$ ${CD} /tmp; echo "test" >> test.txt; ${TAIL} test.txt
bash: /tmp: is a directory
test
zsh:
~ ${CD} /tmp; echo "test" >> test.txt; ${TAIL} test.txt
zsh: command not found: tail -f
✘ /tmp
But using tail directly is fine
✘ /tmp tail -f test.txt
test
test
whereis tail
/usr/bin/tail
echo $PATH
/usr/local/bin:/usr/bin
I think this is a classic case in zsh for Why does $var where var="foo bar" not do what I expect?
Unlike bash, by default, zsh does not split into words when passed to a command or used in a loop as for foo in $var.
var="foo bar"
enabled the flag manually as
setopt shwordsplit
then try the same as
echo "test" >> test.txt; ${TAIL} test.txt

Bash shell script: how do I exit and restart the script?

I use a shell script to provision my server. After I modify the .bashrc file, i need to exit then log back in to restart the shell.
su vagrant <<'EOF'
echo "export WORKON_HOME=$HOME/.virtualenvs" >> ~/.bashrc
echo "export PROJECT_HOME=/var/www" >> ~/.bashrc
echo "alias mkvirtualenv='mkvirtualenv --no-site-packages'" >> ~/.bashrc
echo "source /usr/local/bin/virtualenvwrapper.sh" >> ~/.bashrc
source ~/.bashrc
// this is where I need help, i need to exit the shell and relogin. then run mkvirutalenv command.
mkvirtualenv test1
EOF
Update:
this is the shell script file vagrant will run.
#!/usr/bin/env bash
if [ -f "/var/vagrant_provision" ]; then
exit 0
fi
echo "Installing Flask environment and setting it up.."
echo "------------------------------------------------"
apt-get update >/dev/null 2>&1
echo "1. update is done"
#apt-get upgrade -y >/dev/null 2>&1
echo "2. upgrade is done -- skipped for dev"
rm -rf /var/www
ln -fs /vagrant /var/www
echo "3. Symbolic link is created"
apt-get install -y build-essential python-dev >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
echo "4. curl is installed"
apt-get install -y python-pip >/dev/null 2>&1
echo "5. pip is installed"
pip install virtualenv virtualenvwrapper >/dev/null 2>&1
echo "6. virtualenv and virtualenvwrapper are installed"
su vagrant <<'EOF'
echo "export WORKON_HOME=$HOME/.virtualenvs" >> ~/.bashrc
echo "export PROJECT_HOME=/var/www" >> ~/.bashrc
echo "source /usr/local/bin/virtualenvwrapper.sh" >> ~/.bashrc
echo "alias mkv='mkvirtualenv --no-site-packages'" >> ~/.bashrc
echo "alias mycmd='ls'" >> ~/.bashrc
source ~/.bashrc
mycmd
mkv test1
EOF
echo "7. add environment variables to .bashrc"
echo "8. source .bashrc"
echo "9. test1 environment is created"
touch /var/vagrant_provision
echo "------------------------------------------------"
echo "Installation is done"
this is the output I got. still getting command not found.
Installing Flask environment and setting it up..
------------------------------------------------
1. update is done
2. upgrade is done -- skipped for dev
3. Symbolic link is created
4. curl is installed
5. pip is installed
6. virtualenv and virtualenvwrapper are installed
bash: line 8: mycmd: command not found
bash: line 9: mkv: command not found
7. add environment variables to .bashrc
8. source .bashrc
9. test1 environment is created
------------------------------------------------
Installation is done
==> After I modify the .bashrc file, i need to exit then log back in to restart the shell.
No need to restart the shell. If you want changes to get reflected in current session immediately then you can do this by using below commands.
source ~/.bashrc
or
. ~/.bashrc
By doing this you will load current new settings into your session. So you need not to re-login.
Please find one sample code which work properly.
#!/usr/bin/sh
echo "alias mycmd='ls'" >> ~/.bashrc
source ~/.bashrc
mycmd
To fix your problem -->
Please create passwordless ssh for user 'vagrant'. Please check the documantation to create passwordless ssh here.
Then put your run document commands like below.
ssh vagrant#localhost "alias mycmd='echo $HOME';/mycmd"
here using '/' before mycmd is mandatory otherwise 'mycmd' will be executed by current shell only and you will get command not found error.

Resources