1

I wish to execute a script every time on boot-up using /etc/rc.local.

My script for example is called startscript.sh which is stored in /home/debian as below. It first tries to create a file called test.log and then does other things.

However, I read the error on boot-up that touch: cannot touch ‘test.log’: Permission denied

How is this even possible if, from what I understand, rc.local gets run as root, therefore anything it executes should be run as root as well, and hence test.log should be created regardless?

startscript.sh:

#!/bin/sh
touch test.log
#... other stuff

rc.local snippet:

#!/bin/sh -e
#.. other stuff
sh /home/debian/startscript.sh
Kusalananda
  • 333,661
Engineer999
  • 1,151
  • 2
    You can get permission denied even as root: try to write to a read-only filesystem, try to write to a special filesystem (e.g., /proc or /sys) in a not-permitted way, try to write to a network filesystem (server does permission checks, too), etc... You haven't really given us enough information to figure out which you're seeing. What is the current working directory of startscript.sh? – derobert Feb 06 '19 at 18:41
  • 1
    To build off of user derobert, please include what permissions your script has, as well as the permissions of the working directory of the script or where the script is being run from. Is your / filesystem mounted as read only? Either touch is being run in a filesystem that is mounted as read-only or the script is being run before the filesystem has assigned the relevant options in fstab during the boot up process. The first option is far more likely than the latter I feel. – kemotep Feb 06 '19 at 18:51
  • @derobert and @Engineer999: unless the #.. other stuff includes any explicit cd commands, then the current working directory of startscript.sh will be /, and so the file it's attempting to create will be /test.log. When you log in, your working directory is set to be your home directory (on modern systems, most likely by the PAM session module), but for start-up scripts, this convenience does not exist. – telcoM Feb 06 '19 at 19:16
  • @derobert The current working directory for startscript.sh is /home/debian as shown in the rc.local file snippet – Engineer999 Feb 07 '19 at 15:46
  • @kemotep The file system is not read-only. This is why I don't understand the problem. It should create the file . I also did sudo chmod 777 /home/debian to ensure everyone has permissions and it still complains – Engineer999 Feb 07 '19 at 15:49
  • @Engineer999 please edit your post to include that information as well as whether your file system employs an ACL. I have found this post that includes a script to assist in debugging. Perhaps you can add that information to your post after you try it? – kemotep Feb 07 '19 at 16:16
  • @Engineer999 your snipped doesn't show that. sh /home/debian/startscript.sh does not change the current working directory. (cd /home/debian/ would, but just executing a script out of it does not.) – derobert Feb 07 '19 at 20:15
  • @derobert ah ok. I see what you mean. So i'm actually trying to create file test.log in the same working directory wherever rc.local is being executed? So when I just do sh /home/debian/startscript.sh , i'm not actually executing that inside /home/debian/startscript.sh. This is my problem I guess :)) – Engineer999 Feb 11 '19 at 16:39
  • @Engineer999 could well be. A simple cd /home/debian && ./startscript.sh would fix that. (Though do pay attention the warnings Ken Jackson has given you.) – derobert Feb 11 '19 at 18:32

2 Answers2

1

There are two problems with that approach. One, rc.local is executed by root, so all the files it creates will be owned by root unless you run chown on them. Second, it's a security hole in that root executes code which is potentially modifiable by a user without root privilege.

A better way is to use the @reboot time specifier with cron as an unprivileged user. If you already have a crontab file, edit it to add this line and then run the crontab <yourcrontab> command. Or use the crontab -e command to enter this line directly.

@reboot /home/debian/startscript.sh

Note that you don't need sh if the script is executable because it starts with #!/bin/sh.

  • 2
    Or one could write a native service definition for whatever one's service manager is, with appropriate user account settings. https://unix.stackexchange.com/a/471871/5132 – JdeBP Feb 06 '19 at 19:56
  • I don't want a better way. I know Cron works ok for this. I'm just trying to understand why rc.local won't work – Engineer999 Feb 07 '19 at 15:45
1

If your distribution uses systemd, the problem might be that /etc/rc.local gets executed too early, while the root filesystem is still read-only, or while some of the other file systems are not mounted yet.

If the systemd .service file that runs rc.local has no specific order dependencies configured, systemd will run it as early as possible.

Run systemctl cat rc-local.service to see the full definition of the service that runs rc.local. Pay attention to any After= lines, and think about the earliest possible point in the system start-up process that can satisfy those. You might want to add an override file that adds an extra After= line or two to suit the needs of your configuration.

telcoM
  • 96,466