Link to home
Start Free TrialLog in
Avatar of remeshk
remeshkFlag for United States of America

asked on

how to execute a custom shell script in startup while user's login

how to execute a custom shell script in startup while user's login to the system other than below method.

I had added my script in .bashrc & .bash_profile  but users are using  "bash --noprofile --norc" option, this won't read the startup files.

please help with your suggestions to achieve this.
Avatar of ITguy565
ITguy565
Flag of United States of America image

Maybe this will help :

https://linuxconfig.org/how-to-automatically-execute-shell-script-at-startup-boot-on-systemd-linux

Systemd service unit
First, we need to create a systemd startup script eg.disk-space-check.serviceand place it into /etc/systemd/system/ directory. You can find the example of such systemd startup script below:
[Unit]
After=mysql.service

[Service]
ExecStart=/usr/local/bin/disk-space-check.sh

[Install]
WantedBy=default.target
After: Instructs systemd on when the script should be run. In our case the script will run after mysql database has started. Other example could be network.target etc.
ExecStart: This field provides a full path the actual script to be execute
WantedBy: Into what boot target the systemd unit should be installed
The above is an absolute minimum that our systemd service unit should contain in order to execute our script at the boot time. For more information and options to be used see systemd.service manual page:
$ man systemd.service
Startup shell script
Next, we create our custom shell script to be executed during systemd startup. The location and script name is already defined by service unit as /usr/local/bin/disk-space-check.sh. The content of the script can be simple as:
#!/bin/bash

date > /root/disk_space_report.txt
du -sh /home/ >> /root/disk_space_report.txt
Configure and Install
Before we reboot our system we need to make our script executable:
# chmod 744 /usr/local/bin/disk-space-check.sh
Next, install systemd service unit and enable it so it will be executed at the boot time:
# chmod 664 /etc/systemd/system/disk-space-check.service
# systemctl daemon-reload
# systemctl enable disk-space-check.service
Created symlink from /etc/systemd/system/default.target.wants/disk-space-check.service to /etc/systemd/system/disk-space-check.service.
If you wish to test your script before you reboot run:
# systemctl start disk-space-check.service
# cat /root/disk_space_report.txt
Thursday 7 July  11:30:25 AEST 2016
1.5G    /home/
All ready. After rebooting your Linux system the above systemd unit will invoke shell script to be executed during the boot time.
Avatar of remeshk

ASKER

Thank you for the update. I am looking for user login startup script.  When user is login to the system I need to execute this script.  this only for user login not system wide.
I had added my script in .bashrc & .bash_profile

That Is the only way I know to do it.
Avatar of remeshk

ASKER

any other suggestions ?  I am looking this for only root user. when ever who access the root user shell I want to get a notification. is there any other method if I can achieve this ?
Avatar of noci
noci

Yes there still is an option:

create a script:      /bin/myforcedlogin
$ cat >/bin/myforcedlogin   <<EOF
#!/bin/bash

wall Root logging in Hide....
source /etc/profile
echo And whatever you want to do......

exec /bin/bash $*
EOF
$ chmod 755 /bin/myforcedlogin
$ echo /bin/myforcedlogin >>/etc/shells
$ #Then assign this as a shell to the intended user...
$ usermod -s /bin/myforcedlogin  theforceduser

Open in new window

This assumes /bin/bash is the regular shell though... and it exists.
You will need to make adjustments accordingly.

And of course if you want to force some flags on bash it can be done as well.. on line 1 for this script, on the exec line for the later script.
Using same code from noci
created and tested following file 29095044.sh using root user and murugesandins user.
#!/bin/ksh
ID=$(/usr/bin/id -u)
if [ $ID -eq 0 ]
then
	/bin/ps -eaf |\
	/bin/grep 29095044.sh |\
	/bin/egrep -v "\/bin\/grep|\/bin\/ps" |\
	/bin/egrep "\/usr\/bin\/sudo" >/dev/null 2>&1
	if [ $? -eq 0 ]
	then
		echo "Executing $0 using /usr/bin/sudo not allowed"
		echo "ERROR" | /bin/grep exception
	else
		if [ $# -eq 0 ]
		then
			echo "Usage:"	
			echo "$0 UserName"	
			echo "ERROR" | /bin/grep exception
		else
			LOGNAME=$(/usr/bin/whoami)
			CHG_DEFAULT_SHELL="n"
			USERSHELL=$(/usr/bin/getent passwd "$1" 2>/dev/null |\
			/bin/awk -F: '{ print $NF}')
			if [ "$USERSHELL" = "" ]
			then
				echo "No such user: $1"
				echo "ERROR" | /bin/grep exception
			else
				if [ ! -f ~$LOGNAME/Default_shell_for_users.txt ]
				then
					echo "$USERSHELL $1" > ~$LOGNAME/Default_shell_for_users.txt
					CHG_DEFAULT_SHELL="y"
				else
					/bin/grep "$USERSHELL $1" ~$LOGNAME/Default_shell_for_users.txt >/dev/null 2>&1
					if [ $? -ne 0 ]
					then
						if [ "$USERSHELL" != "/bin/myforcedlogin" ]
						then
							echo "$USERSHELL $1" >> ~$LOGNAME/Default_shell_for_users.txt
							CHG_DEFAULT_SHELL="y"
						fi
					fi
				fi
				if [ ! -f /bin/myforcedlogin ]
				then
					if [ "$USERSHELL" != "/bin/myforcedlogin" ]
					then
						USER_DEFAULT_SHELL=$(/bin/grep "$USERSHELL" ~$LOGNAME/Default_shell_for_users.txt |\
						/bin/egrep -v "\/bin\/myforcedlogin" |\
						/bin/awk '{ print $1}')
						if [ "$USER_DEFAULT_SHELL" = "/bin/myforcedlogin" ]
						then
							USER_DEFAULT_SHELL="/bin/bash"
						fi
					else
						USER_DEFAULT_SHELL="/bin/bash"
					fi
					echo "Creating file /bin/myforcedlogin"
					/bin/cat >/bin/myforcedlogin   <<EOF
#!/bin/ksh
/usr/bin/wall Root logging in Hide....
source /etc/profile
echo And whatever you want to do......
exec $USER_DEFAULT_SHELL \$*
EOF
					echo "/bin/cat /bin/myforcedlogin"
					/bin/cat /bin/myforcedlogin
				fi
				FORCED_LOGON_MOD=$(/usr/bin/stat -c "%a" /bin/myforcedlogin)
				if [ $FORCED_LOGON_MOD -ne 755 ]
				then
					echo /bin/chmod 755 /bin/myforcedlogin
					/bin/chmod 755 /bin/myforcedlogin
				fi
				/bin/grep -l "/bin/myforcedlogin" /etc/shells >/dev/null 2>&1
				if [ $? -ne 0 ]
				then
					echo /bin/myforcedlogin >>/etc/shells
				fi
				if [ "$USERSHELL" != "/bin/myforcedlogin" ]
				then
						echo /usr/sbin/usermod -s /bin/myforcedlogin  $1
						/usr/sbin/usermod -s /bin/myforcedlogin  $1
						echo "/bin/myforcedlogin change applied for $1"
				else
					echo "/bin/myforcedlogin was changed"
				fi
			fi
		fi
	fi
else
	echo "$LOGNAME not allowed to execute this script"
fi

Open in new window

Test results
murugesandins@localhost /home/murugesandins [ 0 ]
$ /bin/ls -ld ~root/29095044.sh
/bin/ls: cannot access '/root/29095044.sh': Permission denied
murugesandins@localhost /home/murugesandins [ 2 ]
$ /usr/bin/sudo /bin/ls -ld ~root/29095044.sh
-rwxr-xr-x 1 root root 2511 May 17 10:35 /root/29095044.sh
murugesandins@localhost /home/murugesandins [ 0 ]
$ /usr/bin/sudo ~root/29095044.sh
Executing /root/29095044.sh using /usr/bin/sudo not allowed
murugesandins@localhost /home/murugesandins [ 1 ]
$ /bin/su - root
Password:
root@localhost /root [ 0 ]
$ ~root/29095044.sh
Usage:
/root/29095044.sh UserName
root@localhost /root [ 1 ]
$ /usr/bin/sudo ~root/29095044.sh
Executing /root/29095044.sh using /usr/bin/sudo not allowed
root@localhost /root [ 1 ]
$ ~root/29095044.sh testing
No such user: testing
root@localhost /root [ 1 ]
$ ~root/29095044.sh murugesandins
/usr/sbin/usermod -s /bin/myforcedlogin murugesandins
/bin/myforcedlogin change applied for murugesandins
root@localhost /root [ 0 ]
$ ~root/29095044.sh murugesandins
/bin/myforcedlogin was changed
root@localhost /root [ 0 ]
$ /usr/sbin/usermod -s /bin/ksh  murugesandins
root@localhost /root [ 0 ]
$ ~root/29095044.sh murugesandins
/usr/sbin/usermod -s /bin/myforcedlogin murugesandins
/bin/myforcedlogin change applied for murugesandins
root@localhost /root [ 0 ]
$ su - murugesandins

Broadcast message from murugesandins@localhost (pts/9) (Thu May 17 10:37:

Root logging in Hide....

And whatever you want to do......
murugesandins@localhost localhost [ 0 ]
$

Open in new window

Exceptions I prefer using scripts:
1. Using full path for any Linux oriented commands
2. Save default shell and user names
root@localhost /root [ 0 ]
$ cat ~/Default_shell_for_users.txt
/bin/ksh murugesandins
root@localhost /root [ 0 ]
$

Open in new window

3. Do not allow /usr/bin/sudo ~root/29095044.sh
      a. from other user
      b. root user also not allowed using /usr/bin/sudo
4. Handle exceptions:
Example:
$ 29095044.sh
Usage:
29095044.sh UserName
$ echo $?
1
$ 29095044.sh testing
No such user: testing
$ echo $?
1
$ 29095044.sh murugesan.nagarajan
/usr/sbin/usermod -s /bin/myforcedlogin murugesan.nagarajan
/bin/myforcedlogin change applied for murugesan.nagarajan
$ echo $?
0
$ 29095044.sh murugesan.nagarajan
/bin/myforcedlogin was changed
$ echo $?
0

5. Verified non-existence of users
>> From noci
>> This assumes /bin/bash is the regular shell though... and it exists
Replaced:
        exec /bin/bash $*
with (inside the script):
        exec $USER_DEFAULT_SHELL \$*
@Ramesh,
Accept/assist to finish current query
or post your comments if any update required.
This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.