【问题标题】:Running multiple commands in one line in shell在 shell 的一行中运行多个命令
【发布时间】:2011-07-05 02:08:48
【问题描述】:

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

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

所以,/templates/apple 将被复制到 /templates/used AND /templates/inuse 然后我想删除原来的。

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

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

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

这是正确的语法吗?

【问题讨论】:

    标签: bash shell


    【解决方案1】:

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

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

    【讨论】:

    【解决方案2】:

    为什么不 cp 到位置 1,然后 mv 到位置 2。这可以“删除”原件。

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

    cp file1 file2 ; cp file1 file3 ; rm file1
    

    如果您要求各个命令必须成功才能启动下一个命令,那么您可以改用 &&

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        另一个选项是在每个命令的末尾键入 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

        【讨论】:

          【解决方案5】:

          试试这个..

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

          【讨论】:

            【解决方案6】:

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

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

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

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

            【讨论】:

              猜你喜欢
              • 2012-09-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-10-12
              • 1970-01-01
              • 2011-07-14
              • 2023-03-24
              • 1970-01-01
              相关资源
              最近更新 更多