Questions regarding crontab and bash command

Hi,

1. My first question is regarding crontabs. I added a command to be run every minute in the file /var/cron/tabs/root but it does not execute, is there any other file I need to change as well to make the changes take effect? The syntax of what I added is like this:
* * * * * (bash -c '....')

The same line added on Linux/Ubuntu works(to the equivalent file /var/spool/cron/crontabs/root there).

2. My second question is that I'm trying to run a bash oneliner like this: curl -sk "https://domain.com/test.txt" | bash <(curl -sk "http://domain/script.sh") /usr/sbin/syslog
But I get this error: Missing name for redirect.
The same command on Linux/Ubuntu works perfect, so I'm not sure what to modify to get this oneliner to work on FreeBSD. I tried escaping the < but it didn't help.

I appreciate all help I can get.
 
Add the full path to bash executable in the crontab entry.
I added /bin/bash, but still it's not run every minute. At the end of a minute, I check "ps aux" every second but it doesn't seem to run.

I tried with having this in that file: * * * * * (bash -c 'echo test > /root/test.txt')
But it doesn't write that file so for some reason, the cronjob is still not running.
 
I added /bin/bash

That's the wrong path on FreeBSD.

You need to understand what the environment (and in particular the path) is for jobs started by cron. Read the man page, it's explained somewhere in there.

Also, make sure you have cron configured such that you get e-mails for failures. Otherwise, you're debugging in the blind.
 
That's the wrong path on FreeBSD.

You need to understand what the environment (and in particular the path) is for jobs started by cron. Read the man page, it's explained somewhere in there.

Also, make sure you have cron configured such that you get e-mails for failures. Otherwise, you're debugging in the blind.
This is the path to bash on my FreeBSD

1677881756947.png
 
The same command on Linux/Ubuntu works perfect, so I'm not sure what to modify to get this oneliner to work on FreeBSD. I tried escaping the < but it didn't help.
Bash isn't the standard shell on FreeBSD, it isn't even included in the base system. If you need bash, you have to install the port/package, and, like all ports/packages, it will be installed below "localbase" which defaults to /usr/local and is almost never changed.

This form of redirection is almost certainly special bash syntax, so will only work if you start it from within bash.

If ever possible, avoid "bashisms" and use plain POSIX/bourne shell syntax, then it will work on any (POSIX-compliant) system.
 
If you're using ports or packages, you won't get this. If you're using the source you won't get this without explicit defining another path. So…: You changed the system in some special way, you don't have a usual installation; To get your question answered those changes should be part of your question ;)
Note that /bin/bash is Linux only. Bash defaults officially to /usr/local/bin/bash, and FreeBSD takes that over.

…what does "file /bin/bash" say?
 
You have installed a rogue version of bash(1). That's a bad idea, unless you know exactly what you are doing. See, for instance, shells(5).

Abandon the use of cron(8), and get the thing working on the command line.

Then make sure it works when you are using /bin/sh as your shell (because that's what cron uses).

Finally, when that's working, address any issues if a crontab(5) entry does not work.

Make sure that the PATH used by cron(8) is the same as you use on the command line (read crontab(5)).
 
I added a command to be run every minute in the file /var/cron/tabs/root but it does not execute, is there any other file I need to change as well to make the changes take effect?
You should not edit /var/cron/tabs/username files directly.
Use crontab() tool instead. It will manage personal crons or edit it using default editor.
crontab -e to edit user's crontab, root has its own user's crontab too.
If you edited /var/cron/tabs/username directly - try to restart cron() daemon service cron restart.
Also check /var/log/cron if you have any issues related to cron.
 
* * * * * (bash -c '....')
Drop the parentheses. For example: * * * * * bash -c "date >> /tmp/junk"
2. My second question is that I'm trying to run a bash oneliner like this: curl -sk "https://domain.com/test.txt" | bash <(curl -sk "http://domain/script.sh") /usr/sbin/syslog
But I get this error: Missing name for redirect.
The same command on Linux/Ubuntu works perfect, so I'm not sure what to modify to get this oneliner to work on FreeBSD. I tried escaping the < but it didn't help.
Don't blindly copy such scripts from Linux. Understand what this is supposed to do and reimplement it.
 
Bash isn't the standard shell on FreeBSD, it isn't even included in the base system. If you need bash, you have to install the port/package, and, like all ports/packages, it will be installed below "localbase" which defaults to /usr/local and is almost never changed.

This form of redirection is almost certainly special bash syntax, so will only work if you start it from within bash.

If ever possible, avoid "bashisms" and use plain POSIX/bourne shell syntax, then it will work on any (POSIX-compliant) system.

I see, so I should convert my command to tcsh command for example?

If you're using ports or packages, you won't get this. If you're using the source you won't get this without explicit defining another path. So…: You changed the system in some special way, you don't have a usual installation; To get your question answered those changes should be part of your question ;)
Note that /bin/bash is Linux only. Bash defaults officially to /usr/local/bin/bash, and FreeBSD takes that over.

…what does "file /bin/bash" say?
file /bin/bash
/bin/bash: symbolic link to /usr/local/bin/bash

file /usr/local/bin/bash
/usr/local/bin/bash: ELF 64-bit LSB executable, x86-64, version 1 (FreeBSD), dynamically linked, interpreter /libexec/ld-elf.so.1, for FreeBSD 12.3, FreeBSD-style, stripped

You have installed a rogue version of bash(1). That's a bad idea, unless you know exactly what you are doing. See, for instance, shells(5).

Abandon the use of cron(8), and get the thing working on the command line.

Then make sure it works when you are using /bin/sh as your shell (because that's what cron uses).

Finally, when that's working, address any issues if a crontab(5) entry does not work.

Make sure that the PATH used by cron(8) is the same as you use on the command line (read crontab(5)).
Okay I will look into converting my command to /bin/sh. But for some reason, I'm still getting a lot of "Ambiguous output redirect.". I get this error directly when I use 2&1 for example. If I do: /bin/sh -i 2>&1 , it gives that error but if I do /bin/sh -i , it doesn't give it. Do you know how I can pipe errors like that on FreeBSD?
You should not edit /var/cron/tabs/username files directly.
Use crontab() tool instead. It will manage personal crons or edit it using default editor.
crontab -e to edit user's crontab, root has its own user's crontab too.
If you edited /var/cron/tabs/username directly - try to restart cron() daemon service cron restart.
Also check /var/log/cron if you have any issues related to cron.
Okay thank you, will remember to try to restart it and check cron logs.
Drop the parentheses. For example: * * * * * bash -c "date >> /tmp/junk"

Don't blindly copy such scripts from Linux. Understand what this is supposed to do and reimplement it.
In this case, I want the paranthesis because after the paranthesis I have: >/dev/null 2>&1 &
To pipe errors accordlingly and run in background.
 
I see, so I should convert my command to tcsh command for example?
No, that's arguably even worse. Bash is a POSIX/bourne shell with custom extensions, Tcsh is a C shell that's incompatible with POSIX/bourne.

C shells are traditionally part of BSD systems, but using them for scripting is NOT recommended. Some like to use them interactively, which is mostly a matter of taste.

What you should use for scripting is the system's bourne shell. On FreeBSD (and, on most other POSIX-compliant systems), this is /bin/sh.
 
The original command you posted was:curl -sk "https://domain.com/test.txt" | bash <(curl -sk "http://domain/script.sh") /usr/sbin/syslog. This uses "Process Substitution" with the second curl which is not generally available in Bourne shells.

You don't have to abandon bash to get done what you want. You just have to use /bin/sh as your basic interpreter (as does cron).

So, start on the command line by invoking /bin/sh and setting your PATH so it will find curl and bash:
Code:
/bin/sh
PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/sbin:/usr/sbin
export PATH
You can then move on to test your bash code:
Code:
bash -c 'curl -sk "https://domain.com/test.txt" | bash <(curl -sk "http://domain/script.sh") /usr/sbin/syslog'
Beware /usr/sbin/syslog does not exist on FreeBSD systems. Presumably, it's an argument to script.sh. But you have to figure out the context, and what needs to be done on FreeBSD to get an equivalent outcome.

Once you have it all tested and working, you can add it to your crontab. Don't forget to set the PATH in your crontab(5) file.
 
BTW, if you write a script that you then call from crontab the correct way to get bash on different OSes is:
Code:
#! /usr/bin/env bash

foo bar baz
 
Back
Top