How to execute a script when xfce session ends - linux

Is it possible to run a script/command when the xfce session stops ?

See http://mail.xfce.org/pipermail/xfce/2012-November/031694.html - There, Erik Habicht suggested creating a wrapper script in /usr/local/bin/xfce4-session (or another dir that precedes the dir where xfce4-session is installed, /usr/bin in your PATH). This way, you do not have to change /usr/bin/X11/xfce4-session, so it can be updated independently.
#!/bin/bash
# Add your own pre-session logic here
/usr/bin/xfce4-session
# Add your own logout logic here
then
$ chmod +x /usr/local/bin/xfce4-session
It's not perfect (depends on PATH order) but may be more palatable.
(Note: I promoted my comment to an answer.)

Change the /usr/bin/xfce4-session executable with a shell script which runs the original xfce4-session and your logout script if xfce4-session finished.
# mv /usr/bin/xfce4-session /usr/bin/xfce4-session.orig
The new /usr/bin/xfce4-session file:
#!/bin/bash
/usr/bin/xfce4-session.orig
echo "my logout script" > /tmp/testfile
Don't forget to set the execute permissions:
# chmod a+x /usr/bin/xfce4-session
(Tested on Debian Squeeze.)

I'd prefer solution that does not touch system directories or files and will run the logout hook within current user session and its privilledges.
below is my solution:
create ~/.local/bin/xfce4-session-logout script with the following contents:
#!/bin/bash
PRELOGOUT=${HOME}/scripts/pre-logout.sh
RESULT=RES_`echo -e "logout\nrestart\nshutdown\nsuspend" | zenity --height=250 --list --title "Logout from $USER" --column "What do You want to do?"`
case $RESULT in
RES_logout)
[ -x $PRELOGOUT] && $PRELOGOUT
/usr/bin/xfce4-session-logout --fast --logout
;;
RES_restart)
[ -x $PRELOGOUT] && $PRELOGOUT
/usr/bin/xfce4-session-logout --fast --reboot
;;
RES_shutdown)
[ -x $PRELOGOUT] && $PRELOGOUT
/usr/bin/xfce4-session-logout --fast --halt
;;
RES_suspend)
/usr/bin/xfce4-session-logout --suspend
;;
*)
exit 1
;;
esac
and make it executable:
chmod u+x ~/.local/bin/xfce4-session-logout
Now, put whatever You need to be executed at logout action to ~/scripts/pre-logout.sh and make it executable
chmod u+x ~/scripts/pre-logout.sh
after relogin, either menu > logout button or Alt+f3: "logout" will bring simple dialog for leaving the current session
Note: pressing Alt+F4 does not work with it, but maybe some black belted xfce4 users will provide some suggestion

I validated the answer above since it does not involve new code writing.
I however found another way to proceed : create a X11 program which would be launched at session startup : it could execute custom scripts when the X session is closed
Note : the drawback is that the used scripts could not connect to X windows so this solution may, depending on the need, execute the script too late.

Related

How can we prevent CTRL-C from screen terminating?

I'm currently writing a bash script that would create multiple shell instances (with screen command) and execute a subprogram.
The problem is when I try to interrupt the subprogram, it interrupts the screen instance too. I already searched for trap command on internet with SIGINT but I don't really know how to use it in this case.
Here is my code to show you how do I create the screen:
#!/bin/bash
#ALL PATHS ARE DECLARED HERE.
declare -A PATHS; declare -a orders;
PATHS["proxy"]=/home/luna/proxy/HydraProxy; orders+=( "proxy" )
PATHS["bot"]=/home/luna/bot; orders+=( "bot" )
#LAUNCH SERVERS
SERVERS=/home/luna/servers
cd "$SERVERS"
for dir in */; do
d=$(basename "$dir")
PATHS["$d"]="$(realpath $dir)"; orders+=( "$d" )
done
for name in "${orders[#]}"; do
if ! screen -list | grep -q "$name"; then
path="${PATHS[$name]}"
cd "$path"
screen -dmS "$name" ./start.sh
echo "$name CREATED AT $path"
sleep 2
else
echo "SCREEN $name IS ALREADY CREATED"
fi
done
Could you help me more to find a solution please ? Thank you very much for your time.
Each of your screen instances is created to run a single command, start.sh. When this command terminates, for instance when you interrupt it, the screen will have done its job and terminate. The reason for this is that screen runs shell scripts directly in a non-interactive shell, rather than spawning a new interactive shell and running it there.
If you wanted to run start.sh inside an interactive shell in each screen, you'd do something like this:
screen -dmS "$name" /bin/bash -i
screen -S "$name" -X stuff "./start.sh^M"
The ^M is needed as it simulates pressing enter in your shell within screen.
If you use this, then when you interrupt a script within screen, you will still be left with an interactive prompt afterward to deal with as you see fit.

Can't write to file with script

I have written a script that is supposed to run some commands, reboot my ubuntu server and then after the server boots up, resume operation, and removes the entry from the bash file.
I have been trying for hours to figure out why my script won't write to .bashrc (or any file for that matter). Testing the commands individually works just fine. However, when run through my script nothing is written to the file. At this point I am stumped and would really like a fresh pair of eyes to help as I am sure the reason is silly and probably something I am missing. This would be my first script so sorry if this ends up being a stupid question. I put the "sudo reboot command in a comment so I won't have to reboot each time.
The script's name is test.sh and is run from ~/ . I hope this is clear and I didn't miss anything.
#!/bin/bash
echo "Script initiating"
#condition for script to run after reboot, created later on
if [ ! -f /var/run/bootflag ]; then
echo "First run"
script="bash ~/test.sh"
#this will add the script in the bash file so it will be ran on next boot
echo "$script" >> ~/.bashrc
echo "bash entry added"
#creating flag file to check if this is a second run
sudo touch /var/run/bootflag
echo "Flag created"
echo "Rebooting..."
#sudo reboot
else
echo "resuming script..."
echo "cleaning up..."
#remove the bash entry by replacing it with a space
sed -i '/bash/d' ~/.bashrc
echo "bash entry removed"
#remove the boot flag
sudo rm -f /var/run/bootflag
echo "bootflag removed"
echo "running commands post-reboot"
#commands here
echo "script exiting"
fi
I finally figured it out.
Because I was running the script with sudo, the script would take the relative path ~/.bashrc for the root user. The script was working fine all along, I was just looking at my user's .bashrc and was expecting things to appear, when all along the root user's .bashrc file was being written in.
I used sudo inside the script for all elevated commands and run the script normally without sudo and there it is, working as expected.
As I thought, this was beyond silly after all. At least I learned something today.
Thank you all for taking the time to reply and help, I really appreciate it.

Is it possible to auto reboot for 5 loops through mint?

I am currently using the following command to run reboot
sudo shutdown -r now
however, I would need to run it for 5 loops before and after executing some other programs. Was wondering if it is possible to do it in MINT environment?
First a disclaimer: I haven't tried this because I don't want to reboot my machine right now...
Anyway, the idea is to make a script that can track it's iteration progress to a file as #david-c-rankin suggested. This bash script could look like this (I did test this):
#!/bin/sh
ITERATIONS="5"
TRACKING_FILE="/path/to/bootloop.txt"
touch "$TRACKING_FILE"
N=$(cat "$TRACKING_FILE" | wc -c)
if [ "$N" -lt "$ITERATIONS" ]; then
printf "." >> "$TRACKING_FILE"
echo "rebooting (iteration $N)"
# TODO: this is where you put the reboot command
# and anything you want to run before rebooting each time
else
rm "$TRACKING_FILE"
# TODO: other commands to resume anything required
fi
Then add a call to this script somewhere where it will be run on boot. eg. cron (#reboot) or systemd. Don't forget to remove it from a startup/boot command when you're finished or next time you reboot, it will reboot N times.
Not sure exactly how you are planning on using it, but the general workflow would look like:
save script to /path/to/reboot_five_times.sh
add script to run on boot (cron, etc.)
do stuff (manually or in a script)
call the script
computer reboots 5 times
anything in the second TODO section of the script is then run
go back to step 3, or if finished remove from cron/systemd so it won't reboot when you don't want it to.
First create a text document wherever you want,I created one on Desktop,
Then use this file as a physical counter and write a daemon file to run things at startup
For example:
#!/bin/sh
var=$(cat a.txt)
echo "$var"
if [ "$var" != 5 ]
then
var=$((var+1))
echo "$var" > a.txt
echo "restart here"
sudo shutdown -r now
else
echo "stop restart"
echo 0 > a.txt
fi
Hope this helps
I found a way to create a file at startup for my reboot script. I incorporated it with the answers provided by swalladge and also shubh. Thank you so much!
#!/bin/bash
#testing making a startup application
echo "
[Desktop Entry]
Type=Application
Exec=notify-send success
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
Name[en_CA]=This is a Test
Name=This is a Test
Comment[en_CA]=
Comment=" > ~/.config/autostart/test.desktop
I create a /etc/rc.local file to execute user3089519's script, and this works for my case. (And for bootloop.txt, I put it here: /usr/local/share/bootloop.txt )
First: sudo nano /etc/rc.local
Then edit this:
#!/bin/bash
#TODO: things you want to execute when system boot.
/path/to/reboot_five_times.sh
exit 0
Then it works.
Don't forget edit /etc/rc.local and remove /path/to/reboot_five_times.sh when you done reboot cycling.

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.

How to run a Shell Script before shutdown on CentOS

I want to send an email when the system is going to shutdown to an email ID. I have CentOS 6.4. Below is my Script.
cat /ect/init.d/sendshtmail
#!/bin/bash
EMAIL="example#example.com"
SHUTDOWNSUBJECT="["`hostname`"] - System Shutdown"
SHUTDOWNBODY="This is an automated message to notify you that "`hostname`" is shutting down.
LOCKFILE=/var/lock/subsys/SystemEmail
echo "${SHUTDOWNBODY}" | mutt -s "${SHUTDOWNSUBJECT}" ${EMAIL}
It has the appropriate permission. While running it manually it's working perfectly. I have just symlinked it to /etc/rc0.d/ folder. By issuing below command.
ln -s /etc/init.d/sendshtmail /etc/rc0.d/K00sendshtmail
But the script is not sending any email during shutdown. Thanks in Advance.
Place your shell script in /etc/init.d with executable permission and symlink name should start with K##. If you want to execute your script at first place immediately after shut down then name it with K00scriptname. Script started will K will be executed first based on ascending order then script with S.
ln -s /etc/init.d/script /etc/rc0.d/K00scriptname
Shutdown command will send the stop signal to script, your script (K00scriptname) should have stop function like example
stop()
{
echo "executing scriptname"
"Your script logic"
}
case "$1" in
stop)
stop
;;
esac
Most important, K00scriptname will execute only if there would be lock file present in /var/lock/subsys folder, so do "touch /var/lock/subsys/scriptname" then check by doing shutdown.
Try to set executable permissions for your script. Sometimes you need to do that to activate it.
chmod 755 /etc/init.d/sendshtmail
Also try to use absolute paths for your command, while quoting the other variable as well.
echo "${SHUTDOWNBODY}" | /usr/bin/mutt -s "${SHUTDOWNSUBJECT}" "${EMAIL}"
Another attempt is to switch your user to your current user e.g.
echo "${SHUTDOWNBODY}" | su -l -c "/usr/bin/mutt -s \"${SHUTDOWNSUBJECT}\" \"${EMAIL}\"" yourusername
ln -s /etc/init.d/sendshtmail /etc/rc0.d/S01sendshtmail
The symlink name should begin with a S - for Start (K for Kill)
The two-digit specifies the order of execution for your script, the lowest numbered being execute first.

Resources