bash 在 shell 中的一行中运行多个命令
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5130847/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Running multiple commands in one line in shell
提问by John Redyns
Say I have a file /templates/apple
and I want to
说我有一个文件/templates/apple
,我想
- put it in two different places and then
- remove the original.
- 把它放在两个不同的地方,然后
- 取出原件。
So, /templates/apple
will be copied to /templates/used
AND /templates/inuse
and then after that I'd like to remove the original.
所以,/templates/apple
将被复制到/templates/used
AND /templates/inuse
,然后我想删除原来的。
Is cp
the best way to do this, followed by rm
? Or is there a better way?
是cp
最好的方法,其次是rm
?或者,还有更好的方法?
I want to do it all in one line so I'm thinking it would look something like:
我想在一行中完成所有操作,所以我认为它看起来像:
cp /templates/apple /templates/used | cp /templates/apple /templates/inuse | rm /templates/apple
Is this the correct syntax?
这是正确的语法吗?
回答by Maxim Egorushkin
You are using |
(pipe) to direct the output of a command into another command. What you are looking for is &&
operator to execute the next command only if the previous one succeeded:
您正在使用|
(pipe) 将命令的输出定向到另一个命令。您正在寻找的是&&
操作员仅在前一个命令成功时才执行下一个命令:
cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apple
Or
或者
cp /templates/apple /templates/used && mv /templates/apple /templates/inuse
To summarize (non-exhaustively) bash's command operators/separators:
总结(非详尽地)bash 的命令操作符/分隔符:
|
pipes (pipelines) the standard output (stdout
) of one command into the standard input of another one. Note thatstderr
still goes into its default destination, whatever that happen to be.|&
pipes bothstdout
andstderr
of one command into the standard input of another one. Very useful, available in bash version 4 and above.&&
executes the right-hand command of&&
only if the previous one succeeded.||
executes the right-hand command of||
only it the previous one failed.;
executes the right-hand command of;
always regardless whether the previous command succeeded or failed. Unlessset -e
was previously invoked, which causesbash
to fail on an error.
|
管道 (pipelines) 将stdout
一个命令的标准输出 ( ) 连接到另一个命令的标准输入。请注意stderr
,无论发生什么情况,它仍然会进入其默认目的地。|&
将一个命令的stdout
和管道传输stderr
到另一个命令的标准输入中。非常有用,可在 bash 版本 4 及更高版本中使用。&&
&&
仅当前一个成功时才执行右侧的命令。||
仅执行||
前一个失败的右侧命令。;
;
无论前一个命令是成功还是失败,都执行always的右侧命令。除非set -e
之前被调用,这会导致bash
错误失败。
回答by Marc B
Why not cp
to location 1, then mv
to location 2. This takes care of "removing" the original.
为什么不到cp
位置 1,然后mv
到位置 2。这负责“删除”原始文件。
And no, it's not the correct syntax. |
is used to "pipe" output from one program and turn it into input for the next program. What you want is ;
, which seperates multiple commands.
不,这不是正确的语法。|
用于从一个程序“管道”输出并将其转换为下一个程序的输入。你想要的是;
,它分隔多个命令。
cp file1 file2 ; cp file1 file3 ; rm file1
If you require that the individual commands MUST succeed before the next can be started, then you'd use &&
instead:
如果您要求单个命令必须成功才能启动下一个命令,那么您可以&&
改用:
cp file1 file2 && cp file1 file3 && rm file1
That way, if either of the cp
commands fails, the rm
will not run.
这样,如果其中一个cp
命令失败,rm
则不会运行。
回答by glenn Hymanman
Note that cp A B; rm A
is exactly mv A B
. It'll be faster too, as you don't have to actually copy the bytes (assuming the destination is on the same filesystem), just rename the file. So you want cp A B; mv A C
请注意,cp A B; rm A
正是mv A B
. 它也会更快,因为您不必实际复制字节(假设目标位于同一文件系统上),只需重命名文件即可。所以你要cp A B; mv A C
回答by Eyal Levin
Another option is typing Ctrl+VCtrl+Jat the end of each command.
另一种选择是Ctrl+VCtrl+J在每个命令的末尾键入。
Example (replace #
with Ctrl+VCtrl+J):
示例(替换#
为Ctrl+VCtrl+J):
$ echo 1#
echo 2#
echo 3
Output:
输出:
1
2
3
This will execute the commands regardless if previous ones failed.
无论以前的命令是否失败,这都会执行命令。
Same as: echo 1; echo 2; echo 3
与...一样: echo 1; echo 2; echo 3
If you want to stop execution on failed commands, add &&
at the end of each line except the last one.
如果要停止执行失败的命令,请&&
在除最后一行之外的每一行末尾添加。
Example (replace #
with Ctrl+VCtrl+J):
示例(替换#
为Ctrl+VCtrl+J):
$ echo 1 &&#
failed-command &&#
echo 2
Output:
输出:
1
failed-command: command not found
In zsh
you can also use Alt+Enteror Esc+Enterinstead of Ctrl+VCtrl+J
在zsh
你也可以使用Alt+Enter或Esc+Enter代替Ctrl+VCtrl+J
回答by Peter
Try this..
尝试这个..
cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apple
cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apple
回答by Renaud
Using pipes seems weird to me. Anyway you should use the logical and
Bash operator:
使用管道对我来说似乎很奇怪。无论如何,您应该使用逻辑and
Bash 运算符:
$ cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apples
If the cp
commands fail, the rm
will not be executed.
如果cp
命令失败,rm
则不会执行。
Or, you can make a more elaborated command line using a for
loop and cmp
.
或者,您可以使用for
循环和cmp
.