How environment variables can be read from a file when going into a login shell with here-string and using the sudo command? - linux

I am trying to write a small script that aims to login to a remote server, load environment variables and print one of them. (In the actual script, instead of an echo, the parameters that are read are to be used. For the sake of simplicity here I am using just echo.)
The structure of the script and the commands that I tried are as follows but unfortunately none succeeds:
ssh -i lightsail.pem ubuntu#production <<< '
sudo echo $TEST_PARAMETER
sudo sh -c "~/Environment/environment-variables.sh && echo $TEST_PARAMETER"
sudo bash -c "~/Environment/environment-variables.sh && echo $TEST_PARAMETER"
sudo bash -c "source ~/Environment/environment-variables.sh && echo $TEST_PARAMETER"
sudo bash <<< "source ~/Environment/environment-variables.sh && echo $TEST_PARAMETER"
';
How environment variables can be read from a file when going into a login shell with here-string and using the sudo command?

If your environment variable is set for ubuntu and not root you will need to use sudo -E
-E Indicates to the security policy that the user wishes to preserve their existing environment variables

Related

How can I feed input within bash [Executed through the Network]

As the title says, within linux how can I feed input to the bash when I do sudo bash
Lets say I have a bash script that reads the name.
The way I execute the script is through sudo using:
cat read-my-name-script.sh | sudo bash
Lets just say this is how I execute the script throught the network.
Now I want to fill the name automatically, is there a way to feed the input. I tried doing this: cat read-my-name-script.sh < name-input-file | sudo bash where the name-input-file is a file for the input that the user will be using to feed the script.
I am new to linux and learning to automate the input and wanted to create a file for input where the user can fill it and feed it to my script.
This is convoluted, but might do what you want.
sudo bash -c "$(cat read-my-name.sh)" <name-input-file
The -c says the next quoted argument are the commands to run (so, read the script as a string on the command line, instead of from a file), and the calling shell interpolates the contents of the file inside the double quotes before the sudo command gets evaluated. So if read-my-name.sh contains
#!/bin/bash
read -p "I want your name please"
then the command gets expanded into
sudo bash -c '#!/bin/bash
read -p "I want your name please"' <name-input-file
(where of course at this time the shell has actually removed the outer double quotes altogether; I put in single quotes in their place instead to show how this would look as actually executable, syntactically valid code).
I think you need that:
while read -r arg; do sudo bash read-my-name-script.sh "$arg";done <name-input-file
So each line of name-input-file will be passed as argument to sudo bash read-my-name-script.sh
If your argslist located on http server, you can do that:
while read -r arg; do sudo bash read-my-name-script.sh "$arg";done < <(wget -q -O- http://some/address/in/internet/name-input-file)
UPD
add [[ -f name-input-file ]] && readarray -t args <name-input-file
to read-my-name-script.sh
and use "${args[#]}" as arguments of command in the script.
For example echo "${args[#]}" or cmd "${args[0]}" "${args[1]}" ... "${args[100]}" in any order.
In this case you can use
wget -q -O- http://some/address/in/internet/read-my-name-script.sh | bash
for run your script with arguments from name-input-file whitout saving script to the local machine

Run command as root within shell script

I'm working on a script that will shred a usb drive and install Kali linux with encrypted persistent data.
#! /bin/bash
cd ~/Documents/Other/ISOs/Kali
echo "/dev/sdx x=?"
read x
echo "how many passes to wipe? 1 will be sufficient."
read n
echo "sd$x will be wiped $n times."
read -p "do you want to continue? [y/N] " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]
then
exit 1
fi
echo "Your role in the installation process is not over. You will be prompted to type YES and a passphrase."
sudo shred -vz --iterations=$n /dev/sd$x
echo "Wiped. Installing Kali"
sudo dd if=kali-linux-2.0-amd64.iso of=/dev/sd$x bs=512k
echo "Installed. Making persistence."
y=3
sudo parted /dev/sd$x mkpart primary 3.5GiB 100%
x=$x$y
sudo cryptsetup --verbose --verify-passphrase luksFormat /dev/sd$x
sudo cryptsetup luksOpen /dev/sd$x my_usb
sudo mkfs.ext3 -L persistence /dev/mapper/my_usb
sudo e2label /dev/mapper/my_usb persistence
sudo mkdir -p /mnt/my_usb
sudo mount /dev/mapper/my_usb /mnt/my_usb
sudo -i
echo "/ union" > /mnt/my_usb/persistence.conf
umount /dev/mapper/my_usb
cryptsetup luksClose /dev/mapper/my_usb
echo "Persistence complete. Installation complete."
It works nearly perfectly. These commands individually entered into the terminal will create the desired effect, but the problem comes in at line 37:
sudo echo "/ union" > /mnt/my_usb/persistence.conf
That command won't work unless I'm logged in as root user. To solve this I tried adding the sudo -i command before, but once I do that all of the following commands are skipped.
It's okay if the solution suggested requires me to type in the password. I don't want the password stored in the script, that's just wreckless.
Side note, I didn't make a generic form for this question because I want other people to be able use this if they like it.
The problem is that the echo runs with root privilege but the redirection happens in the original shell as the non-root user. Instead, try running an explicit sh under sudo and do the redirection in there
sudo /bin/sh -c 'echo "/ union" > /mnt/my_usb/persistence.conf'
The problem is that when you type in the following command:
sudo echo "/ union" > /mnt/my_usb/persistence.conf
Only the "echo" will be run as root through sudo, but the redirection to the file using > will still be executed as the "normal" user, because it is not a command but something performed directly by the shell.
My usual solution is to use teeso that it runs as a command and not as a shell built-in operation, like this:
echo "/ union" | sudo tee /mnt/my_usb/persistence.conf >/dev/null
Now the tee command will be run as root through sudo and will be allowed to write to the file. >/dev/null is just added to keep the output of the script clean. If you ever want to append instead of overwrite (e.g. you would be using >>normally), then use tee -a.

How to execute multiple commands with sudo in script [duplicate]

This question already has answers here:
How to run two commands with sudo?
(11 answers)
Closed 7 years ago.
Can we use heredocs to run multiple commands using sudo?
I am facing an issue (need to pass password for every command) while running
multiple commands:
echo 'password'| sudo -S ls
echo 'password'| sudo -S cat /var/log/abc.log
Can anyone help me how to automate this in a script? Like:
echo 'password' | sudo -S << ENDBLOCK
ls
cat
ENDBLOCK
you can run sh -c ..., but remember to quote properly.
sudo sh -c 'id; echo another command ; id'
sudo must see this as a single argument for the sh command.
Of course you can use new line instead of semicolon:
sudo sh -c '
echo "I am root"
id
echo "another command"
id
'
One way is to write a script with all the things you need to do with sudo and then run the script with sudo.
you could put all your commands in a script. Then
sudo ./script.sh
put permissions for script.sh in /etc/sudoers.d; that way you'll never need to type your password again (for that script)

Multiple commands in sudo over ssh in shell script

My script is as below.
#!/bin/bash
version = 1.1
echo "Enter username"
read UserName
ssh -t $UserName#server bash -c " '
./runSomeScript
echo "Entering Sudo"
sudo -s -u user1 -c "cd random; ./randomscrip xx-$version-yy"
'"
But this is not working.
Basically i want to do a ssh to a account. And then runSomeScript
Then do a sudo with user as user1 and then run commands cd random and ./randomscrip (with xx-Version-yy as argument) as the sudo user only.
But the commands inside sudo are not working.
Your quoting is a little careless. You're using double-quotes for the first and third levels of quoting, and the shell can't tell one from the other. Do something like this instead:
sudoScript="cd random; ./randomscrip xx-${version}-yy"
sshScript='
./runSomeScript
echo "Entering Sudo"
sudo -s -u user1 bash -c '"'${sudoScript}'"'
'
ssh -t ${UserName}#server "${sshScript}"
But beware that if you embed any single-quotes, it will still go wrong unless you add a layer of shell-quoting.
Finally, remove the spaces around = when you assign to version.

Piping a shell script to bash and launch interactive bash

Consider the following shell script on example.com
#/bin/bash
export HELLO_SCOPE=WORLD
eval $#
Now, I would like to download and then execute this shell script with parameters in the simplest way and be able to launch an interactive bash terminal with the HELLO_SCOPE variable set.
I have tried
curl http://example.com/hello_scope.sh | bash -s bash -i
But it quits the shell immediately. From what I can understand, it's because curls stdout, the script, remains the stdin of the bash, preventing it from starting interactively (as that would require my keyboard to be stdin).
Is there a way to avoid this without going through the extra step of creating a temporary file with the shell script?
You can source it:
# open a shell
. <(curl http://example.com/hello_scope.sh)
# type commands ...
You could just download this script you (using wget for example) and source this script, isn't it ?
script_name="hello_scope.sh"
[[ -f $script_name ]] && rm -rf "$script_name"
wget "http://example.com/$script_name" -O "$script_name" -o /dev/null
&& chmod u+x "$script_name"
&& source "$script_name"
You could use . "$script_name" instead of source "$script_name" if you want (. is POSIX compliant). You could write the previous code in a script and source it to have interactive shell with the setted variable $HELLO_SCOPE.
Finally you could remove the eval line in your remote shell script.

Resources