0

What is the difference among following path patterns in Linux

  • ./ e.g. cp ./ [destination-path]
  • ./. e.g. cp ./. [destination-path]
  • ./* e.g. cp ./* [destination-path]
  • ./** e.g. cp ./** [destination-path]
ctrl-alt-delor
  • 27,473
  • 9
  • 58
  • 102
Adnan
  • 103
  • 2
  • Did you try them? What happened? Is anything else still unclear? – Kusalananda Mar 07 '19 at 14:59
  • 2
    This question combines https://unix.stackexchange.com/questions/62070/ , https://unix.stackexchange.com/questions/381282/ , and https://unix.stackexchange.com/questions/62660/ . – JdeBP Mar 07 '19 at 15:06
  • @JeffSchaller I have provided `cp` as an example to make my question clear. I want to know the main difference. – Adnan Mar 07 '19 at 15:30
  • @Kusalananda yes I have executed them, found ./. and ./ same, ./* copies non hidden files but couldn't find the difference of ./**. – Adnan Mar 07 '19 at 15:31
  • Thank you very much @JdeBP for useful links, I found the answer from your given links. LOL where were they when I was searching, I was not using proper keywords perhaps. – Adnan Mar 07 '19 at 15:33
  • The `*` and `**` will get expanded my the shell. See `glob`ing in the manual for your shell. To understand `./.` first understand `././././././././.`. – ctrl-alt-delor Mar 07 '19 at 16:40

1 Answers1

2

The first two would make more sense with a recursive copy, i.e. cp -r. The difference comes up if the source is a named directory, and the destination exists. Of these:

cp -r src/  dest
cp -r src/. dest

the first would copy src into dest, creating dest/src and files within it (src/a becomes dest/src/a), while the latter copies the contents of src, so src/a becomes dest/a.

In the other two, the shell expands the glob, so the contents of the directory (except dotfiles) are copied even without -r.

cp ./*  dest
cp ./** dest

In the first, the shell expands ./* to the list of filenames in the current directory (except those starting with a dot), and cp copies them. In the second, shells supporting it would expand ./** to a recursive listing of filenames, and again cp would copy the files it was listed.

The recursive ** works at least in Bash if shopt -s globstar is set, in ksh with set -o globstar.

Neither Bash or ksh includes files or directories with names starting with dot in the result of **, regardless of which level in the tree they appear, so using that is not a very good way to make a complete copy of a full directory structure; cp -r . dest would copy dotfiles too.

Bash has shopt -s dotglob which unhides dotfiles with both * and **, I'm not sure if ksh has a similar feature.

ilkkachu
  • 133,243
  • 15
  • 236
  • 397
  • Thank you for such a good explanation, you said that "except those starting with a dot" mean hidden files will not be included in the list, what if I want to include them in the list or what if the source has many dot files, they will not be copied? – Adnan Mar 08 '19 at 09:40
  • @Adnan, yeah, `cp ./** dest/` would miss all dotfiles, unless you use `shopt -s dotglob` in Bash. So it's probably easier to just use `cp -r` for recursive copies (or `cp -a` in GNU cp). – ilkkachu Mar 08 '19 at 14:32