Say I have a file /templates/apple
and I want to
So, /templates/apple
will be copied to /templates/used
AND /templates/inuse
and then after that I'd like to remove the original.
Is cp
the best way to do this, followed by rm
? Or is there a better way?
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?
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:
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:
|
pipes (pipelines) the standard output ( stdout
) of one command into the standard input of another one. Note that stderr
still goes into its default destination, whatever that happen to be. |&
pipes both stdout
and stderr
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. Unless set -e
was previously invoked, which causes bash
to fail on an error. Why not cp
to location 1, then mv
to location 2. This takes care of "removing" the original.
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.
Note that cp AB; rm A
cp AB; rm A
is exactly mv AB
. 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 AB; mv AC
cp AB; mv AC
Another option is typing Ctrl+V Ctrl+J at the end of each command.
Example (replace #
with Ctrl+V Ctrl+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+V Ctrl+J ):
$ echo 1 &&#
failed-command &&#
echo 2
Output:
1
failed-command: command not found
In zsh
you can also use Alt+Enter or Esc+Enter instead of Ctrl+V Ctrl+J
尝试这个..
cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apple
Using pipes seems weird to me. Anyway you should use the logical and
Bash operator:
$ cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apples
If the cp
commands fail, the rm
will not be executed.
Or, you can make a more elaborated command line using a for
loop and cmp
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.