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

Joh*_*yns 349 bash shell

说我有一个文件/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
Run Code Online (Sandbox Code Playgroud)

这是正确的语法吗?

Max*_*kin 710

您正在使用|(管道)将命令的输出定向到另一个命令.你要找的是&&运营商只有在前一个命令成功的情况下执行下一个命令:

cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apple
Run Code Online (Sandbox Code Playgroud)

要么

cp /templates/apple /templates/used && mv /templates/apple /templates/inuse
Run Code Online (Sandbox Code Playgroud)

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

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

  • 已投票。官方文档https://www.gnu.org/software/bash/manual/bash.html#Lists (3认同)

Mar*_*c B 71

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

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

cp file1 file2 ; cp file1 file3 ; rm file1
Run Code Online (Sandbox Code Playgroud)

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

cp file1 file2 && cp file1 file3 && rm file1
Run Code Online (Sandbox Code Playgroud)

这样,如果其中一个cp命令失败,rm则不会运行.


gle*_*man 10

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


Eya*_*vin 7

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

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

$ echo 1#
echo 2#
echo 3
Run Code Online (Sandbox Code Playgroud)

输出:

1
2
3
Run Code Online (Sandbox Code Playgroud)

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

与...一样: echo 1; echo 2; echo 3

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

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

$ echo 1 &&#
failed-command &&#
echo 2
Run Code Online (Sandbox Code Playgroud)

输出:

1
failed-command: command not found
Run Code Online (Sandbox Code Playgroud)

zsh你也可以使用Alt+EnterEsc+Enter代替Ctrl+V Ctrl+J