Can rc.local wait for Bash script to finish before booting - linux

I am running the rolling release of Kali Linux, and have started to write a script that is executed by rc.local upon booting, that will be allow the user update the hostname of the computer.
rc.local:
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
/root/hostnameBoot
exit 0
hostnameBoot Script:
#!/bin/bash
# /etc/init.d/hostnameBoot
# Solution Added
exec < /dev/tty0
echo "Enter desired hostname:"
read hostname
echo "New hostname: $hostname"
#exit 0
As you can see, currently hostnameBoot prompts the user to enter a new hostname, and then returns the hostname to the user.
Upon booting, rc.local execute the script, but does not prompt the user to enter a new hostname.
Sample Boot Output:
- misc boot info -
Enter desired hostname:
New hostname:
The Sample Boot Output shows all at once and does not allow the user to enter a new hostname. Once the lines are shown, the system then continues to the login screen. Desired behavior of the system would allow the user time to enter a new hostname, then be presented with the input previously submitted.
note: The script is not the end product, it was just a proof of concept using rc.local to trigger the script.

Boot scripts, including rc.local, are usually not executed in interactive mode (i.e. with a fully functioning terminal where the user can enter data). Their output is redirected to the console (so you can see the boot messages) but the input is most likely /dev/null (so read returns immediately with nothing to read).
You will need to either manually redirect the read to use a fixed terminal all the time (e.g. read </dev/tty0) or open a virtual console to do the user input in (e.g. openvt -s -w /root/hostnameBoot). See this answer for more details.

Related

Switch to root user within bash script

Im currently logged in as admin and I want to edit the /etc/hosts file which required root access.
I'm not able to make the changes. The script gets executed sucessfully but the changes arent made.
My Script - Runs Sucessfully when executed from terminal
sudo -s
echo "127.0.0.1" >> /etc/hosts
su admin
sudo -s - switches to root without password when executed from terminal
su admin - switches back to admin user when run on terminal
My /etc/hosts file remains empty after running the script
There is no need to actually switch your user within the script.
Also, you can't echo something as root like that because the redirect (>>) is executed by the shell.
A possible workaround is using tee:
echo "127.0.0.1" | sudo tee -a /etc/hosts
Further explanation:
tee basically takes the data from the standard input and writes it either to the standard output, or to a file. For more information see the commands manual ($ man tee)

Rqaspberry run a java script on startup and see the cmd?

I have a java code I want to run on startup ,
but I wnat to be able to see the code running on the CMD.(like when I run the java manually)
how do I do this ?
this is what I have in the rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
# Print the IP address - this was in the default - didn't touch it..
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %s\n" "$_IP"
# run the java file from desktop
sudo java -jar Desktop/test.jar &
exit 0
Thanks ,
From what i see, you have to option.
First you maybe need to wait a moment before the next command, witch is exit 0 and will for sure exit, execute itself. Like this you will have time to read output.
Try to add sleep 1m befor exit 0
you will find more info on this command on google if you need, but 1m in exemple is for 1 minute
Other solution is to change a bit your java programm to wait for a user intput like for exemple:
System.out.println("\n Hit Return to exit... ");
String kS = scan.nextLine();
System.exit(0);
like this the java prog. will wait till you press return.
Hope you find what's best for you.

Linux script for probing ssh connection in a loop and start log command after connect

I have a host machine that gets rebooted or reconnected quite a few times.
I want to have a script running on my dev machine that continuously tries to log into that machine and if successful runs a specific command (tailing the log data).
Edit: To clarify, the connection needs to stay open. The log command keeps tailing until I stop it manually.
What I have so far
#!/bin/bash
IP=192.168.178.1
if (("$#" >= 1))
then
IP=$1
fi
LOOP=1
trap 'echo "stopping"; LOOP=0' INT
while (( $LOOP==1 ))
do
if ping -c1 $IP
then
echo "Host $IP reached"
sshpass -p 'password' ssh -o ConnectTimeout=10 -q user#$IP '<command would go here>'
else
echo "Host $IP unreachable"
fi
sleep 1
done
The LOOP flag is not really used. The script is ended via CTRL-C.
Now this works if I do NOT add a command to be executed after the ssh and instead start the log output manually. On a disconnect the script keeps probing the connection and logs back in once the host is available again.
Also when I disconnect from the host (CTRL-D) the script will log right back into the host if CTRL-C is not pressed fast enough.
When I add a command to be executed after ssh the loop is broken. So pressing (CTRL-C) does not only stop the log but also disconnects and ends the script on the dev machine.
I guess I have to spawn another shell somewhere or something like that?
1) I want the script to keep probing, log in and run a command completely automatically and fall back to probing when the connection breaks.
2) I want to be able to stop the log on the host (CTRL-C) and thereby fall back to a logged in ssh connection to use it manually.
How do I fix this?
Maybe best approach on "fixing" would be fixing requirements.
The problematic part is number "2)".
The problem is from how SIGINT works.
When triggered, it is sent to the current control group related to your terminal. Mostly this is the shell and any process started from there. With more modern shells (you seem to use bash), the shell manages control groups such that programs started in the background are disconnected (by having been assigned a different control group).
In your case the ssh is started in the foreground (from a script executed in the foreground), so it will receive the interrupt, forward it to the remote and terminate as soon as the remote end terminated. As by that time the script shell has processed its signal handler (specified by trap) it is going to exit the loop and terminate itself.
So, as you can see, you have overloaded CTRL-C to mean two things:
terminate the monitoring script
terminate the remote command and continue with whatever is specified for the remote side.
You might get closer to what you want if you drop the first effect (or at least make it more explicit). Then, calling a script on the remote side that does not terminate itself but just the tail command, will be step. In that case you will likely need to use -t switch on ssh to get a terminal allocated for allowing normal shell operation later.
This, will not allow for terminating the remote side with just CTRL-C. You always will need to exit the remote shell that is going to be run.
The essence of such a remote script might look like:
tail command
shell
of course you would need to add whatever parts will be necessary for your shell or coding style.
An alternate approach would be to keep the current remote command being terminated and add another ssh call for the case of being interrupted that is spanning the shell for interactive use. But in that case, also `CTRL-C will not be available for terminating the minoring altogether.
To achieve this you might try changing active interrupt handler with your monitoring script to trigger termination as soon as the remote side returns. However, this will cause a race condition between the user being able to recognize remote command terminated (and control has been returned to local script) and the proper interrupt handler being in place. You might be able to sufficiently lower that risk be first activating the new trap handler and then echoing the fact and maybe add a sleep to allow the user to react.
Not really sure what you are saying.
Also, you should disable PasswordAuthentication in /etc/ssh/sshd_config and log by adding the public key of your home computer to `~/.ssh/authorized_keys
! /bin/sh
while [ true ];
do
RESPONSE=`ssh -i /home/user/.ssh/id_host user#$IP 'tail /home/user/log.txt'`
echo $RESPONSE
sleep 10
done

automatic reverse SSH tunneling

I need to connect to my office computer through ssh, but all the ports are blocked and there is nothing to do there. I'd like to connect with reverse SSH tunneling. For that I want to use an external server that it's always on, and I want to set up my office computer to run the ssh command right at boot (before login).
I tried by modifying /etc/rc.local. These are the permissions:
-rwxr-xr-x 1 root root 385 nov 2 17:27 /etc/rc.local
The file:
#!/bin/sh -e
#
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
sleep 1
sshpass -p 'pass' ssh -N -R 9091:localhost:22 user#server &
exit 0
Running /etc/rc.local allows me to connect from my home computer to my office computer, so the code does what it's supposed to, but it doesn't seem to do anything while booting.
Any ideas how to make the script run during booting?
Thanks.

start a python script as soon as power is supplied

I work on raspberry pi via SSH session, model B raspbian
I want the python script to run as soon as I plug in the power supply to my raspberry pi without connecting the ethernet cable.
I have found people asking about starting the script on boot up and what I found is to add the command in rc.local so I did
it looks like that now
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %s\n" "$_IP"
fi
sudo python tt3.py --cascade=s.xml 0
exit 0
but it doest work neither on plug in power supply or on starting up the SSH session
I think you are headed in the correct direction, but the issue probably revolves around tt3.py and s.xml not being found where rc.local is being run (its cwd - current working dir).
Try making the paths to the files explicit. Also check out /var/log/messages to see if there are any applicable error messages relevant to your script.
Also remember, rc.local is just another file which can be executed. So to test out if this will work, you can always run ./rc.local from its directory.

Resources