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

时间:2011-02-27 01:36:11

标签: bash shell

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

  1. 把它放在两个不同的地方然后
  2. 删除原文。
  3. 因此,/templates/apple将被复制到/templates/used/templates/inuse 之后我想删除原文。

    cp是执行此操作的最佳方式,其次是rm吗?或者有更好的方法吗?

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

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

    这是正确的语法吗?

6 个答案:

答案 0 :(得分:633)

您正在使用|(管道)将命令输出定向到另一个命令。您正在寻找的是&&运算符,只有在前一个命令成功的情况下执行下一个命令:

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仍会进入其默认目标,无论发生什么情况。
  • |&将一个命令的stdoutstderr连接到另一个命令的标准输入中。非常有用,可在bash版本4及更高版本中使用。
  • &&仅在前一个成功的情况下执行&&的右侧命令。
  • ||执行||的右手命令,只有前一个命令失败。
  • ;执行;的右手命令,无论前一个命令是成功还是失败。除非先前调用set -e,否则会导致bash因错误而失败。

答案 1 :(得分:67)

为什么不cp到位置1,然后mv到位置2.这需要“删除”原始文件。

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

cp file1 file2 ; cp file1 file3 ; rm file1

如果您要求在下一个命令启动之前必须成功,那么您将使用&&代替:

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

这样,如果cp命令之一失败,rm将无法运行。

答案 2 :(得分:8)

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

答案 3 :(得分:6)

另一个选择是在每个命令的末尾输入 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 + Enter Esc + Enter 而不是 Ctrl + V Ctrl + J

答案 4 :(得分:2)

试试这个..

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

答案 5 :(得分:1)

使用管道对我来说似乎很奇怪。无论如何,你应该使用逻辑and Bash运算符:

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

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

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