Linux script not executing properly after a reboot - linux

I am using a raspberry pi4 with 32bit Raspbian to display some webpages. I have a script to open 2 webpages, one on each monitor. The end of the script selects one of the pages and enters in login credentials. The script works great and I have it working with systemctl to auto start on reboot. The problem is the script doesn't always select the window after a reboot of my pi. It works 50% of the time. Which I believe is just which page happens to open first. Sometimes the cursor is left on the correct page. This happens whether I am using the systemctl or not.
The line it seems to ignore is:
xdotool search --name 'Login'>xdotool windowactivate
Troubleshooting that I did:
Waiting a long time after rebooting - This didn't work
Changed windowactivate to windowfocus - This made no difference
Removing the --kiosk flag - This didn't work
Closing the windows and running the script again - Works every subsequent time
Opening a browser and closing it after reboot then running script - Works every subsequent time
This led me to the next step which was to add a sleep in between opening the browsers. My hope was that once the second browser opened it would just be left as the active browser. Unfortunately this solidified my conclusion that the script isn't executing properly after a reboot.
After adding the sleep, the browsers open simultaneously after a reboot ignoring the sleep command. However, if I close the browsers and run the script again the sleep command works and 1 browser opens then the other one after the sleep.
Then I tried adding at the beginning of the script to open a browser and
then close it and then continuing the script -This didn't work.
Almost as if ignoring the opening and closing of the browser? I tried buffering the 2 commands with sleep but it ignored those as well.
The script works 100% of the time either the second time it is run or after opening and closing a browser.
Below is my script.
#!/bin/bash
xset s noblank
xset s off
xset -dpms
unclutter -idle 0.5 -root &
sed -i 's/"exited_cleanly":false/"exited_cleanly":true/' /home/pi/.config/chromium/Default/Preferences
sed -i 's/"exit_type":"Crashed"/"exit_type":"Normal"/' /home/pi/.config/chromium/Default/Preferences
rm -rf ~/.config/chromium/Singleton*
/usr/bin/chromium-browser --new-window --noerrdialogs --disable-infobars --kiosk --user-data-dir="/tmp/1" --window-position=0,0 'http://ExampleDisplay.com' &
/usr/bin/chromium-browser --new-window --noerrdialogs --disable-infobars --kiosk --user-data-dir="/tmp/2" --window-position=2500,0 'http://ExampleLogin.com' &
sleep 7
xdotool search --name 'Login'>xdotool windowactivate
sleep 2.5
xdotool type 'TEST' # CHANGE THIS FOR DIFFERENT LOGIN
sleep .2
xdotool key 'Tab'
sleep .2
xdotool type 'TEST' # CHANGE THIS FOR DIFFERENT LOGIN
sleep .2
xdotool key 'Return'
sleep 4
xdotool type 'TESTORG' # CHANGE THIS FOR DIFFERENT ORGANIZATION
sleep .2
xdotool key 'Tab'
sleep .2
xdotool key 'Tab'
sleep .2
xdotool key 'Tab'
sleep .2
xdotool type 'TESTSTATION' # CHANGE THIS FOR DIFFERENT STATION
sleep .2
xdotool key 'Return'
To rule out other parts of the script I tried boiling it down to the very basic issue of opening the browsers one after the other with this script. This had the same issue: after a reboot it opens both browsers ignoring the sleep function. Then, if run again, it works.
#!/bin/bash
/usr/bin/chromium-browser --new-window --noerrdialogs --disable-infobars --kiosk --user-data dir="/tmp/1" --window-position=0,0 'http://ExampleDisplay.com' &
sleep 5
/usr/bin/chromium-browser --new-window --noerrdialogs --disable-infobars --kiosk --user-data-dir="/tmp/2" --window-position=2500,0 'http://ExampleLogin.com' &
Lastly, here is my systemctl (this shouldn't be needed because it happens regardless of using the systemctl, but just in case)
[Unit]
Description=Chromium Kiosk
Wants=graphical.target
After=graphical.target
[Service]
Environment=DISPLAY=:0.0
Environment=XAUTHORITY=/home/pi/.Xauthority
Type=forking
ExecStart=/bin/bash /home/pi/kiosk1.sh
Restart=on-abort
User=pi
Group=pi
[Install]
WantedBy=graphical.target
As a side note, I tried an alternative solution using a python script for the opening of the browsers using the multibrowse.py script from https://github.com/foxxyz/multibrowse and had the same issues even when adding the sleep calls between the browsers in the python script.

I don't use xdotool, but suspect you want:
xdotool windowactivate $(xdotool search --name 'Login')
Hopefully that means you will activate the window whose name is 'Login', which the xdotool search ... found.

Related

Script runs fully when ran manually but misses commands when ran from another script

I have 2 scripts that I'm testing to automate starting services on my server however they behave weirdly.
The first script is
#!/bin/sh
screen -dmS Test_Screen
sleep 1
sudo sh cd.sh
echo "finished"
Which runs perfectly however the script it runs does not and is as follows
#!/bin/sh
screen -S Test_Screen -X stuff "cd /home/Test"
sleep 1
screen -S Test_Screen -X eval "stuff \015"
sleep 1
echo "Complete"
The second script will run perfect if I run it from command line and will CD into the directory within the screen. However, if it runs from the first script it Will Not CD into the correct directory within the screen, but it will still print "Complete".
I'm Using CENTOS 6.7 and the latest version of GNU screen
Any Ideas?
This seems to be a problem with session nesting.
In your first script you create a session named Test_Screen.
In your second script the -S parameter tells screen to create a session of the same name. This might cause screen to exit and not cd into the correct directory.
You could move the cd command in front of the sudo sh cd.sh and remove those screen calls from the second script leaving only
stuff \015
echo "Complete"
Using the correct screenflags should also work.
#!/bin/sh
screen -dr Test_Screen -X stuff "cd /home/Test"
sleep 1
screen -dr Test_Screen -X eval "stuff \015"
sleep 1
echo "Complete"
For a more modern alternative to screen, have a look at tmux.
Ok so this turned out really weird. After posting i tried a couple of things on a centos 6.7 hyper V test environment and got the exact same issue. However, later in the day we ended up changing service provider and upgrading to centos 7 in the process. I am not sure why but since the update the script now runs perfectly and i was able to actually merge the two scripts into one in order to make it more efficient. If anyone knows why the update fixed it feel free to let me know.

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 make xdotool work with matchbow-window-manager?

I have trouble using xdotool to simulate simple keypresses in my browser.
Now my browsers starts up on boot by adding the following code in '/home/pi/.xintirc'
#!/bin/sh
xset -dpms
xset s off
xset s noblank
// not sure if this is needed.
killall -TERM matchbox-window-manager 2>/dev/null;
killall -9 matchbox-window-manager 2>/dev/null;
exec matchbox-window-manager -use_titlebar no &
iceweasel [someURL]
python /etc/xdo_test.py
My /etc/xdo_test.py looks as follows:
import time
import subprocess
time.sleep(20)
subprocess.call(["xdotool", "key", "c"]);
I don't have any output of this file while using it on startup but if I excecute this in another console, I get the following output:
Error: Can't open display: (null)
Failed creating new xdo instance
Does anyone have an idea why I get this error and how to solve it?
You use in the python script the subprocess.call command. This call don't set the currently set environment variables in the subprocesse. Hence the missing display. Simply call the xdotool command in the .xinitrc file directly.
#!/bin/sh
xset -dpms
xset s off
xset s noblank
// not sure if this is needed.
killall -TERM matchbox-window-manager 2>/dev/null;
killall -9 matchbox-window-manager 2>/dev/null;
exec matchbox-window-manager -use_titlebar no &
iceweasel [someURL] & #<--- add ampersand
sleep 20
# you have to determine the window to which you want to send the keystroke
WIN=`xdotool search --sync --onlyvisible --class iceweasel | head -1`
# then activate it
xdotool windowactivate $WIN
# and send the keystroke
xdotool key --window $WIN c
If you have problems with the ampersand in the iceweasel call try to put quotes around the URL.
I got it to work. I eventually found this tutorial and used some ideas from it. I'll post the solutions for the people who may have a similar problem.
This is what i placed in the /home/pi/.xinitrc file:
#!/bin/sh
xset -dpms
xset s off
xset s noblank
// not sure if this is needed.
killall -TERM matchbox-window-manager 2>/dev/null;
killall -9 matchbox-window-manager 2>/dev/null;
exec matchbox-window-manager -use_titlebar no &
iceweasel [someURL] &
sudo /etc/xdo_test.sh
I changed the python script to a shell script an inserted the following code:
sleep 20
$WIN=$(xdotool search --onlyvisible --class Iceweasel|head -1)
xdotool key --window $WIN c
while:
do
sleep 300
done
The while loop at the end is something I added because Xserver crashed from the moment it lost connection to the script. I'm still looking for a cleaner solution to end the script but this works for now. I'll update this awnser when I find one.
Thanks Sebastian Stigler for the help!
call xdo_test.sh before running the window manager

Running Shell Script after boot on Raspberry PI

I'm making a web kiosk display board using a raspberry pi and I want to send some key strokes to the browser window 2 minutes after it's loaded. The script sends the logon details for a webserver.
I've got a script that sends the keystrokes which works fine from the telnet console:
#!/usr/bash
username="username"
password="password"
echo "Setting Display"
export DISPLAY=:0
echo "Sending Username"
for char in $(sed -E s/'(.)'/'\1 '/g <<<"$username"); do
xdotool key $char
done
xdotool key Tab
echo "Sending Password"
for char in $(sed -E s/'(.)'/'\1 '/g <<<"$password"); do
xdotool key $char
done
xdotool key Return
echo "Waiting 5 Seconds"
sleep 5
echo "Setting Remember Password"
xdotool key Tab
xdotool key Tab
xdotool key Return
echo "Finished"
I've tried to add bash /home/pi/logon.sh to the rc.local file - but it doesn't send the keystrokes to the browser?
Does any one know why that would be? As I say - it works fine from the telnet window if I run the script, but it doesn't work when run from boot.
I had sleep 120 on the line before it to stop if firing right away and wait until the browser has loaded - and I know the script is running from rc.local, because when I remove the sleep command, I see the echos from the script.
Any ideas?
The reason it wasn't working was because the script needed to be run as the user pi.
I changed the code in the rc.local script to this: su - pi -c "bash /home/pi/logon.sh &"
This makes the script run as the user pi and the ampersand is used to make the script run separate to the rc.local script by forking it. (http://hacktux.com/bash/ampersand)
Put this in your crontab
#reboot /path/to/script
Edit it using
#crontab -e

cygwin: How to make a Windows Menu launcher for a remote application

I have made a application launcher for Thunderbird (called mythunderbird) on a remote machine using the .XWinrc file.
menu apps {
xterm exec "xterm"
"Emacs" exec "emacs"
notepad exec notepad
xload exec "xload -display %display%" # Comment
mythunderbird exec "ssh -X mckserver.mckserver.apollo3.com thunderbird"
}
This starts beautifully with a multiple of keystrokes (right click XWin > (pint to Applicatoins) > click mythunderbird.
Can someone tell me how I can add such a menu to a desktop short cut? Putting a short cut to run "xterm" then logging in to the remote server and starting Thunderbird is easy, but a lot of steps and clicks.
What I really need to do is know what to change in this default short cut for starting xterm:
C:\cygwin\bin\run.exe -p /usr/X11R6/bin xterm -display 127.0.0.1:0.0 -ls
What I like about the functionality of the XWinrc application is that it has a clean execution of Thunderbird without the residue of an extra terminal left running. If I start it outside XWinrc, I have Thunderbird running, but also an extra xterm running.
The way I got it to work was to make a script in cygwin in my home directory (/home/dave/mythunderbird) which does the ssh call.
In the windows shortcut, set the target C:\cygwin\bin\run.exe bash -le /home/dave/mythunderbird
run.exe stops the command window being displayed and bash -le runs the script in bash from a login shell

Resources