Why was `cp` designed to silently overwrite existing files?
Clash Royale CLAN TAG#URR8PPP
up vote
4
down vote
favorite
I tested cp
with the following commands:
$ ls
first.html second.html third.html
$ cat first.html
first
$ cat second.html
second
$ cat third.html
third
Then I copy first.html
to second.html
:
$ cp first.html second.html
$ cat second.html
first
The file second.html
is silently overwritten without any errors. However, if I do it in a desktop GUI by dragging and dropping a file with the same name, it will be suffixed as first1.html
automatically. This avoids accidentally overwriting an existing file.
Why doesn't cp
follow this pattern instead of overwriting files silently?
cp history
New contributor
rider dragon is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |Â
up vote
4
down vote
favorite
I tested cp
with the following commands:
$ ls
first.html second.html third.html
$ cat first.html
first
$ cat second.html
second
$ cat third.html
third
Then I copy first.html
to second.html
:
$ cp first.html second.html
$ cat second.html
first
The file second.html
is silently overwritten without any errors. However, if I do it in a desktop GUI by dragging and dropping a file with the same name, it will be suffixed as first1.html
automatically. This avoids accidentally overwriting an existing file.
Why doesn't cp
follow this pattern instead of overwriting files silently?
cp history
New contributor
rider dragon is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
3
I imagine only the coreutils designers can truly answer the question, but it's just the way it works for now. Usually the apps are built assuming the user really means what they're doing and to minimize the extra prompting. If you want to change the behavior, alias 'cp' to 'cp -i' or 'cp -n'.
– kevlinux
4 hours ago
Is it "do one thing at one time"? @kevlinux
– rider dragon
3 hours ago
1
@kevlinux The coreutils devs are just implementing the POSIX standard.
– Kusalananda
1 hour ago
add a comment |Â
up vote
4
down vote
favorite
up vote
4
down vote
favorite
I tested cp
with the following commands:
$ ls
first.html second.html third.html
$ cat first.html
first
$ cat second.html
second
$ cat third.html
third
Then I copy first.html
to second.html
:
$ cp first.html second.html
$ cat second.html
first
The file second.html
is silently overwritten without any errors. However, if I do it in a desktop GUI by dragging and dropping a file with the same name, it will be suffixed as first1.html
automatically. This avoids accidentally overwriting an existing file.
Why doesn't cp
follow this pattern instead of overwriting files silently?
cp history
New contributor
rider dragon is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
I tested cp
with the following commands:
$ ls
first.html second.html third.html
$ cat first.html
first
$ cat second.html
second
$ cat third.html
third
Then I copy first.html
to second.html
:
$ cp first.html second.html
$ cat second.html
first
The file second.html
is silently overwritten without any errors. However, if I do it in a desktop GUI by dragging and dropping a file with the same name, it will be suffixed as first1.html
automatically. This avoids accidentally overwriting an existing file.
Why doesn't cp
follow this pattern instead of overwriting files silently?
cp history
cp history
New contributor
rider dragon is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
rider dragon is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
edited 3 mins ago


isanae
13816
13816
New contributor
rider dragon is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
asked 4 hours ago


rider dragon
1234
1234
New contributor
rider dragon is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
rider dragon is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
rider dragon is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
3
I imagine only the coreutils designers can truly answer the question, but it's just the way it works for now. Usually the apps are built assuming the user really means what they're doing and to minimize the extra prompting. If you want to change the behavior, alias 'cp' to 'cp -i' or 'cp -n'.
– kevlinux
4 hours ago
Is it "do one thing at one time"? @kevlinux
– rider dragon
3 hours ago
1
@kevlinux The coreutils devs are just implementing the POSIX standard.
– Kusalananda
1 hour ago
add a comment |Â
3
I imagine only the coreutils designers can truly answer the question, but it's just the way it works for now. Usually the apps are built assuming the user really means what they're doing and to minimize the extra prompting. If you want to change the behavior, alias 'cp' to 'cp -i' or 'cp -n'.
– kevlinux
4 hours ago
Is it "do one thing at one time"? @kevlinux
– rider dragon
3 hours ago
1
@kevlinux The coreutils devs are just implementing the POSIX standard.
– Kusalananda
1 hour ago
3
3
I imagine only the coreutils designers can truly answer the question, but it's just the way it works for now. Usually the apps are built assuming the user really means what they're doing and to minimize the extra prompting. If you want to change the behavior, alias 'cp' to 'cp -i' or 'cp -n'.
– kevlinux
4 hours ago
I imagine only the coreutils designers can truly answer the question, but it's just the way it works for now. Usually the apps are built assuming the user really means what they're doing and to minimize the extra prompting. If you want to change the behavior, alias 'cp' to 'cp -i' or 'cp -n'.
– kevlinux
4 hours ago
Is it "do one thing at one time"? @kevlinux
– rider dragon
3 hours ago
Is it "do one thing at one time"? @kevlinux
– rider dragon
3 hours ago
1
1
@kevlinux The coreutils devs are just implementing the POSIX standard.
– Kusalananda
1 hour ago
@kevlinux The coreutils devs are just implementing the POSIX standard.
– Kusalananda
1 hour ago
add a comment |Â
3 Answers
3
active
oldest
votes
up vote
11
down vote
accepted
The default overwrite behavior of cp
is specified in POSIX.
If source_file is of type regular file, the following steps shall be taken:
3.a. The behavior is unspecified if dest_file exists and was written by a previous step. Otherwise, if dest_file exists, the following steps shall be taken:
3.a.i. If the -i option is in effect, the cp utility shall write a prompt to the standard error and read a line from the standard input. If the response is not affirmative, cp shall do nothing more with source_file and go on to any remaining files.
3.a.ii. A file descriptor for dest_file shall be obtained by performing actions equivalent to the open() function defined in the System Interfaces volume of POSIX.1-2017 called using dest_file as the path argument, and the bitwise-inclusive OR of O_WRONLY and O_TRUNC as the oflag argument.
3.a.iii. If the attempt to obtain a file descriptor fails and the -f option is in effect, cp shall attempt to remove the file by performing actions equivalent to the unlink() function defined in the System Interfaces volume of POSIX.1-2017 called using dest_file as the path argument. If this attempt succeeds, cp shall continue with step 3b.
When the POSIX specification was written, there already was a large number of scripts in existence, with a built-in assumption for the default overwrite behavior. Many of those scripts were designed to run without direct user presence, e.g. as cron jobs or other background tasks. Changing the behavior would have broken them. Reviewing and modifying them all to add an option to force overwriting wherever needed was probably considered a huge task with minimal benefits.
Also, the Unix command line was always designed to allow an experienced user to work efficiently, even at the expense of a hard learning curve for a beginner. When the user enters a command, the computer is to expect that the user really means it, without any second-guessing; it is the user's responsibility to be careful with potentially destructive commands.
add a comment |Â
up vote
5
down vote
You may insert the "if check" yourself with
alias cp='cp -i'
The -i
option to cp
makes it ask interactively if the operation would overwrite the target and with the above alias, your interactive use of cp
would enable this option by default.
The cp
utility is often used in scripts. These scripts may not always be run manually, but may be part of system maintenance tasks run by via cron or some similar facility. In those cases, there are no humans to ask for confirmation.
To have a script avoid overwriting a file with cp
one may insert an explicit check:
if [ -e "$target" ]; then
printf '%s already exists, refusing to overwriten' "$target" >&2
exit 1
fi
cp "$source" "$target"
I'm opting for exiting the script with an error message if $target
exists in the above example. The existence of the target is obviously unexpected, and allowing the script to continue after detecting this may lead to other more severe issues (depending on what the script is doing and what its purpose is).
I remember some distros set such an alias at least for therm
command in interactive shells. AFAIR, SuSE is one of them.
– rexkogitans
9 mins ago
add a comment |Â
up vote
0
down vote
Because these commands are also meant to be used in scripts, possibly running without any kind of human supervision, and also because there are plenty of cases where you indeed want to overwrite the target (the philosophy of the Linux shells is that the human knows what s/he is doing)
There still a few safeguards:
- GNU
cp
has a-n
|--no-clobber
option - if you copy several files to a single one
cp
will complain that the last one is not a directory.
add a comment |Â
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
11
down vote
accepted
The default overwrite behavior of cp
is specified in POSIX.
If source_file is of type regular file, the following steps shall be taken:
3.a. The behavior is unspecified if dest_file exists and was written by a previous step. Otherwise, if dest_file exists, the following steps shall be taken:
3.a.i. If the -i option is in effect, the cp utility shall write a prompt to the standard error and read a line from the standard input. If the response is not affirmative, cp shall do nothing more with source_file and go on to any remaining files.
3.a.ii. A file descriptor for dest_file shall be obtained by performing actions equivalent to the open() function defined in the System Interfaces volume of POSIX.1-2017 called using dest_file as the path argument, and the bitwise-inclusive OR of O_WRONLY and O_TRUNC as the oflag argument.
3.a.iii. If the attempt to obtain a file descriptor fails and the -f option is in effect, cp shall attempt to remove the file by performing actions equivalent to the unlink() function defined in the System Interfaces volume of POSIX.1-2017 called using dest_file as the path argument. If this attempt succeeds, cp shall continue with step 3b.
When the POSIX specification was written, there already was a large number of scripts in existence, with a built-in assumption for the default overwrite behavior. Many of those scripts were designed to run without direct user presence, e.g. as cron jobs or other background tasks. Changing the behavior would have broken them. Reviewing and modifying them all to add an option to force overwriting wherever needed was probably considered a huge task with minimal benefits.
Also, the Unix command line was always designed to allow an experienced user to work efficiently, even at the expense of a hard learning curve for a beginner. When the user enters a command, the computer is to expect that the user really means it, without any second-guessing; it is the user's responsibility to be careful with potentially destructive commands.
add a comment |Â
up vote
11
down vote
accepted
The default overwrite behavior of cp
is specified in POSIX.
If source_file is of type regular file, the following steps shall be taken:
3.a. The behavior is unspecified if dest_file exists and was written by a previous step. Otherwise, if dest_file exists, the following steps shall be taken:
3.a.i. If the -i option is in effect, the cp utility shall write a prompt to the standard error and read a line from the standard input. If the response is not affirmative, cp shall do nothing more with source_file and go on to any remaining files.
3.a.ii. A file descriptor for dest_file shall be obtained by performing actions equivalent to the open() function defined in the System Interfaces volume of POSIX.1-2017 called using dest_file as the path argument, and the bitwise-inclusive OR of O_WRONLY and O_TRUNC as the oflag argument.
3.a.iii. If the attempt to obtain a file descriptor fails and the -f option is in effect, cp shall attempt to remove the file by performing actions equivalent to the unlink() function defined in the System Interfaces volume of POSIX.1-2017 called using dest_file as the path argument. If this attempt succeeds, cp shall continue with step 3b.
When the POSIX specification was written, there already was a large number of scripts in existence, with a built-in assumption for the default overwrite behavior. Many of those scripts were designed to run without direct user presence, e.g. as cron jobs or other background tasks. Changing the behavior would have broken them. Reviewing and modifying them all to add an option to force overwriting wherever needed was probably considered a huge task with minimal benefits.
Also, the Unix command line was always designed to allow an experienced user to work efficiently, even at the expense of a hard learning curve for a beginner. When the user enters a command, the computer is to expect that the user really means it, without any second-guessing; it is the user's responsibility to be careful with potentially destructive commands.
add a comment |Â
up vote
11
down vote
accepted
up vote
11
down vote
accepted
The default overwrite behavior of cp
is specified in POSIX.
If source_file is of type regular file, the following steps shall be taken:
3.a. The behavior is unspecified if dest_file exists and was written by a previous step. Otherwise, if dest_file exists, the following steps shall be taken:
3.a.i. If the -i option is in effect, the cp utility shall write a prompt to the standard error and read a line from the standard input. If the response is not affirmative, cp shall do nothing more with source_file and go on to any remaining files.
3.a.ii. A file descriptor for dest_file shall be obtained by performing actions equivalent to the open() function defined in the System Interfaces volume of POSIX.1-2017 called using dest_file as the path argument, and the bitwise-inclusive OR of O_WRONLY and O_TRUNC as the oflag argument.
3.a.iii. If the attempt to obtain a file descriptor fails and the -f option is in effect, cp shall attempt to remove the file by performing actions equivalent to the unlink() function defined in the System Interfaces volume of POSIX.1-2017 called using dest_file as the path argument. If this attempt succeeds, cp shall continue with step 3b.
When the POSIX specification was written, there already was a large number of scripts in existence, with a built-in assumption for the default overwrite behavior. Many of those scripts were designed to run without direct user presence, e.g. as cron jobs or other background tasks. Changing the behavior would have broken them. Reviewing and modifying them all to add an option to force overwriting wherever needed was probably considered a huge task with minimal benefits.
Also, the Unix command line was always designed to allow an experienced user to work efficiently, even at the expense of a hard learning curve for a beginner. When the user enters a command, the computer is to expect that the user really means it, without any second-guessing; it is the user's responsibility to be careful with potentially destructive commands.
The default overwrite behavior of cp
is specified in POSIX.
If source_file is of type regular file, the following steps shall be taken:
3.a. The behavior is unspecified if dest_file exists and was written by a previous step. Otherwise, if dest_file exists, the following steps shall be taken:
3.a.i. If the -i option is in effect, the cp utility shall write a prompt to the standard error and read a line from the standard input. If the response is not affirmative, cp shall do nothing more with source_file and go on to any remaining files.
3.a.ii. A file descriptor for dest_file shall be obtained by performing actions equivalent to the open() function defined in the System Interfaces volume of POSIX.1-2017 called using dest_file as the path argument, and the bitwise-inclusive OR of O_WRONLY and O_TRUNC as the oflag argument.
3.a.iii. If the attempt to obtain a file descriptor fails and the -f option is in effect, cp shall attempt to remove the file by performing actions equivalent to the unlink() function defined in the System Interfaces volume of POSIX.1-2017 called using dest_file as the path argument. If this attempt succeeds, cp shall continue with step 3b.
When the POSIX specification was written, there already was a large number of scripts in existence, with a built-in assumption for the default overwrite behavior. Many of those scripts were designed to run without direct user presence, e.g. as cron jobs or other background tasks. Changing the behavior would have broken them. Reviewing and modifying them all to add an option to force overwriting wherever needed was probably considered a huge task with minimal benefits.
Also, the Unix command line was always designed to allow an experienced user to work efficiently, even at the expense of a hard learning curve for a beginner. When the user enters a command, the computer is to expect that the user really means it, without any second-guessing; it is the user's responsibility to be careful with potentially destructive commands.
answered 3 hours ago
telcoM
13.2k11441
13.2k11441
add a comment |Â
add a comment |Â
up vote
5
down vote
You may insert the "if check" yourself with
alias cp='cp -i'
The -i
option to cp
makes it ask interactively if the operation would overwrite the target and with the above alias, your interactive use of cp
would enable this option by default.
The cp
utility is often used in scripts. These scripts may not always be run manually, but may be part of system maintenance tasks run by via cron or some similar facility. In those cases, there are no humans to ask for confirmation.
To have a script avoid overwriting a file with cp
one may insert an explicit check:
if [ -e "$target" ]; then
printf '%s already exists, refusing to overwriten' "$target" >&2
exit 1
fi
cp "$source" "$target"
I'm opting for exiting the script with an error message if $target
exists in the above example. The existence of the target is obviously unexpected, and allowing the script to continue after detecting this may lead to other more severe issues (depending on what the script is doing and what its purpose is).
I remember some distros set such an alias at least for therm
command in interactive shells. AFAIR, SuSE is one of them.
– rexkogitans
9 mins ago
add a comment |Â
up vote
5
down vote
You may insert the "if check" yourself with
alias cp='cp -i'
The -i
option to cp
makes it ask interactively if the operation would overwrite the target and with the above alias, your interactive use of cp
would enable this option by default.
The cp
utility is often used in scripts. These scripts may not always be run manually, but may be part of system maintenance tasks run by via cron or some similar facility. In those cases, there are no humans to ask for confirmation.
To have a script avoid overwriting a file with cp
one may insert an explicit check:
if [ -e "$target" ]; then
printf '%s already exists, refusing to overwriten' "$target" >&2
exit 1
fi
cp "$source" "$target"
I'm opting for exiting the script with an error message if $target
exists in the above example. The existence of the target is obviously unexpected, and allowing the script to continue after detecting this may lead to other more severe issues (depending on what the script is doing and what its purpose is).
I remember some distros set such an alias at least for therm
command in interactive shells. AFAIR, SuSE is one of them.
– rexkogitans
9 mins ago
add a comment |Â
up vote
5
down vote
up vote
5
down vote
You may insert the "if check" yourself with
alias cp='cp -i'
The -i
option to cp
makes it ask interactively if the operation would overwrite the target and with the above alias, your interactive use of cp
would enable this option by default.
The cp
utility is often used in scripts. These scripts may not always be run manually, but may be part of system maintenance tasks run by via cron or some similar facility. In those cases, there are no humans to ask for confirmation.
To have a script avoid overwriting a file with cp
one may insert an explicit check:
if [ -e "$target" ]; then
printf '%s already exists, refusing to overwriten' "$target" >&2
exit 1
fi
cp "$source" "$target"
I'm opting for exiting the script with an error message if $target
exists in the above example. The existence of the target is obviously unexpected, and allowing the script to continue after detecting this may lead to other more severe issues (depending on what the script is doing and what its purpose is).
You may insert the "if check" yourself with
alias cp='cp -i'
The -i
option to cp
makes it ask interactively if the operation would overwrite the target and with the above alias, your interactive use of cp
would enable this option by default.
The cp
utility is often used in scripts. These scripts may not always be run manually, but may be part of system maintenance tasks run by via cron or some similar facility. In those cases, there are no humans to ask for confirmation.
To have a script avoid overwriting a file with cp
one may insert an explicit check:
if [ -e "$target" ]; then
printf '%s already exists, refusing to overwriten' "$target" >&2
exit 1
fi
cp "$source" "$target"
I'm opting for exiting the script with an error message if $target
exists in the above example. The existence of the target is obviously unexpected, and allowing the script to continue after detecting this may lead to other more severe issues (depending on what the script is doing and what its purpose is).
edited 1 hour ago
answered 1 hour ago


Kusalananda
111k15216342
111k15216342
I remember some distros set such an alias at least for therm
command in interactive shells. AFAIR, SuSE is one of them.
– rexkogitans
9 mins ago
add a comment |Â
I remember some distros set such an alias at least for therm
command in interactive shells. AFAIR, SuSE is one of them.
– rexkogitans
9 mins ago
I remember some distros set such an alias at least for the
rm
command in interactive shells. AFAIR, SuSE is one of them.– rexkogitans
9 mins ago
I remember some distros set such an alias at least for the
rm
command in interactive shells. AFAIR, SuSE is one of them.– rexkogitans
9 mins ago
add a comment |Â
up vote
0
down vote
Because these commands are also meant to be used in scripts, possibly running without any kind of human supervision, and also because there are plenty of cases where you indeed want to overwrite the target (the philosophy of the Linux shells is that the human knows what s/he is doing)
There still a few safeguards:
- GNU
cp
has a-n
|--no-clobber
option - if you copy several files to a single one
cp
will complain that the last one is not a directory.
add a comment |Â
up vote
0
down vote
Because these commands are also meant to be used in scripts, possibly running without any kind of human supervision, and also because there are plenty of cases where you indeed want to overwrite the target (the philosophy of the Linux shells is that the human knows what s/he is doing)
There still a few safeguards:
- GNU
cp
has a-n
|--no-clobber
option - if you copy several files to a single one
cp
will complain that the last one is not a directory.
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Because these commands are also meant to be used in scripts, possibly running without any kind of human supervision, and also because there are plenty of cases where you indeed want to overwrite the target (the philosophy of the Linux shells is that the human knows what s/he is doing)
There still a few safeguards:
- GNU
cp
has a-n
|--no-clobber
option - if you copy several files to a single one
cp
will complain that the last one is not a directory.
Because these commands are also meant to be used in scripts, possibly running without any kind of human supervision, and also because there are plenty of cases where you indeed want to overwrite the target (the philosophy of the Linux shells is that the human knows what s/he is doing)
There still a few safeguards:
- GNU
cp
has a-n
|--no-clobber
option - if you copy several files to a single one
cp
will complain that the last one is not a directory.
edited 1 hour ago


Kusalananda
111k15216342
111k15216342
answered 1 hour ago


xenoid
1,9711620
1,9711620
add a comment |Â
add a comment |Â
rider dragon is a new contributor. Be nice, and check out our Code of Conduct.
rider dragon is a new contributor. Be nice, and check out our Code of Conduct.
rider dragon is a new contributor. Be nice, and check out our Code of Conduct.
rider dragon is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f477401%2fwhy-was-cp-designed-to-silently-overwrite-existing-files%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
3
I imagine only the coreutils designers can truly answer the question, but it's just the way it works for now. Usually the apps are built assuming the user really means what they're doing and to minimize the extra prompting. If you want to change the behavior, alias 'cp' to 'cp -i' or 'cp -n'.
– kevlinux
4 hours ago
Is it "do one thing at one time"? @kevlinux
– rider dragon
3 hours ago
1
@kevlinux The coreutils devs are just implementing the POSIX standard.
– Kusalananda
1 hour ago