7

I am using bash and flock on centos.

Normally I would run cd /to/my/dir && python3.6 runcommand.py

But then we add it to cron and don't want output so add > /dev/null 2>&1

And add a flock before it to prevent multiple instances, like so:

flock -n ~/.my.lock cd /to/my/dir && python3.6 runcommand.py > /dev/null 2>&1

Question Only does this flock the cd /to/my/dir and then execute the python3.6 (normally without flock) or does it flock the complete row of bash commands (so both) and only unlock when python3.6 runcommand.py is also finished?

Not clear from the man and examples I found.

codeforester
  • 39,467
  • 16
  • 112
  • 140
snh_nl
  • 2,877
  • 6
  • 32
  • 62
  • 1
    `&&` is a shell construct, so `flock` isn't aware of it. – codeforester Oct 27 '17 at 20:51
  • 2
    `flock` isn't even *given* your whole command by the shell -- it can't "understand" or "support" something it never even sees. All it gets is `flock -n ~/.my.lock cd /to/my/dir` (with the `~` already replaced with the actual directory name); nothing else is even visible to it. – Charles Duffy Oct 27 '17 at 21:00
  • 1
    (None of that is in any respect specific to `flock` -- if you were running, say, `echo cd /to/my/dir && python3.6 runcommand.py`, then `echo` too would only be given the single command before the `&&`). – Charles Duffy Oct 27 '17 at 21:05
  • (To be a bit more pedantically correct: What `flock` gets is an argument vector that looks like this: `char*[]{"flock", "-n", "/home/whatever/.my.lock", "cd", "/to/my/dir", NUL}` -- ie. it doesn't even get the original string, but an array of separate C strings that the shell creates when parsing the command line). – Charles Duffy Oct 27 '17 at 21:17
  • Suggestion: don't add logic to the crontab. Write a script with the logic and invoke the script. Crontabs should be absolutely trivial, IMO without even any redirections. But the redirections in the script. – William Pursell Oct 27 '17 at 21:22

2 Answers2

1

Shell interprets your command this way:

flock -n ~/.my.lock cd /to/my/dir && python3.6 runcommand.py > /dev/null 2>&1
  • Step 1: Run flock -n ~/.my.lock cd /to/my/dir part
  • Step 2: If the command in step 1 exits with non-zero, skip step 3
  • Step 3: Run python3.6 runcommand.py > /dev/null 2>&1 part

So, flock has no business with && or the right side of it.

You could do this instead:

touch ./.my.lock # no need for this step if the file is already there and there is a potential that some other process could lock it
(
  flock -e 10
  cd /to/my/dir && python3.6 runcommand.py > /dev/null 2>&1
) 10< ./.my.lock

See this post on Unix & Linux site:

codeforester
  • 39,467
  • 16
  • 112
  • 140
0

I had to do this in crontab. Here is my way -

*/30 * * * * cd /home/myfolder/ /usr/bin/flock -w 0 /home/myfolder/my-file.lock && python my_script.py > /dev/null 2>&1
Pankaj Tanwar
  • 850
  • 9
  • 11