mv -f有什么意义?


34

用于GNU Coreutils的手册mv说:

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

但是,这似乎已经是的默认行为mv,因此该-f选项似乎是多余的。例如在GNU Bash版本4.3.11中:

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

-f标志的意图似乎不太可能是重写alias mv="mv -i",因为存在几种重写别名(例如使用\mv)的标准方法这些方法可以更简洁,且在命令之间保持一致。

手册指出:“如果您指定-i,-f,-n选项中的多个选项,则只有最后一个选项会生效。”但是,该-f标志的意图似乎-i一般是不能覆盖该标志,因为等同的行为可以通过简单地使用来实现mv,这比使用更加简洁和易懂mv -if

既然如此,-f标记的目的是什么?为什么存在?


6
违约是一项挑剔的事情。以诸如之类的工具mount为例(尽管有更好的示例)。您是否真的要记住每个选项的默认值,以便确定需要设置的选项?同时具有默认值和非默认值的选项是一件好事,因此您可以显式设置该选项,而不必费神地跟踪默认值。那里的东西比那里的东西更容易记住。
2015年

如果将MV应用于mv-i,则不能使用等效行为
PlasmaHH 2015年

1
IMO,它在脚本中也很好用,因为您很明确。它更好地传达了意图。
Blacklight Shining

Answers:


41

-f在4BSD 的手册页中更清楚地描述了的用法,该手册页中添加了-f-i选项:

如果file2已经存在,则在移动file1之前将其删除。如果file2具有禁止写入的模式,则mv打印该模式并读取标准输入以获得一行;如果该行以y开头,则发生移动;如果没有,则退出MV。

选项:

-i代表交互模式。每当要取代现有文件的步骤时,系统都会向用户提示文件名,后跟问号。如果他回答以'y'开头的行,则继续进行此操作。其他任何答复均会阻止此举。

-f代表力量。此选项将覆盖所有模式限制或-i开关。

POSIX标准对mv的运行方式给出了更为精确的定义,该标准增加了-f-i在以后命令行中出现时才覆盖的功能。

因此,默认行为与有所不同-f。默认设置是仅在目标不可写时才要求确认。(此行为至少可以追溯到V4,在V4mv没有任何选项。)如果-i给出了选项,则只要目标存在,mv就会另外要求确认。-f在这两种情况下,该选项都将禁止询问(如果之后发生-i)。


好答案,谢谢!注意:某些文件系统(例如CIFS)可能会导致mv出现意外行为(即与手册不同),例如,即使-f未使用该标志,也好像在使用该标志。
sampablokuper,2015年

值得注意的是,许多实现只要求确认是否似乎在交互式终端(isatty(0))中。同样,虽然以后确实-f覆盖了-i,但这并不意味着这与没有给出任何参数相同。
phk

15

将的执行设置mv为合理的默认值时非常有用:

alias mv="mv -i"

然后,当您想强制移动时,这将起作用:

mv -f

由于它是扩展命令中的最后一个选项,因此很重要:

mv -i -f

GNU Coreutils手册中也提到了这一点。


1
谢谢,但是由于我现在添加到问题alias mv="mv -i"中的原因,似乎不太可能是覆盖是存在的原因-f
sampablokuper,2015年

12
mv(1)
反对称

1
vonbrand,尽管我很欣赏没有使用Linux / UNIX命令的直接响应-i,但是我相信使用命令行超过几年的任何人都会mv在某种程度上被烧死。
亚历山大

1
您可能会认为覆盖-i不太可能,但这正是为什么我猜想-f如此使用的原因。
Walter

11

存在是因为(man mv

如果指定一个以上的-i-f-n,只有最后一个生效。

因此,您可以拥有一个始终询问的脚本/别名/功能,但仍可以覆盖该选项。

# alias
alias mv='mv -i'

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

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

有意义的功能/脚本当然会做更多的事情(例如记录操作)。


@choroba谢谢,但是由于我现在添加到问题alias mv="mv -i"中的原因,覆盖别名的可能性似乎不大,例如的存在的原因-f。不过,您还提到了脚本和函数。请问您能用这两个例子吗?
sampablokuper,2015年

@sampablokuper:已更新。
choroba

@choroba,再次感谢。遗憾的是,您的函数示例和脚本示例均未使用mv -f,因此我仍然不清楚它们如何证明/解释其存在。对不起,如果我错过了显而易见的事情!
sampablokuper,2015年

@sampablokuper:他们都使用mv -i。如果你想使用他们,但跳过互动,你会使用MV -f
choroba

1
@sampablokuper mv不带这些选项的情况有时是要询问(目标不可写和交互式终端),因此这mv -f和之间是明显的区别\mv
phk

5

mv命令本身可以与该-f选项一起发挥不同的功能,因为它将尝试覆盖写保护的文件而没有提示。

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

由于目录中的写许可权,user2可以覆盖中的user1文件./dir/,但在这样做之前会被警告。-f防止警告。


-1

在shell编程中,使用-f是一个常见用法,用于确保您的命令不会因错误而中止或在运行某些命令时要求脚本/用户提供交互式响应。您想要的最后一件事是让脚本暂停等待用户输入,或者更糟糕的是,错误的命令将标准输入带入了命令。

注意:撤消别名可能会导致/消除副作用。如果您已将命令别名为另一个版本或带有其他选项,则撤消别名将导致不必要的副作用。例如,您可能使用mv和rm设置了别名,以使用回收罐(或其他保护/跟踪系统)。撤消别名将破坏此...


Nitpick:-fcp或mv 的选项不保证“它们可以工作”。例如,如果权限不足,则-f命令将使其无效。您的意思是-f强制覆盖而没有提示。相反的标志-i表示需要交互才能覆盖。
埃里克·莱斯钦斯基

需要注意两点:1.)实现通常会测试您是否处于交互式终端(isatty(0))中,因此,例如,如果您的脚本作为管道的一部分运行,则不会被触发。2.)添加-f与撤消操作不同,-i因为mv -i -f有所不同mv,请参阅Mark的回答
phk
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.