Raspberry Pi CRON #reboot not firing or firing early - cron

I need to run this command
xinput set-prop ‘raspberrypi-ts’ ‘Coordinate Transformation Matrix’ 0 1 0 -1 0 1 0 0 1
After boot up when the OS desktop is in place and finished loading, so I'm using crontab #reboot command to try and make this work but it seems it's either firing too early or not at all as the touch is still inverted on my screen.
Is there a better way to fire this command after everything has loaded so I can ensure the touch input is altered correctly after boot up
Thank you

Related

Bash script creates zombie and uses 100% CPU

I have a bash script which runs in a loop. Occasionally, the script gets into a state where it is using 100% of the CPU. Looking at pidtree, when that happens, the process has launched a child process to call date.
my_script(401)---my_script(463)---date(15804)
That PID of that child process is never changing. Moreover, that child process is somehow a zombie.
1 R root 463 401 51 80 0 - 4997 - Mar22 ? 6-17:43:01 /bin/bash -eu /usr/sbin/my_script
0 Z root 15804 463 0 80 0 - 0 - Mar28 ? 00:00:00 [date] <defunct>
Luckily, my code has exactly one place where date is called. That line, in a simplified version of the script, looks like (updated to include flock)
LOG="/tmp/foo"
(
flock -e -n 200 || exit 1
while true; do
do_something_that_includes_sleep
vals=("$(date --iso-8601=seconds --utc)")
echo ${vals} >> ${LOG}
done
) 200>>${LOG}
How can this possibly cause date to become a Zombie? Even if it did somehow become a zombie, why would the main script be in Running state consuming 100% of CPU instead of blocking on a pipe read from the child?
After much hair pulling, and several additional failure instances which were investigated with GDB, I now have an answer. There is nothing wrong with the Bash script itself. The problem is the Bash version. What I didn't mention originally is that this problem was only seen when running on Debian Stretch which has Bash version 4.4.11 (from 4.4-5 DEB package). This version has a known bug that was reported back in 2017 and has since been fixed, which explains why my other test systems that are running newer OS's didn't see the same failure.
Original bug report - https://lists.gnu.org/archive/html/bug-bash/2017-02/msg00025.html
There was also a second bug which explicitly documents the 100% CPU utilization waiting for a zombie child at https://lists.gnu.org/archive/html/bug-bash/2017-03/msg00141.html but that ultimately ties back to the original bug report.

Starting a custom screensaver on boot behaves differently than manually starting the screensaver

I have a touchscreen kiosk on which I'm running a webserver. I want to show a slideshow if the screen hasn't been touched for a certain amount of time. For that purpose I have the script below.
#!/bin/sh
# Wanted trigger timeout in milliseconds.
IDLE_TIME=$((15*1000))
# Sequence to execute when timeout triggers.
trigger_cmd() {
DISPLAY=:0 feh -ZXYrzFD 10 /home/pi/screensaver/img --zoom fill &
echo '"pkill -n feh; pkill -n xbindkeys"'>/home/pi/screensaver/xbindkeys.temp
echo "b:1">>/home/pi/screensaver/xbindkeys.temp
DISPLAY=:0 xbindkeys -n -f /home/pi/screensaver/xbindkeys.temp
sudo rm /home/pi/screensaver/xbindkeys.temp
}
sleep_time=$IDLE_TIME
triggered=false
# ceil() instead of floor()
while sleep $(((sleep_time+999)/1000)); do
idle=$(DISPLAY=:0 xprintidle)
if [ $idle -gt $IDLE_TIME ]; then
if ! $triggered; then
trigger_cmd
triggered=true
sleep_time=$IDLE_TIME
fi
else
triggered=false
# Give 100 ms buffer to avoid frantic loops shortly before triggers.
sleep_time=$((IDLE_TIME-idle+100))
fi
done
I use xprintidle to check how long the screen has been idle.
The xbindkeys part is for killing feh when the screen is touched. When I start the script manually I can close the slideshow by touching the screen once and it will reopen after the given idle time. When I start the script via a script in init.d I have to touch the screen twice before it will open the slideshow again, and will never reopen the slideshow if you only touched the screen once.
The script in init.d simply starts the script above as the user pi.
Can someone help me figure out why starting the script on boot apparently causes the script to require two clicks instead of one to start the idle timer?
The touchscreen script is most likely being run by init.d before your DISPLAY environment variable is set (i.e. user pi is not logged in).
Try running this from .bash_profile. That way all your user environment variables will be set especially $DISPLAY and the script will run once upon login.

How to end a process in another linux terminal

Background Info:
I'm trying to set up a remote display using a raspberry pi.
Currently I'm using fbi (frame buffer image viewer) to display the image.
The device is going to be controlled via ssh or web interface - not sure which, but definitely not from the actual device.
The Problem is I cant seem to find an easy way to "clean" quit the process remotely, clear the screen & generate no errors. The fbi program will exit if the q button is pressed but that seems to do no good over ssh. Ideally I'd prefer a less messy solution then having to look up the pid each time before killing it. I am open to the idea of using another program, however I can't run it in Xorg.
I've tried:
Grep-ing the pid and sending kill -sigterm but it either doesn't quit or doesnt clear the screen
echo "q" > /proc/[pid]/fd/0 - all the iterations i try I either get an access denied or nothing happens
Any Ideas?
How to kill a process without a message?
In one terminal, I started a process:
# sleep 100
Now to kill the process, without a message and without knowing the pid:
# kill -13 (pgrep sleep)
How to remotely clear the screen of a terminal?
First, get the tty # of the terminal you want to clear:
# tty
/dev/pts/1
Now from a different terminal:
# printf '\033c' > /dev/pts/1
Without seeing your code, a solution could be to use fbi to just display an image on fb0 from another terminal:
fbi -T 1 -noverbose -d /dev/fb0 image.png
Then just clear the entire framebuffer (fb0):
dd if=/dev/zero of=/dev/fb0
Or better yet, just write a "blank" image to fb0 to "clear" it.

Wait for a process launched by another program to terminate

So I'm creating a quick script that basically launches xboxdrv then a game from steam to enable controller support. Yes, while the most games with controller support automatically work with the Xbox 360 controller, there are some games that require you to be running the controller under the xpad driver, else it won't recognize the controller for some reason. The game in question is Bit.Trip Runner 2 on Linux (XUbuntu).
The problem I'm having is trying to get the script to wait for the game to exit (since it gets launched by steam's own commands), and then terminate xboxdrv, to free up memory, but what is happening is when the game exits, I have to go into the terminal and hit Ctrl+C in order to move it along.
If possible, please explain in layman's terms, because this is my first full out batch scrpt for linux. Below is the script in question:
sudo --validate
sudo xboxdrv --silent --detach-kernel-driver --mimic-xpad --dbus session & sleep 2
steam steam://rungameid/$APPID #<-- I want the game to exit to then kill xboxdrv
wait -n $! #<-- If I don't put wait, it will immediately kill xboxdrv after the game launches
sudo killall xboxdrv
exit 0
Well, it seems like the issue was that wait wasn't applying properly, something about child processes. If it wasn't that it was waiting on xboxrdv, it was that it couldn't apply itself properly. After doing a bit more looking around, I happened upon this question, which gave me the code I needed for the wait. So what I ended up doing was adding that bit of code along with a pgrep -x command, so that it could grab and wait on the proper pid.
So in the end, the important part code ended up looking like this:
if [ "$GAMENAME" = "BTR2" ] || [ "$GAMENAME" = "Runner 2" ]; then
APPID=218060
GameProc=[r]unner2
fi
sudo --validate
sudo xboxdrv --silent --quiet --detach-kernel-driver --mimic-xpad --dbus session & sleep 2
steam steam://rungameid/$APPID & sleep 20
check_run_and_grab(){
if ps aux | grep "$GameProc" > /dev/null
then
GamePID=$(pgrep -x "$GameProc")
while kill -0 "$GamePID";do
sleep 5
done
sudo killall xboxdrv
exit 0
else
echo "Game process not found, waiting 5 seconds and trying again"
sleep 5
check_run_and_grab
fi
}
check_run_and_grab
To me, the only thing that would make this better is if it didn't care for capitalization for the game argument (first if statement).

commands at ubuntu shutdown

How to execute one or more commands and scripts when ubuntu shutdown? Is there any script like /etc/profile and ~/.bashrc at system starting?
I know linux shutdown may have many causes, in addition to dealing with the kill signal, where can I get for this reason?
Is there any script like /etc/profile and ~/.bashrc at system starting?
The SysV Init scripts (/etc/init.d/*) are invoked at startup. A trivial/easy way to invoke some activity at system startup is to put it into /etc/init.d/local (/etc/rc.local for some other distros). See also: RcLocalHowto.
How to execute one or more commands and scripts when ubuntu shutdown?
It sounds as if you want to create a real init script that gets started on entering runlevels X-Z and stopped on exiting them. See also: UbuntuBootupHowto.
I know linux shutdown may have many causes, in addition to dealing with the kill signal, where can I get for this reason?
To do this noninteractively is not straightforward. You can grep through the system logs, looking for indications from shutdown.
There is a ~/.bash_logout file that executes when you log out of Ubuntu 11.04
I am not sure, but assume there is a similar script in 10.04
Hope this helps.
You can put your script in /etc/rc0.d (for halt) and /etc/rc6.d/ (for reboot). Make sure script has executable permission.
There is differents run level :
* 0 System Halt
* 1 Single user
* 2 Full multi-user mode (Default)
* 3-5 Same as 2
* 6 System Reboot
Run level 0 is the system halt condition. When run level 0 is reached all scripts in /etc/rc0.d are exectute.
Run level 6 is used to signal system reboot. This is the same as run level 0 except a reboot is issued at the end of the sequence instead of a power off.
If you want to execute your script on hibernate or on sleep, put your script in /etc/pm/sleep.d/
This is a example of script :
#!/bin/sh
WLANSTATUS=`cat /sys/class/ieee80211/phy*/rfkill*/state`
test -z $WLANSTATUS && exit 1
case $1 in
hibernate)
# Do something before hibernate
;;
suspend)
# Do something before sleep
;;
thaw)
# Do something after hibernate
;;
resume)
# Do something after sleep
if [ $WLANSTATUS = 0 ]; then
echo 0 > /sys/devices/platform/asus_laptop/wlan
elif [ $WLANSTATUS = 1 ]; then
echo 1 > /sys/devices/platform/asus_laptop/wlan
fi
;;
*) echo "somebody is calling me totally wrong."
;;
esac
Have fun !

Resources