How to pass variable to command executed by run-one?

Asked by toobuntu

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 run-one 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

Any ideas?

Question information

Language:
English Edit question
Status:
Solved
For:
Ubuntu run-one Edit question
Assignee:
No assignee Edit question
Solved by:
toobuntu
Solved:
Last query:
Last reply:
Revision history for this message
Thomas Krüger (thkrueger) said :
#1

Why don't you just put them in rsync-daily.sh?

export DEBUG=n
export TEST=n

Revision history for this message
Manfred Hampl (m-hampl) said :
#2

the other way round
DEBUG=n;TEST=n;/usr/bin/run-one /usr/local/bin/rsync-daily.sh
might work

or use
export DEBUG=n
export TEST=n
/usr/bin/run-one /usr/local/bin/rsync-daily.sh
as aready written by thkrueger

Revision history for this message
toobuntu (toobuntu) said :
#3

I now realize that I should have made it clear in my question that I have a cronjob which, for convenience and safety, requires two variables to be passed to it in production.

@thkrueger and @m-hampl: I appreciate your desire to help but neither of you actually answered the question as posed.

@thkrueger, I cannot declare the variables in the script. See above.

@m-hampl, your first idea is the same as that shown at the end of my question and there is no need to export the variables for use outside of the script.

I dug around the run-one code, which is quite short, and discovered that what I set out to do is not possible the way run-one calls flock, unless the cronjob 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. I created a patch and filed a bug report (which is linked to this question).

The below patch 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-05 15:27:46.635948096 -0500
@@ -32,14 +32,15 @@
 mkdir -p "$DIR"

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

 # Handle run-this-one invocation, by killing matching process first
 case "$(basename $0)" in
  run-one)
- # Run the specified commands, assuming we can flock this command string's hash
- flock -xn "$FLAG" "$@"
+ # Run the specified command, assuming we can flock this command string's hash
+ flock -xn "$FLAG" -c "$CMD"
  ;;
  run-this-one)
   ps="$@"
@@ -58,15 +59,15 @@
   pid=$(lsof "$FLAG" | awk '{print $2}' | grep "^[0-9]") || true
   [ -z "$pid" ] || kill $pid
   sleep 0.1
- # Run the specified commands, assuming we can flock this command string's hash
- flock -xn "$FLAG" "$@"
+ # Run the specified command, assuming we can flock this command string's hash
+ 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
+ # Run the specified command, 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