# Execute script after FreeBSD is rebooted



## Sessa (Jan 7, 2019)

Hi,

I'd like to start a script (or some more) automatically after the system is rebooted.
I tried already this: https://unix.stackexchange.com/ques...cript-that-it-will-run-on-start-up-in-freebsd

But it does not work. Which way is the way which works fine? 
Im using the newest FreeBSD. 

Thanks a lot


----------



## SirDice (Jan 7, 2019)

Sessa said:


> Which way is the way which works fine?


Create your own rc(8) script.


----------



## Phishfry (Jan 7, 2019)

Another good resource for creating rc.d bootup daemons.
https://www.freebsd.org/doc/en/articles/rc-scripting/


----------



## olli@ (Jan 7, 2019)

Actually, the way described in the linked article (using `@reboot` with cron) _does_ work.
If it doesn't work for you, there's probably a mistake in the script or in the way it is called. In particular, the script runs with a reduced environment, for example the PATH is different. See the crontab(5) manual page for details. Also, if there is any problem with your cron job, you will receive the output (error messages) via e-mail.

Would you please share your exact crontab entry with us? Might be easier to advise what the problem could be. Also, do you receive output from the cron job via e-mail?


----------



## Phishfry (Jan 7, 2019)

We also have /etc/rc.local for short and sweet scripts.
https://forums.freebsd.org/threads/script-at-boot.20681/


----------



## olli@ (Jan 7, 2019)

Indeed, there are several ways to execute things upon reboot.
Just keep in mind that rc scripts are executed with root privileges. If you don't need that, it's safer to use a user cronjob.


----------



## Phishfry (Jan 7, 2019)

One more method is 'per-user' with /$USER/.profile and /$USER/.login


----------



## Sessa (Jan 7, 2019)

I tried to understand rc i made following script which is located in /etc/rc.d/:


```
#!/bin/sh

. /etc/rc.subr

name="dir"
start_cmd="${dir}_start"
stop_cmd=":"

dir_start()
{
    mkdir /test
}
```
But this does not work. What have i made wrong?




olli@ said:


> Actually, the way described in the linked article (using `@reboot` with cron) does work.


I made a script which is located in /.
I edit the `crontab -e` file and paste following in this file: `@reboot /script.sh` and tried. Does not work. Than I have edit it: `@reboot sh /script.sh`.
Does still not work.

//
Execute as root is OK.


----------



## olli@ (Jan 7, 2019)

Sessa said:


> I made a script which is located in `/`.
> I edit the `crontab -e` file and paste following in this file: `@reboot /script.sh` and tried. Does not work. Than i have edit it: `@reboot sh /script.sh`.
> Does still not work.


Is the script executable (chmod +x)? Does it produce any output? If in doubt, put something like this at the beginning:

```
date >> /tmp/script-debug.log
```
So you can see if your script is started at all.
Also, look in /var/mail if you have any output mailed from the cron job.
If your mail system is not configured correctly, a work around is to redirect all output to a log file:

```
@reboot /script.sh >> /tmp/script-output.log 2>&1
```


----------



## SirDice (Jan 7, 2019)

Sessa said:


> ```
> start_cmd="${dir}_start"
> ```


Typo here. The variable ${dir} doesn't exist, it should probably be ${name} instead. In your version the start_cmd points to a function named _start (which doesn't exist) when it should be pointing to dir_start.


----------



## Sessa (Jan 7, 2019)

olli@ said:


> Is the script executable (chmod +x)?


Yes.



olli@ said:


> So you can see if your script is started at all.


There is no file. So the script was not executed. Any other idea?
`@reboot sh /script.sh` OR `@reboot /script.sh`?



SirDice said:


> The variable ${dir} doesn't exist, it should probably be ${name} instead. In your version the start_cmd points to a function named _start (which doesn't exist) when it should be pointing to dir_start.


Could you show me how the script is right? So maybe i understand it than better 
For the beginning it is OK when the script creates a dir.


----------



## SirDice (Jan 7, 2019)

This is wrong:

```
start_cmd="${dir}_start"
```
It should be:

```
start_cmd="${name}_start"
```
OR

```
start_cmd="dir_start"
```

The ${name} is a variable. It's set on the line above it: `name="dir"`.

If you're having trouble with shell scripts I can highly recommend: http://www.grymoire.com/Unix/Sh.html
It's an old site but I still use it quite often for reference.


----------



## olli@ (Jan 7, 2019)

Sessa said:


> I tried to understand rc i made following script which is located in /etc/rc.d/:


Your script should contain at least one REQUIRE line. Otherwise it is undefined at which point it is executed during reboot (for example, it could be executed before file systems are mounted, which is probablt too early). This is documented in the rcorder(8) manual page. To run the script rather late during reboot (so filesystems, networking and the standard daemons are running), the following dependency line can be used:

```
# REQUIRE: LOGIN
```


----------



## olli@ (Jan 7, 2019)

Sessa said:


> There is no file. So the script was not executed. Any other idea?


That's very strange. Do you have cron disabled? (By default it's enabled.)
Otherwise I guess there must be something fundamentally wrong with your script.


> `@reboot sh /script.sh` OR `@reboot /script.sh`?


Both should work. By default cron uses /bin/sh to execute commands (see the description of the SHELL variable in the crontab(5) manual page), so you don't have to specify it.
Actually, just specifying “sh” (as opposed to “/bin/sh”) is not a good idea, because it relies on the PATH setting.


----------



## Sessa (Jan 7, 2019)

Alright, got it. I have define a wrong bash location in the crontab file.
I comment it out and everything works fine.

When i try to set another editor with `@reboot setenv EDITOR /usr/local/bin/nano` directly in the crontab, is does not work?


----------



## olli@ (Jan 7, 2019)

Sessa said:


> Alright, got it. I have define a wrong bash location in the crontab file.
> I comment it out and everything works fine.


It's better to use the base system's /bin/sh for such things, not bash.


> When i try to set another editor with `@reboot setenv EDITOR /usr/local/bin/nano` directly in the crontab, is does not work?


Wait a second – Are you trying to set an environment variable globally for all users? In that case, a reboot script is not the right place to do that, because the variable is only set for the duration of the script. You probably want to modify /etc/login.conf instead.
However, it's usually not good practice to force such settings on all users. If you prefer nano personally, you should set the EDITOR variable inside your login shell's profile (the details depend on which login shell you use).


----------



## Sessa (Jan 7, 2019)

olli@ said:


> If you prefer nano personally, you should set the EDITOR variable inside your login shell's profile (the details depend on which login shell you use).



Ah, that's a good idea.
If I set the editor variable to nano and then reboot, the default editor is Vim again.
With this "restart script" I would want to make the env again set as the default editor on nano.


----------



## SirDice (Jan 7, 2019)

Sessa said:


> When i try to set another editor with `@reboot setenv EDITOR /usr/local/bin/nano` directly in the crontab, is does not work?


Well, actually it does work but is in essence useless. What happens is that the EDITOR variable gets set, a shell is spawned (with the variable set) and this shell closes immediately. So for a short period the EDITOR variable was indeed changed but only for that short-lived sub-shell. This is probably not what you intended to do.


----------



## SirDice (Jan 7, 2019)

Sessa said:


> If I set the editor variable to nano and then reboot, the default editor is Vim again.


The default editor is vi(1), not vim(1). There is a difference (editors/vim has to be installed, vi(1) is part of the base OS).

You don't need to reboot for this. Just source(1) the right file. 
It's going to depend on that user's shell; ~/.cshrc is for csh(1)/tcsh(1), ~/.profile is for sh(1) and other Bourne compatible shells (i.e. bash, zsh).


----------



## Sessa (Jan 19, 2019)

SirDice said:


> It's going to depend on that user's shell;



I'm logged in as root user. So what have i to edit and how?


----------



## Phishfry (Jan 19, 2019)

You need to edit the file /.cshrc if using the stock shell. This will change the root user editor.
My preferred editor is `ee` or "easy editor". Very similar to nano.
So to change to nano you will need to use some other editor to make the change.
For instance:
`ee /.cshrc`
This brings up the FreeBSD editor and all you need to do is change the line that says EDITOR=vi to EDITOR=/usr/local/bin/nano
Once editing is complete hit ESC key and save and exit.

If you want to change a users shell editor the command would be like this:
`ee /home/username/.cshrc`

I really think you need to drop the Linuxisms and adopt `ee` right now. It is so simple a kid could use it.
On a new install I change mine from `vi` to `ee` with EDITOR=ee
No weird shortcut keys needed. All commands are shown on screen. The ESC key brings up the menu.
It is very similar to nano but is in our base system. Learn it and set yourself free.


----------



## ralphbsz (Jan 19, 2019)

Sessa said:


> I'm logged in as root user.


Explain: Why are you trying to do a system-wide change while logged in as root?

The correct way to do this: log in as a normal user, and do the change for that user.  In a nutshell, the only thing root should ever do is to administer the system to keep running.  Some people even say that root should never log in at all, instead normal users should execute system administration commands one at a time with sudo.

Another thing: be very careful changing files like .cshrc for the root user.  If you screw up, and root can't log in, or can't work effectively, you have a system that is very difficult to repair (probably have to use the console and do the single-user boot thing, which is hard).  I would leave the root user alone.

I don't care which editor you use.  If you like vim instead of vi, use it.  I happen to like emacs, and use it as the default editor.  To each their own.

(Having said that, I don't actually follow my advice above: Not only do I log into an account that has ID 0, I even change the login shell of that account to be bash instead of tcsh.  However, that account is not root, and ssh logins to those accounts is disabled.)


----------



## Sessa (Jan 21, 2019)

Phishfry said:


> You need to edit the file /.cshrc if using the stock shell. This will change the root user editor.



Unfortunately, after i rebooted the system, the changes are lost.

EDIT
Not lost but the editor is not nano.


----------



## olli@ (Jan 21, 2019)

The file /.cshrc is only used in single-user mode (when “/” is the home directory). During normal operation, when you log in as the root user (which is strongly discouraged!), /root is the home directory, so you should make that change to /root/.cshrc. However, it is better not to log in as root. You can, for example, use `su -m` to change to root privileges while logged in as normal user. In that case, your normal user environment stays the same, including the setting of `EDITOR` that you have as normal user.

Please note that Phishfry made a small mistake in his advice above. csh(1) has a different syntax for setting environment variables than most other shells. So, instead of writing `EDITOR=/usr/local/bin/nano` (sh syntax) you need to write `setenv EDITOR /usr/local/bin/nano` (csh syntax).

Another point to keep in mind: For historical reasons, there are two different environment variables to specify the editor: `EDITOR` and `VISUAL`. The first is intended to be used for line editors such as ed(1) and ex(1), and the latter for full-screen editors such as vi(1) and ee(1). Applications don't use these variables consistently, so it's better to always set _both_ to the same value. So in your case, you need these lines for csh:
`setenv EDITOR /usr/local/bin/nano`
`setenv VISUAL /usr/local/bin/nano`


----------



## SirDice (Jan 21, 2019)

Normally /.cshrc and /root/.cshrc are hard-linked and thus should be exactly the same.


```
dice@armitage:~ % ls -li /.cshrc /root/.cshrc
130082 -rw-r--r--  2 root  wheel  1259 Mar 12  2014 /.cshrc
130082 -rw-r--r--  2 root  wheel  1259 Mar 12  2014 /root/.cshrc
```


----------



## olli@ (Jan 21, 2019)

SirDice said:


> Normally /.cshrc and /root/.cshrc are hard-linked and thus should be exactly the same.


Right. I tend to forget what the default is, because I always answer no when mergemaster(8) asks if those files should be hardlinks. I thought it was confusing if they're hardlinks.


----------



## Sessa (Jan 28, 2019)

I have set the env in the .cshrc file to "nano". When i reboot the system and type in "crontab -e" the crontab will be open by "vi".
What have i made wrong?


----------



## SirDice (Jan 28, 2019)

In your shell, what does `echo $SHELL $EDITOR` output?


----------



## Sessa (Jan 28, 2019)

`EDITOR: Undefined Variable`

So i set the editor var again with `setenv EDITOR /usr/locale/bin/nano` and checked again. Now the output is:

`/bin/sh /usr/locale/bin/nano`

After a reboot the output is again:

`EDITOR: Undefined Variable`


----------



## SirDice (Jan 28, 2019)

Sessa said:


> Now the output is:
> 
> `/bin/sh /usr/locale/bin/nano`


Your shell is sh(1), the ~/.cshrc file is only for tcsh(1)/csh(1).


----------



## Sessa (Jan 28, 2019)

I have changed the `/root/.cshrc` and the `/.cshrc` file. The env variable is still not set after a reboot.


----------



## SirDice (Jan 28, 2019)

Again, .cshrc is only for csh(1) or tcsh(1). It has NO effect on sh(1).


----------



## Vull (Jan 29, 2019)

Login with the user name of the user who is executing `crontab -e` and put the following two lines at the end of the file .shrc and also at the end of the file .profile ... 
	
	



```
export EDITOR=/usr/local/bin/nano
export VISUAL=/usr/local/bin/nano
```
Use the nano editor to make your changes by using these commands:
	
	



```
nano .shrc
nano .profile
```
Then enter the `exit` command at the command prompt to log out, because the changes won't take effect until you login again. Then login again as the same user name and execute the command `crontab -e` ... and you should find yourself using nano instead of vi or any other editor.


----------



## SirDice (Jan 29, 2019)

Vull said:


> Then enter the  exit command at the command prompt to log out, because the changes won't take effect until you login again.


No need to logoff. You can simply do `source ~/.shrc` or `source ~/.profile`. You can use the same command for the C shells too; `source ~/.cshrc`.


----------

