You are not logged in.
I want to copy a directory (and all of its contents) to another directory.
In some examples of the cp command, I've seen, a dot(.) or asterisk(*) used at the end of the source location. I've googled and I just can't understand what the dot or asterisk would do compared to omitting them.
So, what is the difference between these commands:
cp -r /dir1/ /dir2/
cp -r /dir1/. /dir2/
cp -r /dir1/* /dir2/
Sorry if this is a dumb question.
Thanks :-)
Offline
This is not a `cp` question, as `cp` is not really involved. The asterisk is a feature of your shell, which expands it. `cp` receives the expanded file names. It never sees the asterisk. The same applies to all other commands.⁽¹⁾ Instead of `cp`, use `echo` to understand what arguments a command receives.
If in bash⁽²⁾ you may use this helper function:
printArgs() {
i=1
while (( $# )); do
printf '% 4d: %s\n' "$i" "$1"
(( ++i ))
shift
done
}A single dot is a special entry in a directory, which links to the directory itself. It’s an entry no different as any sub-directory would be. In a similar fashion two dots are an entry that link to the parent directory.
____
⁽¹⁾ Some commands may accept globs as their arguments, but those must be enclosed in quotes to prevent expansion by the shell.
⁽²⁾ May work in other shells too.
Last edited by mpan (2022-12-02 04:02:26)
Offline
[Edit]: mpan got there first and answered excellently. ![]()
The asterisk is shell-globbing (it will expand to all the files underneath dir1). Note: it's a bit worrying doing this with `cp` (or `mv`; this isn't specific to `cp) because it can lead to doing something different than you'd expect (potentially leading to data loss; speaking from experience, I have accidentally overwritten files by doing this; just say "No"
).
The very verbose version of what people are hoping the asterisk version of the command will do is a for loop like so:
for i in /dir1/*; do
cp -r "$i" /dir2/
doneIn nix-like operating systems, every directory has two special "files" always present: `.` and `..`. `..` is the given directory's parent directory, and `.` refers to the directory itself.
So, `/dir1/..` just refers to `/` and `/dir1/.` refers to `/dir1`. There should be no practical difference between the first and second examples you list.
All the best,
-HG
Offline
The asterisk is shell-globbing (it will expand to all the files underneath dir1). Note: it's a bit worrying doing this with `cp` (or `mv`; this isn't specific to `cp) because it can lead to doing something different than you'd expect (potentially leading to data loss; speaking from experience, I have accidentally overwritten files by doing this; just say "No"
).
$ for i in cp mv rm; do type $i; done
cp is aliased to `cp -n'
mv is aliased to `mv -n'
rm is aliased to `rm --one-file-system'Never forget your fallibility when configuring your shell
. For root rm is configured to be interactive, but that would be too inconvenient for day-to-day use.
Edit: also
$ shopt -o
...
noclobber on
...Last edited by cfr (2022-12-02 04:36:42)
CLI Paste | How To Ask Questions
Arch Linux | x86_64 | GPT | EFI boot | refind | stub loader | systemd | LVM2 on LUKS
Lenovo x270 | Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz | Intel Wireless 8265/8275 | US keyboard w/ Euro | 512G NVMe INTEL SSDPEKKF512G7L
Offline
FYI, off the primary topic, but `type` can take multiple arguments:
$ type cp mv rm
cp is an alias for cp -i
mv is an alias for mv -i
rm is rm"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
FYI, off the primary topic, but `type` can take multiple arguments:
Thanks!
CLI Paste | How To Ask Questions
Arch Linux | x86_64 | GPT | EFI boot | refind | stub loader | systemd | LVM2 on LUKS
Lenovo x270 | Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz | Intel Wireless 8265/8275 | US keyboard w/ Euro | 512G NVMe INTEL SSDPEKKF512G7L
Offline