Qual é o ponto de mv -f?

34

O manual do GNU Coreutils paramv diz:

-f --force Do not prompt the user before removing a destination file.

No entanto, esse já parece ser o comportamento padrão para mv, portanto, a -fopção parece ser supérflua. Por exemplo, no GNU Bash versão 4.3.11:

$ ls -l
total 0
$ touch 1 2; mv -f 1 2; ls
2
$ touch 1 2; mv 1 2; ls
2

Parece improvável que a intenção do -fsinalizador seja substituir alias mv="mv -i", porque existem várias maneiras padrão de substituir um apelido (por exemplo, usar \mv) que faria isso de forma mais concisa e consistente de todos os comandos.

O manual observa que, "Se você especificar mais de uma das opções -i, -f, -n, somente a final entrará em vigor", mas ainda parece improvável que a intenção da -fbandeira seja substituí-la -iem geral, porque um comportamento equivalente pode ser alcançado simplesmente usando mv, o que é muito mais conciso e compreensível do que usar mv -if.

Sendo esse o caso, qual é o objetivo da -fbandeira? Por que isso existe?

sampablokuper
fonte
6
Os padrões são um negócio meticuloso. Pegue uma ferramenta como mount, por exemplo (embora haja exemplos melhores). Deseja realmente lembrar quais são os padrões de todas as opções, para poder determinar quais opções precisam ser definidas? É uma BOA COISA ter opções tanto para o padrão quanto para o não padrão, para que você possa definir explicitamente a opção em vez de precisar acompanhar mentalmente qual é o padrão. Algo que é mais fácil de lembrar do que algo que não existe .
Curinga
Comportamento equivalente não pode ser usado se MV é alised a MV-i
PlasmaHH
11
IMO, também é bom para uso em scripts, porque você está sendo explícito. Comunica a intenção um pouco melhor.
Blacklight Shining

Respostas:

41

O uso de -fé descrito com mais clareza na página de manual do 4BSD, onde foram adicionadas as opções -fe -i:

Se o arquivo2 já existir, ele será removido antes que o arquivo1 seja movido. Se o arquivo2 tiver um modo que proíba a gravação, mv imprime o modo e lê a entrada padrão para obter uma linha; se a linha começa com y, o movimento ocorre; caso contrário, o mv sai.

Opções:

-isignifica modo interativo. Sempre que uma movimentação é para substituir um arquivo existente, o usuário é solicitado pelo nome do arquivo seguido por um ponto de interrogação. Se ele responder com uma linha que começa com 'y', a mudança continua. Qualquer outra resposta impede que a movimentação ocorra.

-fsignifica força. Esta opção substitui quaisquer restrições de modo ou o -icomutador.

Uma definição ainda mais precisa de como o mv opera é fornecida no padrão POSIX , que acrescenta que -fsomente substitui -ise ocorrer posteriormente na linha de comando.

Portanto, o comportamento padrão é um pouco diferente de -f. O padrão é solicitar confirmação apenas quando o destino não for gravável. (Esse comportamento remonta pelo menos até a V4 , onde mvnão havia opções.) Se a -iopção for dada, o mv solicitará adicionalmente a confirmação sempre que o destino existir. A -fopção inibirá a pergunta em ambos os casos (se ocorrer depois de algum -i).

Mark Plotnick
fonte
Ótima resposta, obrigado! NB Alguns sistemas de arquivos (por exemplo, CIFS) podem fazer com que o mv apresente comportamento inesperado (diferente do manual), como agir como se o -fsinalizador tivesse sido usado, mesmo que não tivesse sido usado .
sampablokuper
Vale a pena notar que muitas implementações só pedem confirmação se parecem estar em um terminal interativo ( isatty(0)). Além disso, embora seja verdade que uma -fsubstituição posterior -i, pode não significar que isso é o mesmo que nenhum argumento fornecido.
Php 18/03
15

É útil ao definir a execução de mvum padrão sadio:

alias mv="mv -i"

Quando você quiser forçar uma mudança, isso funcionará:

mv -f

Como é a última opção no comando expandido que conta:

mv -i -f

Este ponto também é mencionado no manual GNU Coreutils .

Alexander
fonte
11
Obrigado, mas pelas razões que adicionei à pergunta, parece improvável que a substituição alias mv="mv -i"seja a razão da existência de -f.
sampablokuper
12
Oponho-me a chamar o padrão "fazer o que é pedido, nenhuma pergunta muda" comportamento mv(1)(e outros comandos Unix) "louco" como você implica ...
vonbrand
11
vonbrand, embora aprecie a resposta direta dos comandos Linux / UNIX sem -i, acredito que qualquer pessoa que tenha usado a linha de comando por mais de alguns anos tenha sido queimada por mv, em um ponto ou outro.
1140 Alexander Alexander
11
Você pode pensar que substituir -i é improvável, mas é exatamente por isso que eu acho que -f é usado assim.
219 Walter Walter
11

Existe porque ( man mv)

Se você especificar mais de um -i, -f, -n, apenas o último tem efeito.

Portanto, você pode ter um script / alias / função que sempre pergunta, mas ainda pode substituir a opção.

# alias
alias mv='mv -i'

# function
MV () { mv -i "$@" ; }

# script
#!/bin/bash
mv -i "$@"

Uma função / script significativo faria algo mais, é claro (por exemplo, registre a ação).

choroba
fonte
@choroba Obrigado, mas por razões que adicionei à pergunta, parece improvável que sobrescreva aliases como alias mv="mv -i"o motivo da existência de -f. Você menciona scripts e funções também. Por favor, você poderia dar exemplos usando esses dois?
sampablokuper
@sampablokuper: atualizado.
choroba
@choroba, obrigado novamente. Infelizmente, nem seu exemplo de função nem seu exemplo de script usam mv -f, portanto ainda não está claro para mim como eles justificam / explicam sua existência. Desculpe se estou perdendo o óbvio!
sampablokuper
@sampablokuper: Todos eles usam mv -i. Se você quiser usá-los, mas pular a interação, você usaria MV -fetc. #
choroba
11
@sampablokuper O comportamento de mvsem nenhuma dessas opções é às vezes perguntar (destino, terminal não gravável e interativo); portanto, essa seria uma clara diferença entre mv -fe \mv.
Php 18/03
5

O mvcomando por si só pode funcionar de maneira diferente com a -fopção, na medida em que tentará sobrescrever arquivos protegidos contra gravação sem aviso.

user2@host:location> ls -l ./
drwxrwxr-x 2 user1 users    10   Oct 16 12:58 dir
user2@host:location> ls -l ./dir/
-rw-r--r-- 2 user1 users     0   Oct 16 12:58 file1
-rw-r--r-- 2 user2 users     0   Oct 16 12:58 file2
user2@host:location> \mv ./dir/file2 ./dir/file1
'mv' try to overwrite './dir/file1', overridding mode 0644 (rw-r--r--)? n
user2@host:location> \mv -f ./dir/file2 ./dir/file1
user2@host:location> ls -l ./dir/
-rw-r--r-- 2 user2 users     0   Oct 16 12:58 file1

Por causa das permissões de gravação no diretório, o usuário2 pode substituir os arquivos do usuário1 ./dir/, mas será avisado antes de fazê-lo. -fimpede o aviso.

Centimane
fonte
-1

Na programação de shell, o uso de -f é um idioma comum usado para garantir que seus comandos não abortem com erros ou peça ao script / usuário uma resposta interativa ao executar determinados comandos. A última coisa que você deseja é que seu script pause aguardando a entrada do usuário, ou talvez pior, que o comando errado leve a entrada do padrão.

Nota: desfazer um alias pode causar / remover efeitos colaterais. Se você aliasou o comando para outra versão ou com opções adicionais, desfazer o alias causará efeitos colaterais indesejados. Por exemplo, você pode ter um alias configurado com mv e rm para usar uma lata de reciclagem (ou outros sistemas de proteção / rastreamento). Desfazer o alias quebrará isso ...

Walter
fonte
Nitpick: A -fopção para cp ou mv não garante que "eles funcionem". Por exemplo, se a permissão for insuficiente, o comando -f não fará com que funcione. O que você quis dizer com isso é que -f força uma substituição sem aviso prévio. O sinalizador oposto -i significa exigir interativo na substituição.
Eric Leschinski 27/10
Duas coisas a serem observadas: 1.) As implementações normalmente testariam se você está em um terminal interativo ( isatty(0)), por exemplo, se seu script for executado como parte de um canal, ele não será acionado. 2.) Adicionar -fnão é o mesmo que desfazer, -iporque mv -i -fdifere de mv, veja a resposta de Marcos .
Php 18/03