How to write in /etc/profile using bash | Permission Denied - bash

I'm creating a bash script to set up an Ubuntu 16.04 lts OS to download, install and other stuff without introduce each command separately and I have to write in the /etc/profile file to add a PATH environment variable. When my code get into that line it appears the Permission Denied message, this is what I have:
sudo echo "export PATH=$PATH:/usr/local/go/bin" >> /etc/profile
bash: /etc/profile: Permission denied
Do you know how could I solve this?

Shell i/o redirection happens before the shell executes your command...in other words, when you write:
sudo somecommand >> /etc/profile
The >> /etc/profile part is performed as the current user, not as root. That's why you're getting the "permission denied" message. There are various ways of solving this. You can run:
sudo sh -c "echo export PATH=$PATH:/usr/local/go/bin >> /etc/profile"
Or you can take advantage of the append (-a) flag to the tee command:
echo "export PATH=$PATH:/usr/local/go/bin" | sudo tee -a /etc/profile

sudo sh -c "echo MY_GLOBAL_ENV_TO_MY_CURRENT_DIR=$(pwd)" >> /etc/environment"

Related

Change host file with script on Mac

I'm trying to append a line to the hosts file on a mac.
The command I'm using is:
sudo echo "192.168.99.100 test" >> /private/etc/hosts
This method does work on windows & linux but on Mac I do not have the permissions to run this even when running it in sudo mode.
Can anybody tell me what I'm doing wrong and how I can fix this?
StefanJanssen
Try echo '192.168.99.100 test' | sudo tee -a /private/etc/hosts.
>> is syntax of the shell itself, which is running as your user. sudo echo "192.168.99.100 test" >> /private/etc/hosts runs echo "192.168.99.100 test" as root and the >> "pipe to file" is run as your user.
tee is an ordinary command you can run as root with sudo which outputs to both stdout and a file, so echo 'line' | sudo tee -a file will do what you want. tee -a will append to the file instead of overwriting it.

where did my environment variable go?

I am trying to use an environment variable in a bash script that needs to run as sudo with source.
I have the following file (my_file.sh)
echo "this is DOMAIN = $DOMAIN"
I have the DOMAIN environment variable in my session..
and now I need to run
sudo -E bash -c "source ./my_file.sh"
but the output does not display the value for $DOMAIN. instead it is empty.
if I change the command to be
sudo -E bash -c "echo $DOMAIN"
I see the correct value..
what am I doing wrong?
With the command line:
sudo -E bash -c "source ./my_file.sh"
you are running a script that may refer to environment variables that would need to be exported from a parent shell to be visible.
On the other hand:
sudo -E bash -c "echo $DOMAIN"
expands the value of $DOMAIN in the parent shell, not inside your sudo line.
To demonstrate this, try your "working" solution with single quotes:
sudo -E bash -c 'echo $DOMAIN'
And to make things go, try exporting the variable:
export DOMAIN
sudo -E bash -c "source ./my_file.sh"
Or alternately, pass $DOMAIN on the command line:
sudo -E bash -c "source ./my_file.sh $DOMAIN"
And have your script refer to $1.

executing script lines with another user and access to that user's $HOME

I found a lot of solutions for parts of that problem, but not for the combination. So here is the plan:
#!/bin/bash
echo "current home »$HOME«"
sudo -u git -H /bin/bash << END_OF_SCRIPT
GitToolsRepo=$HOME/git-tools
echo "using git tools at »$GitToolsRepo«"
END_OF_SCRIPT
echo finally
running this script with sudo as auser, unfortunately this always puts
current home »/home/auser«
using git tools at »«
finally
Assuming user git's home is set to /var/lib/git I expect something like
current home »/home/auser«
using git tools at »/var/lib/git«
finally
User git has no login shell set (security)
I also tried
su -s /bin/bash git - << END_OF_SCRIPT
with identical result.
So how can I in a script run a set of script lines as a different user and having its environment set as I would have when executing su -s /bin/bash git - on command line?
Even more difficult with {}
#!/bin/bash
echo "current home »$HOME«"
su -s /bin/bash git - << END_OF_SCRIPT
GitToolsRepo=${HOME}/git-tools
echo "using git tools at »${GitToolsRepo}«"
END_OF_SCRIPT
echo finally
You need to escape $ in script input block.
Hence correct script will be
#!/bin/bash
echo "current home »$HOME«"
sudo -u git -H /bin/bash << END_OF_SCRIPT
GitToolsRepo=\$HOME/git-tools
echo "using git tools at »\$GitToolsRepo«"
END_OF_SCRIPT
echo finally
For all readers coming here for the same problem: I figured it is much better to put the part for the other user in a separate script and have either option in one line:
sudo -u user bash -c script.sh
sudo -u user script.sh
su user -c "bash script"
this it is debuggable and no ugly escaping

Why can't I redirect text to a text file?

I'm writing a bash shell script that has to be run with admin permissions (sudo).
I'm running the following commands
sudo -u $SUDO_USER touch /home/$SUDO_USER/.kde/share/config/kcmfonts > /dev/null
sudo -u $SUDO_USER echo "[General]\ndontChangeAASettings=true\nforceFontDPI=96" >> /home/$SUDO_USER/.kde/share/config/kcmfonts
The first command succeeds and creates the file. However the second command keeps erroring with the following:
cannot create /home/username/.kde/share/config/kcmfonts: Permission denied
I can't understand why this keeps erroring on permissions. I'm running the command as the user who invoked sudo so I should have access to write to this file. The kcmfonts file is created successfully.
Can someone help me out?
Consider doing this:
echo "some text" | sudo -u $SUDO_USER tee -a /home/$SUDO_USER/filename
The tee command can assist you with directing the output to the file. tee's -a option is for append (like >>) without it you'll clobber the file (like >).
You don't need to execute the left side with elevated privs (although it is just echo, this is a good thing to form as a habit), you only need the elevated privs for writing to the file. So with this command you're only elevating permissions for tee.
sudo -u $SUDO_USER echo "some text" >> /home/$SUDO_USER/filename
sudo executes the command echo "some text" as `$SUDO_USER".
But the redirection is done under your account, not under the $SUDO_USER account. Redirection is handled by the shell process, which is yours and is not under the control of sudo.
Try this:
sudo -u $SUDO_USER sh -c 'echo "some text" >> /home/$SUDO_USER/filename'
That way, the sh process will be executed by $SUDO_USER, and that's the process that will handle the redirection (and will write to the output file).
Depending on the complexity of the command, you may need to play some games with escaping quotation marks and other special characters. If that's too complex (which it may well be), you can create a script:
$ cat foo.sh
#!/bin/sh
echo "some text" >> /home/$SUDO_USER/filename
$ sudo -u $SUDO_USER ./foo.sh
Now it's the ./foo.sh command (which executes as /bin/sh ./foo.sh) that will run under the $SUDO_USER account, and it should have permission to write to the output file.

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