Doubt about the usage of ' - ' as redirection operator

Hello guys! I was studying the bash script language and came across this example of ' - ' special character used as redirection operator:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

(cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xpvf -)
# Move entire file tree from one directory to another
# [courtesy Alan Cox <a.cox@swansea.ac.uk>, with a minor change]

# 1) cd /source/directory
#    Source directory, where the files to be moved are.
# 2) &&
#   "And-list": if the 'cd' operation successful,
#    then execute the next command.
# 3) tar cf - .
#    The 'c' option 'tar' archiving command creates a new archive,
#    the 'f' (file) option, followed by '-' designates the target file
#    as stdout, and do it in current directory tree ('.').
# 4) |
#    Piped to ...
# 5) ( ... )
#    a subshell
# 6) cd /dest/directory
#    Change to the destination directory.
# 7) &&
#   "And-list", as above
# 8) tar xpvf -
#    Unarchive ('x'), preserve ownership and file permissions ('p'),
#    and send verbose messages to stdout ('v'),
#    reading data from stdin ('f' followed by '-').
#
#    Note that 'x' is a command, and 'p', 'v', 'f' are options.
#
# Whew!



# More elegant than, but equivalent to:
#   cd source/directory
#   tar cf - . | (cd ../dest/directory; tar xpvf -)
#
#     Also having same effect:
# cp -a /source/directory/* /dest/directory
#     Or:
# cp -a /source/directory/* /source/directory/.[^.]* /dest/directory
#     If there are hidden files in /source/directory.
 */


source: https://tldp.org/LDP/abs/html/special-chars.html

I understand that "-" redirect stdin/stdout depending of the context
for example: $ CURL --output - --url "www.google.com"
It prints the output over the stdout. But for the example above i didnt understand the meaning of ' - '

For this line of code: $ (cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xpvf -)

tar cf - . the doc says "followed by '-' designates the target file as stdout". So what is the name of the target and where does it get it from?

Thank you in advice.
So what is the name of the target and where does it get it from?


There is no name for the target, the first tar archives all the files in the directory, that information is piped to the other directory where it extracted.

To me, it seems easier to just copy the files, as per the comment at the end of the script.
To me, it seems easier to just copy the files, as per the comment at the end of the script.
Presumably, this is just to demonstrate the technique. But it can be useful in other contexts, say with ssh to copy a directory tree with attributes from one host to another.
@kbw

Cool, thanks for your always great advice :+)
There is no name for the target, the first tar archives all the files in the directory, that information is piped to the other directory where it extracted.


So, an archive exist... but it's just passed thorugh the pipe?? i mean.. in that example, does tar create the archive or not?

It's not that easy to understand.. :(
As @TheIdeasMan said:
tar -cf - .. creates a tar archive and writes it to stdout, not a file
tar -xf - ... extracts a tar archive from stdin, not a file.

There are no files involved, just streams.

Remember, tar files can be huge, and you may not want to store the physical file if it's just an intermediate step.

A practical example is, say you want to copy a directory from one computer to another:
1. copy from this computer to host build1.
 
tar -cf - ~/projects | ssh build1 "tar -xf -"


2. As is happens, cat also uses - for stdin, so you can write the output of a program to a file on another computer with:
 
./my-cool-prog | ssh data1 "cat - > my-cool-prog.log"

Last edited on
Ok wow, i got it guys!

Really thank you! expecially to @kbw, it was a good explanation!
Thank you.
Registered users can post here. Sign in or register to post.