Comment 0 for bug 1145461

Revision history for this message
toobuntu (toobuntu) wrote :

I have a cronjob which, for convenience and safety, requires two variables to be passed to it in production. This is not possible the way run-one calls flock, unless the script is called with sh -c, which presumably forks a new process and does not seem streamlined, or the variables are passed to run-one, too, which does not seem elegant.

The below diff fixes this behavior for me:

$ diff -Nru a/run-one b/run-one
--- a/run-one 2013-03-04 18:02:15.513983439 -0500
+++ b/run-one 2013-03-04 18:24:42.414039276 -0500
@@ -32,6 +32,7 @@
 mkdir -p "$DIR"

 # Calculate the hash of the command and arguments
+CMD="$@"
 CMDHASH=$(echo "$@" | md5sum | awk '{print $1}')
 FLAG="$DIR/$CMDHASH"

@@ -39,7 +40,7 @@
 case "$(basename $0)" in
  run-one)
   # Run the specified commands, assuming we can flock this command string's hash
- flock -xn "$FLAG" "$@"
+ flock -xn "$FLAG" -c "$CMD"
  ;;
  run-this-one)
   ps="$@"
@@ -59,14 +60,14 @@
   [ -z "$pid" ] || kill $pid
   sleep 0.1
   # Run the specified commands, assuming we can flock this command string's hash
- flock -xn "$FLAG" "$@"
+ flock -xn "$FLAG" -c "$CMD"
  ;;
  keep-one-running)
   backoff=1
   while true; do
    # Run the specified commands, assuming we can flock this command string's hash
    set +e
- flock -xn "$FLAG" "$@"
+ flock -xn "$FLAG" -c "$CMD"
    if [ "$?" = 0 ]; then
     # Last run finished successfully, reset to minimum back-off of 1 second
     backoff=1

------------------
This will do it, but I'm not sure if invoking /bin/sh launches a new process to do so, and want to keep system resource usage as minimal as possible:
$ /usr/bin/run-one /bin/sh -c 'DEBUG=n TEST=n /usr/local/bin/rsync-daily.sh'

The following fail because of the way run-one invokes flock and passing the command as "$@", flock tries to create a lock on the first parameter passed to /usr/bin/run-one:
$ /usr/bin/run-one DEBUG=n TEST=n /usr/local/bin/rsync-daily.sh
flock: DEBUG=n: No such file or directory
$ /usr/bin/run-one 'DEBUG=n TEST=n /usr/local/bin/rsync-daily.sh'
flock: DEBUG=n TEST=n /usr/local/bin/rsync-daily.sh: No such file or directory

The following fails because the variables do not get passed to the script:
$ /usr/bin/run-one /usr/local/bin/rsync-daily.sh DEBUG=n TEST=n
status: testing $DEBUG...
+ rsync_opts=-v --progress -ah --stats --delete --numeric-ids
+ printf DEBUG != n, debug mode activated\n
DEBUG != n, debug mode activated
+ printf status: testing $TEST...\n
status: testing $TEST...
+ test y = n
+ rsync_opts=-n -v --progress -ah --stats --delete --numeric-ids
+ printf TEST != n, test mode activated\n
TEST != n, test mode activated

I tried playing around with xargs with no luck. For elegance, I'd rather not pass the variables to run-one itself, though this does work:
$ DEBUG=n TEST=n /usr/bin/run-one /usr/local/bin/rsync-daily.sh
status: testing $DEBUG...
DEBUG = n
status: testing $TEST...
TEST = n