在shell的一行中运行多个命令


388

说我有一个文件/templates/apple,我想

  1. 放在两个不同的地方,然后
  2. 删除原件。

因此,/templates/apple将其复制到/templates/usedAND /templates/inuse ,然后在此之后,我想删除原始文件。

cp这样做的最好方法,其次是rm?或者,还有更好的方法?

我想一行完成所有操作,所以我认为它看起来像:

cp /templates/apple /templates/used | cp /templates/apple /templates/inuse | rm /templates/apple

这是正确的语法吗?

Answers:


792

您正在使用|(管道)将命令的输出定向到另一个命令。您正在寻找的是&&操作员仅在上一个命令成功的情况下才执行下一个命令:

cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apple

要么

cp /templates/apple /templates/used && mv /templates/apple /templates/inuse

总结一下(非详尽地)bash的命令运算符/分隔符:

  • |stdout将一个命令的标准输出()管道传输到另一命令的标准输入中。请注意stderr,无论发生什么情况,它仍会进入其默认目的地。
  • |&将一个命令的两个stdout和两个都管道传输stderr到另一个命令的标准输入中。非常有用,在bash版本4及更高版本中可用。
  • &&&&仅在上一个命令成功的情况下执行右手命令。
  • ||仅执行||上一个失败的命令。
  • ;;无论上一条命令成功还是失败,都将始终执行右手命令。除非set -e先前已调用,否则将导致bash错误失败。


78

为什么不cp转到位置1,然后再mv转到位置2。这需要“除去”原稿。

不,这不是正确的语法。|用于“管道”一个程序的输出,并将其转换为下一个程序的输入。您想要的是;,它将多个命令分开。

cp file1 file2 ; cp file1 file3 ; rm file1

如果您要求单个命令必须在下一个命令启动之前成功,那么您可以使用&&

cp file1 file2 && cp file1 file3 && rm file1

这样,如果任何一条cp命令失败,rm将不会运行。


10

请注意,cp A B; rm A正是这样mv A B。这样也将更快,因为您不必实际复制字节(假设目标位于同一文件系统上),只需重命名文件即可。所以你要cp A B; mv A C


7

另一个选择是Ctrl+V Ctrl+J在每个命令的末尾键入。

示例(替换#Ctrl+V Ctrl+J):

$ echo 1#
echo 2#
echo 3

输出:

1
2
3

无论先前的命令是否失败,这将执行命令。

如同: echo 1; echo 2; echo 3

如果要停止执行失败的命令,请&&在每行末尾添加最后一行。

示例(替换#Ctrl+V Ctrl+J):

$ echo 1 &&#
failed-command &&#
echo 2

输出:

1
failed-command: command not found

zsh您还可以使用Alt+EnterEsc+Enter代替Ctrl+V Ctrl+J


3

尝试这个..

cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apple


2

使用管道对我来说很奇怪。无论如何,您应该使用逻辑andBash运算符:

$ cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apples

如果cp命令失败,rm将不会执行。

或者,您可以使用for循环和来制作更详细的命令行cmp

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.