The code for my website uses this piece of code for automatic deployment on the server (Ubuntu).
cmd = 'cd ' + checkout_dir + ' && ' + svn_command + " st | awk '{print $2}' | grep -v ^deploy | tac | xargs -r" + svn_command + " revert -R && " + svn_command + ' up -r ' + options.revision
What this command does is it cd
into checkout directory, runs svn status
, and then extracts the filename ($2
), removes the deploy
directory and all its files from the list (I don't want to revert it). If there are no argument it does not run the svn revert command, else it does.
Unfortunately the xargs -r
does not work on my machine (Mac OS X 10.8). So I am stuck here, can anyone help?
The
-r
forxargs
isn't working on OS X, since it's a GNU extension. As for workaround, you should specify some dummy file which can be parsed byxargs
or to not call command when there are no arguments (which can be checked before).Method using temporary file (or any other placeholder):
Using condition in shell:
See also: Ignore empty result for xargs
Indeed, the BSD implementation of
xargs
doesn't have the-r
flag (--no-run-if-empty
). The GNU version in Linux has it.Here's one way to work around the issue in a way that works in both Linux and BSD:
The
grep ... || echo :
in the middle will generate a line with a:
in it in case the output ofgrep
is empty. It's a bit dirty, becausexargs
will still run the commandsvn revert :
. If your repository doesn't contain the file:
then this should have no effect, so it can be acceptable. The:
could be anything else, as long as there is no such file in your repository.Finally, as @tripleee pointed out, the
grep ... || echo :
must be enclosed within(...)
, because:Your code looks like a Python string. It will be more readable this way:
I made some changes to your original:
grep
insideawk
, as @tripleee suggested. Notice that since thegrep
hack is not needed anymore, there is also no more need to wrap within(...)
tac
, as I don't see the point in it-R
fromsvn revert
, because I don't think you need itNot pretty, but hopefully a workaround.
I'm not convinced that the
tac
is necessary or useful. I refactored the firstgrep
into the Awk script for efficiency and aesthetic reasons.To solve the general "my
xargs
lacks-r
" problem, the gist of the solution is to convertinto
The unquoted
$var
will only work if it doesn't contain file names with spaces or other surprises; but then bare-bonesxargs
without the GNU extensions suffers from the same problem.Bash reimplementation of
xargs
dealing with the-r
argument: