RPI Not Booting because of infinite shell script - linux

so today i was trying to get a shell script(which is an infinite loop) to run on boot in the background of my RaspberryPi's terminal.
I used this command: update-rc.d -f GPIOServer.sh start 4
and then rebooted my pi and after a couple seconds it runs the infinite loop and doesn't boot to the terminal.
i don't know how to cancel the script: ive tried ^C ^Z ^X Esc and i dont want to have to erase all my files etc.
Please help.

There are several options to get a shell without completing the full boot process:
Try switching to a different console for example with CTRL+ALT+F2 (or any other F2-12 key). This will only work if your init script is one of the last scripts to start.
If the ssh server started before your script then you will be able to connect remotely from another computer
Follow Ignacio's recommendation: by taking out the SD card and mounting the SD card on another linux computer and deleting your init script
If you only have a mac or windows machine then you will only be able to edit the boot parition of the SD card. In this case you can modify/add the boot config file cmdline.txt to boot straight into a root terminal. If there is already a cmdline.txt file on the the sd-card then make a backup copy of this file and then simply add init=/bin/bash after the root kernel parameter.
For example, the full line might look something like this:
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p3 init=/bin/bash rootfstype=ext4 elevator=deadline rootwait
If there is no cmdline.txt file on the sd-card then create a new empty text file and just put init=/bin/bash into that file. Your raspberry pi will now boot straight into a root terminal.

Assuming you are not logging in as root. You can try to log in as root and disable the infinite loop for your user's shell.

Related

Creating a bash script that logs the output of 'watch lsusb' into an empty file

I have an embedded Linux system (running Ubuntu 10) on a microprocessor that has an onboard USB hub (specifically a BeagleBone Black).
I made a simple bash script that's supposed to run a command, watch lsusb; and as that runs, my program needs to dump the output my command generates into a text or JSON file (ideally on a USB stick, called usb0 for the sake of the example).
So far, this is what I have:
#!/bin/bash
#DATE=$(date +'%F %H:%M:%S')
DIR=/home/ubuntu/lsusb_logs
CMD='watch lsusb'
$CMD > $DIR
This runs until I stop it, which is fine. But when I go to look at my now created lsusb_logs file, all the data appears to be either encoded or needs to be formatted because its not at all like the original format a single lsusb or even watch lsusb outputs.
The purpose of this script is to gather historical data of the peripherals on the USB hub state over a 24 hour period in an environment chamber (climate stress testing).
Any advice or insight is helpful, thanks.
watch is going to print some non-readable characters because it needs to clear the screen every time it runs the command. You could however just run the command in an infinite while loop with some delay:
while true; do
lsusb >> lsusb_logs
sleep 1 # 1 second delay
done
Instead of looping through the same repetitive command indefinitely, you can take another approach.
You can utilize udev to monitor for plugged or unplugged USB devices, and execute a script at that time.
Example, create 2 scripts:
vi /bin/device_added.sh
vi /bin/device_removed.sh
which will log to a log file the ACTION (added or removed),
and make those executable:
chmod +x /bin/device_added.sh
chmod +x /bin/device_removed.sh
then create a udev rule that will contain the triggers on when a device change is detected:
vi /etc/udev/rules.d/80-test.rules
which will contain for example:
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="/bin/device_added.sh"
SUBSYSTEM=="usb", ACTION=="remove", ENV{DEVTYPE}=="usb_device", RUN+="/bin/device_removed.sh"
This way with your 2 scripts log only upon change, and not all the time..

Linux - shutdown-script with SSH

I would like to make a shutdown-script for my raspberry pi to shut down anothe raspberry pi over ssh.
The script works if it is running itself but at the shutdown routine the ssh command is not executed.
So that I have done until now:
Made the script in /etc/init.d:
#!/bin/sh
# the first thing is to test if the shutdown script is working
echo "bla bla bla " | sudo tee -a /test.txt
ssh pi#10.0.0.98 sudo shutdown -h now
Made it executable
sudo chmod +x /etc/init.d/raspi.sh
Made a symlink to the rc0.d
sudo ln -s /etc/init.d/raspi.sh /etc/rc0.d/S01raspi.sh
Now I know so far that the shutdown script is working outside of the shutdown routing by calling itself and the shutdown symlink I made is also working partially because I see the changes in the test.txt file every time I shut down.
Can anyone help me how to solve my problem?
Have you tried with single quotes?
The first link in Google has it
http://malcontentcomics.com/systemsboy/2006/07/send-remote-commands-via-ssh.html
What about the sudo, how do you solve entering the password?
https://superuser.com/questions/117870/ssh-execute-sudo-command
Please check this or other links on the web that have useful information.
I would have send all this in a comment but I cant yet because of reputation.
I have now got the script running by myself. I do not really know why it is now working but I write it down beneath and maybe someone else can clearifiy it.
I don´t think the first two changes at my system makes a difference but I also write it down. In the meanwhile because I do not managed the script to get working I had made a button to shutdown the system manually. Also I made a script which backs the mysql-database up (which is on the Raspberry Pi which I would like to switch off with the script) and copies the backup to the raspberry pi which should switch of the other raspberry automatically via the shutdown-script. This happens with scp and also for the password is a key generated.
I have also changed my script to get a log-message out of the script.
#!/bin/sh
ssh -t -t pi#10.0.0.99 'sudo shutdown -h now' >> /home/osmc/shutdown.log 2>&1
To get it into the shutdown-routine I used:
sudo update-rc.d raspi-b stop 01 0
I hope somebody can say me why my code now worked on the first day but not on the next few days until now.
I structured a command to suspend or shutdown a remote host over ssh. You may find this useful. This may be used to suspend / shutdown a remote computer without an interactive session and yet not keep a terminal busy. You will need to give permissions to the remote user to shutdown / suspend using sudo without a password. Additionally, the local and remote machines should be set up to SSH without an interactive login. The script is more useful for suspending the machine as a suspended machine will not disconnect the terminal.
local_user#hostname:~$ ssh remote_user#remote_host "screen -d -m sudo pm-suspend"
source: कार्यशाला (Kāryaśālā)

Run a c-programm on startup and see echo via ssh on Raspberry Pi

I have found many ways of starting a script or program when booting Linux, but none of the options is sufficient for what I am looking for:
I have a Raspberry Pi running raspbian wheezy
I have a compiled c-program which creates echo-outputs from time to time
I would like the program to run on startup of the pi and be able to connect via ssh and see what is going on in the program (get echo-live-output, not only a log-file).
Is there any way of achieving this?
To run the program at startup, put it in the root crontab and use the #reboot option. Why don't you want to redirect the output to a log file? Then you can monitor it's output in many ways (eg. using scp).
For anyone encountering a similar problem: I solved it the following way:
I created a startup-bash-script including
sudo /foo/main.o | tee /foo/log;
which writes the output into a log-file. Since the output is created in an infinity-loop, one has to make sure to include a fflush(stdout); after every printf()
Then I can monitor the log-file by using
tail -f /foo/log

Simple replacement of init to just start console

On a very simple PC, I want to replace Ubuntu 12.04 /sbin/init by the most simple bash script in order to have the very minimum number of running processes. Obviously, no X, no USB, no detection of new hardware, no upgrade, no apt, "nothing", I just need a working console with a DHCP-based Wi-Fi IP address (ssid, passphrase are already stored in /etc/network/interfaces). That's all. Currently, I have tried this in replacement of /sbin/init:
#!/bin/sh
mount -o rw,remount /
mount -t proc none /proc
udevd --daemon
mkdir /run/network
ifup -a &
while [ 1 ]; do
/sbin/getty -8 115200 tty1 vt100
done
It's working as I'm getting an IP address and I can login but:
A) While running shutdown, I get "shutdown: Unable to shutdown system:"
B) control-c is not working in the console
C) After a login, I get: "bash: cannot set terminal process group (-1): Inappropriate ioctl for device"
D) After a login, I get: "bash: no job control in this shell"
Also, I have noticed that all the user-space processes have a "?" in the tty column when running ps avx. How can I fix those problems? I don't want to use upstart in order to really control what is started on the PC and have the very bare minimum.
I ended up using Busybox init. Great tiny init...
You could leverage runlevels and based on your question runlevel 3 is what you want to use.
If you have some services that you do not wish to start, you could turn them off too for that runlevel.
For booting into runlevel 3, you just append the boot argument to the kernel in your boot loader:
<EXISTING_BOOT_CMD> 3
If your distro uses systemd instead of sysvinit, they are instead called as targets. The equivalent of runlevel 3 in systemd is usually named as multi-user.target
The kernel boot argument you would need to pass in this case is systemd.unit=multi-user.target
<EXISTING_BOOT_CMD> systemd.unit=multi-user.target
An alternative, if you do not want to touch the boot loader:
systemctl enable multi-user.target

Automatic login on Angstrom Linux

What is a clean way to obtain Angstrom Linux to boot up and open the shell without asking to log in?
This simple answer took me hours to find. For those of you who don't have /etc/inittab the following worked for me. In
/etc/systemd/system/getty.target.wants/serial-getty#ttyO2.service
change the line
ExecStart=-/sbin/getty 115200 %I
to
ExecStart=-/sbin/getty -a USERNAME 115200 %I
I partially figured this out on my own from reading about getty in /etc/inittab, which led me to ExecStart on my system, and a quick google search led me to https://unix.stackexchange.com/questions/42359/how-can-i-autologin-to-desktop-with-systemd which gave me the auto-login syntax of /sbin/getty.
I found a nice way to achieve it. This works for me with Angstrom (on a Beagleboard xM Rev C4).
Make sure agetty is installed (/sbin/agetty is the standard location). It should be included in every Linux Angstrom image.
Create a script file in any location, for example /home/root/autologin.sh. Edit it and add the following:
#!/bin/sh
exec /bin/login -f root
Make it executable with the command
chmod a+x autologin.sh
Edit the file /etc/inittab. Comment out (by adding a “#” at the beginning) the following line
1:2345:respawn:/sbin/getty 38400 tty1
and add the following line:
1:2345:respawn:/sbin/agetty -l /home/root/autologin.sh -n 38400 tty1 linux
Hope this helps out there.
My answer is more linux-generic.
Without a start of a getty-process you doesn't have a passwort login. Look at
/etc/inittab
starts here a *getty-process? Remove this line and restart your device.
1:2345:respawn:/bin/login -f root tty1 </dev/tty1 >/dev/tty1 2>&1
change tty1 for your system configuration, ex) ttyO0, ttyS1, etc..

Resources