56

A command like mv foo* ~/bar/ produces this message in stderr if there are no files matching foo*.

mv: cannot stat `foo*': No such file or directory

However, in the script I'm working on that case would be completely fine, and I'd like to omit that message from our logs.

Is there any nice way to tell mv to be quiet even if nothing was moved?

  • 12
    mv foo* ~/bar/ 2> /dev/null ? – Thomas Nyman Aug 21 '13 at 11:14
  • 1
    Well yeah. I guess I had something "nicer" in mind, like some switch for mv. :) But that will do, of course. – Jonik Aug 21 '13 at 11:34
  • 3
    I've seen some mv implementations support a -q option to quiet them down, but that is not part of the POSIX specification for mv. The mv in GNU coreutils, for instance, does not have such an option. – Thomas Nyman Aug 21 '13 at 11:53
  • Well, I dont think the problem is how to keep "mv" be quiet, but how to do it more properly. Checking if there is any file/dir foo*, and user has writable permission, finally execute "mv", perhaps? – Shâu Shắc Aug 22 '13 at 7:00

10 Answers 10

43

Are you looking for this?

$ mv  file dir/
mv: cannot stat ‘file’: No such file or directory
$ mv  file dir/ 2>/dev/null
# <---- Silent ----->
  • 15
    note, return value still != 0, therefore any set -e (which should be used in every shell script) will fail. you can add a || true to deactivate the check for a single command. – reto Aug 21 '13 at 16:28
  • 6
    @reto set -e should not be used in every shell script, in many cases it makes error management even more complex than it is without. – Chris Down Nov 4 '13 at 9:12
  • 1
    @ChrisDown I see your point. It is usually a choice between two evils. But if in doubt, I prefer a failed successful run, than a successful failure. (which doesn't get noticed until it's getting visible to a customer/user). Shell scripts are a big mine field for beginners, it's so easy to miss a an error and your script goes haywire! – reto Nov 4 '13 at 10:25
12

Actually, I don't think muting mv is a good approach (remember it might report you also on other things which might be of interest ... eg. missing ~/bar). You want to mute it only in case your glob expression doesn't return results. In fact rather not execute it at all.

[ -n "$(shopt -s nullglob; echo foo*)" ] && mv foo* ~/bar/

Doesn't look very appealing, and works only in bash.

OR

[ 'foo*' = "$(echo foo*)" ] || mv foo* ~/bar/

only except you are in bash with nullglob set. You pay a price of 3x repetition of glob pattern though.

11

find . -maxdepth 1 -name 'foo*' -type f -print0 | xargs -0r mv -t ~/bar/

— GNU's mv has nice "destination first" option (-t) and xargs can skip running its command if there's no input at all (-r). Using of -print0 and -0 correspondingly makes sure there wouldn't be a mess when filenames contain spaces and other "funny" stuff.

5

It's probably not the best but you can use find command to check if the folder is empty or not:

find "foo*" -type f -exec mv {} ~/bar/ \;
3

You can do for example

mv 1>/dev/null 2>&1 foo* ~/bar/ or mv foo* ~/bar/ 1&>2

For more details see: http://mywiki.wooledge.org/BashFAQ/055?highlight=%28which%29

  • mv foo* ~/bar/ 1&>2 does not silence the command, it sends what would have been on stdout to also be on stderr. – Chris Down Aug 21 '13 at 12:15
  • @ChrisDown you are right, however this be noticed if you ran cp -rv foo* ~/bar/ Since mv in it's own is silent it won't matter at all. But then yes the second command is somehow not useful. Edit errors please :> – Valentin Bajrami Aug 21 '13 at 12:18
  • and if you're using mingw under windows (like me) replace /dev/null with NUL – Rian Sanderson Mar 10 '16 at 18:46
  • How does this command work? What do the ampersands do? What do 1 and 2 mean? – Aaron Franke Dec 15 '16 at 20:20
3

I'm assuming that you are using bash, because this error depends on bash's behavior to expand unmatched globs to themselves. (By comparison, zsh raises an error when trying to expand an unmatched glob.)

So, what about the following workaround?

ls foo* >/dev/null 2>&1 && mv foo* ~/bar/

This will silently ignore the mv if ls foo* fails, while still logging errors if ls foo* succeeds but the mv fails. (Beware, ls foo* could fail for other reasons than foo* not existing, e.g., insufficient rights, problem with the FS, etc., so such conditions would be silently ignored by this solution.)

  • I'm mostly interested in bash, yeah (and I did tag the question as bash). +1 for taking into account the fact that mv might fail for other reasons than foo* not existing. – Jonik Aug 22 '13 at 12:27
  • 1
    (In practice I probably won't be using this since it's kind of verbose, and the point of the ls command wouldn't be very clear for future readers, at least without a comment.) – Jonik Aug 22 '13 at 12:28
3

Instead

mv foo* ~/bar/

you can do

cp foo* ~/bar/
rm foo* 

Simple, readable, vote me :)

  • 2
    Copying, then removing, takes longer than a simple move. It also will not work if a file is larger than the available free disc space. – Anthon Apr 14 '14 at 7:14
  • 5
    The OP wants a solution that is silent. Neither cp nor rm are silent if foo* does not exist. – ron rothman Oct 3 '14 at 13:10
2

You can cheat (portably) with perl:

perl -e 'system "mv foo* ~/bar/" if glob "foo*"'
  • Please comment before downvoting. – Joseph R. Aug 21 '13 at 18:40
2

If you're going to use Perl, you might as well go all the way:

#!/usr/bin/perl
use strict;
use warnings;
use File::Copy;

my $target = "$ENV{HOME}/bar/";

foreach my $file (<foo*>) {
    move $file, $target  or warn "Error moving $file to $target: $!\n";
}

or as a one-liner:

perl -MFile::Copy -E 'move $_, "$ENV{HOME}/bar/" or warn "$_: $!\n" for <foo*>'

(For details of the move command, see the documentation for File::Copy.)

0

Probably not the most accurate, but it works still and can be used for many other things.

ls | egrep "^foo*" | xargs -I {} mv {} ~/bar

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.