Existe uma maneira de fazer com que “mv” falhe silenciosamente?

54

Um comando como mv foo* ~/bar/ produz esta mensagem em stderr se não houver arquivos correspondentes a foo* .

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

No entanto, no script em que estou trabalhando, o caso estaria completamente correto e gostaria de omitir essa mensagem dos nossos registros.

Existe alguma maneira legal de dizer mv para ficar quieto, mesmo que nada tenha sido movido?

    
por Jonik 21.08.2013 / 13:10

9 respostas

39

Você está procurando por isso?

$ mv  file dir/
mv: cannot stat ‘file’: No such file or directory
$ mv  file dir/ 2>/dev/null
# <---- Silent ----->
    
por 21.08.2013 / 13:31
12

Na verdade, eu não acho que omitir mv seja uma boa abordagem (lembre-se que ele pode relatar você também sobre outras coisas que podem ser de interesse ... por exemplo, falta de ~/bar ). Você deseja silenciá-lo apenas no caso de sua expressão glob não retornar resultados. Na verdade, não executá-lo de todo.

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

Não parece muito atraente e funciona apenas em bash .

OR

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

apenas, exceto que você está em bash com nullglob set. Você paga um preço de 3x repetição do padrão glob.

    
por 21.08.2013 / 14:05
9

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

- O mv do GNU tem a opção "primeiro destino" ( -t ) e xargs podem ignorar a execução do comando se não houver nenhuma entrada ( -r ). O uso de -print0 e -0 garante que não haverá confusão quando nomes de arquivos contiverem espaços e outras coisas "engraçadas".

    
por 21.08.2013 / 18:53
5

Provavelmente não é o melhor, mas você pode usar o comando find para verificar se a pasta está vazia ou não:

find "foo*" -type f -exec mv {} ~/bar/ \;
    
por 26.01.2016 / 11:47
3

Você pode fazer por exemplo

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

Para mais detalhes, consulte: link

    
por 21.08.2013 / 13:16
2

Estou assumindo que você está usando o bash, porque esse erro depende do comportamento do bash para expandir globs não correspondentes para si mesmos. (Por comparação, o zsh gera um erro ao tentar expandir um glob sem igual.)

Então, e a seguinte solução alternativa?

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

Isso silenciosamente ignorará o mv se ls foo* falhar, enquanto ainda estiver registrando erros se ls foo* tiver êxito, mas o mv falhar. (Cuidado, ls foo* poderia falhar por outras razões que nãofoo* não existentes, por exemplo, direitos insuficientes, problema com o FS, etc., então tais condições seriam silenciosamente ignoradas por esta solução).

    
por 21.08.2013 / 14:22
2

Você pode trapacear (portavelmente) com perl :

perl -e 'system "mv foo* ~/bar/" if glob "foo*"'
    
por 21.08.2013 / 14:18
2

Em vez disso

mv foo* ~/bar/

você pode fazer

cp foo* ~/bar/
rm foo* 

Simples, legível, vote em mim:)

    
por 14.04.2014 / 08:49
1

Se você vai usar o Perl, você pode ir até o fim:

#!/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";
}

ou como um verso:

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

(Para detalhes do comando move , veja a documentação para File :: Copy .)

    
por 21.08.2013 / 15:45

Tags