关于bash:在shell中的一行中运行多个命令

Running multiple commands in one line in shell

假设我有一个文件/templates/apple,我想

  • 把它放在两个不同的地方然后
  • 删除原始。
  • 因此,/templates/apple将被复制到/templates/used AND /templates/inuse
    之后我想删除原件。

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

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

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

    这是正确的语法吗?


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

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

    要么

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

    总结(非详尽的)bash的命令操作符/分隔符:

    • |管道(管道)将一个命令的标准输出(stdout)转换为另一个命令的标准输入。请注意,stderr仍会进入其默认目标,无论发生什么情况。
    • |&将一个命令的stdoutstderr连接到另一个命令的标准输入中。非常有用,可在bash版本4及更高版本中使用。
    • &&仅在前一个命令成功时才执行&&的右手命令。
    • ||执行||的右手命令,只有前一个命令失败。
    • ;始终执行;的右手命令,无论前一个命令是成功还是失败。除非之前调用set -e,否则会导致bash失败。


    为什么cp到位置1,然后mv到位置2.这需要"删除"原件。

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

    1
    cp file1 file2 ; cp file1 file3 ; rm file1

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

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

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


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


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

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

    1
    2
    3
    $ echo 1#
    echo 2#
    echo 3

    输出:

    1
    2
    3
    1
    2
    3

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

    与:echo 1; echo 2; echo 3相同

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

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

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

    输出:

    1
    2
    1
    failed-command: command not found

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


    试试这个..

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


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

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

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

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