0

The idea of using crontab to schedule netcat commands on two machines was brought up in this question, but the respondents all rebuked the asker and pivoted to talking about scp instead.

Assuming I am ok with the implications, how would I go about finding what went wrong with this setup? For testing purposes, I was synchronizing these two jobs at 13:45 local. Both computers are on the same local time zone.

Destination crontab:

45 13 * * * nc -l -p 1234 > /path/to/backup-$(date +%F).tar.bz2

Source crontab:

45 13 * * * /path/to/backup_script.sh

Source backup script:

sleep 5  # to ensure the destination is already listening
tar -cvpj --exclude-vcs /path/to/source/files | nc -N dest 1234

On their own (outside of crontab), the listen command and backup script work. It's my understanding that the destination will not stop listening until it receives EOF. However, it's the listening end that seems to not be listening when it should be. I can start it listening manually and the source's scheduled job will send the file, but I'm unable to get the destination to listen at a specified time.

kjekk
  • 13

2 Answers2

0

crontab commands (man -a crontab) are NOT bash. Redirection, and command substitution are not available in crontab commands.

Wrap your desired command in a bash script, beginning with #!/bin/bash, and invoke the script from the crontab entry.

waltinator
  • 36,399
  • Huh? From man 5 crontab " The entire command portion of the line, up to a newline or % character, will be executed by /bin/sh or by the shell specified in the SHELL variable of the crontab file." so any valid /bin/sh constructs (including POSIX redirections and command substitution) are allowed – steeldriver Nov 26 '20 at 23:00
0

As documented in man 5 crontab, the % character is special in crontabs, and must be escaped

                                         Percent-signs (%) in the command,
   unless escaped with backslash (\), will be changed into newline charac‐
   ters,  and  all  data  after the first % will be sent to the command as
   standard input. There is no way to split a  single  command  line  onto
   multiple lines, like the shell's trailing "\".

so your command would need to be written as

45 13 * * * nc -l -p 1234 > /path/to/backup-$(date +\%F).tar.bz2

Otherwise, % is treated as an end-of-line character and the command passed to the shell gets truncated, like nc -l -p 1234 > /path/to/backup-$(date + which is obviously a syntax error.


Note: since the question is "how to debug", you could have diagnosed that by looking at the log entries for the cron service ex.

journalctl -xeu cron | grep CMD

where you would have noticed the truncated command.


Although crontab files are not in themselves shell scripts, the command portion of each crontab entry is passed to a shell. Again from man 5 crontab:

   The  entire  command  portion  of the line, up to a newline or %
   character, will be executed by /bin/sh or by the shell specified in the
   SHELL  variable of the crontab file.  

Because the default is /bin/sh, it will accept any POSIX shell features including redirections like < > >> as well as the $(...) command substitution construct. It will fail with bash-specific redirections like &> unless you change the SHELL appropriately. So while moving your command into a separate shell script will fix the failure, that's simply because it moves the % character outside the crontab.

steeldriver
  • 136,215
  • 21
  • 243
  • 336