Bash Scripting; giving commands to programs stdin - bash

I am very new to bash scripting. I have the following script:
cp /etc/apt/sources.list /var/chroot/etc/apt/sources.list
chroot /var/chroot/
apt-get update
apt-get --simulate install $a > output
I actually want the last 2 comands to be run in chroot environment but I do not know how to give it to it, I searched but I could not find. I also want chroot to exit after execution of the commands, but it currently hangs. What can I do to prevent this?
EDIT: For future visitors:
cp /etc/apt/sources.list /var/chroot/etc/apt/sources.list
chroot /var/chroot apt-get update > /dev/null
chroot /var/chroot apt-get --simulate install nodejs

The command you want to run in the chroot environment must be given to chroot as an argument. See the manual page.

Related

How to Test a Bash File in Terminal

I've been trying to make a bash file for newbie Linux users and I wanted to know if there is a way to test the bash file before running it.
Can I just see the result of my bash file in the terminal and not actually run it?
For example, I don't want to actually update and upgrade my system when I run this script, I just want to see the result of my bash file, whether it gives me back some error or not.
Wanted to know if there is a way to just see the result, like see the result of my 'echo' commands and etc.
echo ---------------
echo hello and welcome to the automized bash file for your new linux distro!
echo ---------------
sudo apt-get update -y ; sudo apt-get upgrade -y ; sudo apt-get autoremove -y ; sudo apt-get autoclean -y ; sudo apt-get clean -y
echo ---------------
echo as you were drinking your coffee,
echo your linux distro got updated, and autocleaned as well!
Thanks in advance!
To see the results of running a bash file, a bash interpreter would have to interpret it. So the simple answer would be no.
However, if you are willing to use an online tool, you could run a bash script online. In this manner, you can see the results of running a bash script, without ever having to run it on your own machine.
A google search popped up these ones, but I cannot vouch for their legitimacy:
https://www.jdoodle.com/test-bash-shell-script-online/ (for evaluating the results of a script)
https://www.shellcheck.net/ (for assessing shell code quality)
There's no general way to run a shell script without running it. You can sometimes sort-of modify the script to make it go through the motions without actually doing anything significant, but this requires understanding the script and the commands in it.
For example, in the update script in the question, you could just add echo before each sudo apt-get command, something like this (note that I've reformatted it a bit, and added quotes around some fixed strings):
echo '---------------'
echo 'hello and welcome to the automized bash file for your new linux distro!'
echo '---------------'
echo sudo apt-get update -y
echo sudo apt-get upgrade -y
echo sudo apt-get autoremove -y
...etc...
This will simply print the commands, rather than executing them. (Note: if any commands had redirections, e.g. somecommand >outputfile or somecommand | anothercommand, the adding echo doesn't remove the redirection, so you'll need to make other changes as well).
If you want to actually see what the various apt-get commands would do if you ran them... you're in luck, because apt-get happens to have a --dry-run option (see the man page and this AskUbuntu question).
Note that this is a feature specific to apt-get. Very few shell commands have an option like this, so it's not like some sort of universal just-try-it-out switch. In fact, not even all apt-get subcommands support --dry-run.
Most relevantly, apt-get update doesn't support --dry-run! And it wouldn't be useful if it did. If you don't start by updating the package indexes -- actually updating them, not just pretending to -- then the other apt-get commands won't be able to tell what's new, and won't actually tell you what needs to be changed.
If you don't actually-for-real update the indexes, then you can't tell what the rest of the script would do if it ran for real. So you could do something like this:
...
sudo apt-get update -y
sudo apt-get upgrade --dry-run --assume-no
sudo apt-get autoremove --dry-run --assume-no
...etc...
...but be aware the script is actually executing, and while some of its effects have been disabled, others haven't.

How to auto run commands when log on to Windows Subsystem for Linux

I have a Ubuntu 20.04 running within WSL 2 on a Windows 10 computer.
Every time I login to Ubuntu, I had to manually execute these four line by pasting it one by one in the Windows 10 Terminal.
sudo apt-get update && sudo apt-get install -yqq daemonize dbus-user-session fontconfig
sudo daemonize /usr/bin/unshare --fork --pid --mount-proc /lib/systemd/systemd --system-unit=basic.target
exec sudo nsenter -t $(pidof systemd) -a su - $LOGNAME
sudo /etc/init.d/xrdp start
May I know if there is a way to skip this manual process?
You can use .bashrc file to execute commands whenever you open the terminal. It should be located at $HOME directory.
cd $HOME
nano .bashrc
place your commands at the end of the file, press ctl+x then y to save.

installing and using conda within a sudo-called bash script

I have a bash script which installs some software with apt-get as well as download and installs miniconda3. Later I would like to utilize conda command without restarting the shell. This script is called with sudo but for all the things related to conda I want to pose as a regular user, see below:
#!/usr/bin/env bash
# we are operating in the user's home dir
sudo -u $SUDO_USER bash Miniconda3-latest-Linux-x86_64.sh -b -p miniconda3
source [path_to_the_user_home]/miniconda3/etc/profile.d/conda.sh
sudo -u $SUDO_USER -H -s eval $(conda shell.bash hook)
sudo -u $SUDO_USER conda --version
However, I get an error that the command conda is not recognized. Interestingly, if the last line would be just conda --version then it is correctly recognised. It seems that the 2nd to last line worked for root, but not the user (which is exactly what I want)

skip installing confirm('yes' or 'no') in Dockerfile [duplicate]

How do I install the anaconda / miniconda without prompts on Linux command line?
Is there a way to pass -y kind of option to agree to the T&Cs, suggested installation location etc. by default?
can be achieved by bash miniconda.sh -b (thanks #darthbith)
The command line usage for this can only be seen with -h flag but not --help, so I missed it.
To install the anaconda to another place, use the -p option:
bash anaconda.sh -b -p /some/path
AFAIK pyenv let you install anaconda/miniconda
(after successful instalation)
pyenv install --list
pyenv install miniconda3-4.3.30
For a quick installation of miniconda silently I use a wrapper
script script that can be executed from the terminal without
even downloading the script. It takes the installation destination path
as an argument (in this case ~/miniconda) and does some validation too.
curl -s https://gist.githubusercontent.com/mherkazandjian/cce01cf3e15c0b41c1c4321245a99096/raw/03c86dae9a212446cf5b095643854f029b39c921/miniconda_installer.sh | bash -s -- ~/miniconda
Silent installation can be done like this, but it doesn't update the PATH variable so you can't run it after the installation with a short command like conda:
cd /tmp/
curl -LO https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh -b -u
Here -b means batch/silent mode, and -u means update the existing installation of Miniconda at that path, rather than failing.
You need to run additional commands to initialize PATH and other shell init scripts, e.g. for Bash:
source ~/miniconda3/bin/activate
conda init bash

Remove sudo permissions for one command

this is probably a really simple question. I apologize if it is a duplicate.
I want to know how to remove sudo permissions for one particular command. I've created a script that installs a bunch of .deb packages and it needs sudo to do that, but one command in it needs to run without sudo permissions, so how would I do that? I'm using Ubuntu and this is a bash script.
I'm calling my script: ROS_install
Here is part of the script:
sudo dpkg -i /home/forklift/Desktop/ROS/ros-hydro-laser-proc_0.1.3-0precise-20131015-2054-+0000_amd64.deb
sudo dpkg -i /home/forklift/Desktop/ROS/ros-hydro-urg-c_1.0.403-0precise-20131010-0128-+0000_amd64.deb
sudo rosdep init
sleep 2
rosdep update
The command "rosdep update" needs to be run without sudo permissions. I assumed that it was already, but I get a warning every time I run the script, and thus get locked out of the command after installation.
Rather than give the entire script elevated privileges, just give them to the actual commands that need them. That is, rather than
$ sudo my_script
modify my_script to use sudo only on those commands that need it. For instance, if this is your script:
command1
command2
command3
command4
command5
and command3 is the non-sudo command, modify your script to read
sudo command1
sudo command2
command3
sudo command4
sudo command5
In the process, think about whether command1 actually needs to run with sudo, or it it can run just as well without. In that way, you should be able to greatly reduce the number of commands that actually need to be run with sudo in your script.
If your command is running with full privileges, it also has the privilege to demote its own privileges, for good or for the duration of one command, by running su.
touch /privileged
su -c 'cp /privileged /tmp/not' nobody
I assume you are calling your script like:
sudo script.sh
And you do not want all of the commands within the script to run as root.
If your script is like:
apt-get install perl
apt-get install python
mv trash /home/user/
And you only want to run the first two commands as root you can specify a specific user for the third like:
su -c "mv trash /home/user/" user
Where user is the username you want to run the command as.
This will allow you to make a single sudo call at the parent level when you call the script.
If you don't want the username hardcoded, you can use a command like logname to get the username of the user that you are logged in as.
Just adding to the other answers, you can do this:
su -c "command" $SUDO_USER
Which will execute the command as the actual user who typed the sudo command
That's very useful when you are making scripts that require sudo to install something and write something in the user's $HOME

Resources