7

I was trying out tar command to make archive with .tar extension.

please have a look at the following series of commands I tried:

$ ls
abc.jpg  hello.jpg  xjf.jpg
$ tar -cfv test.tar *.jpg
tar: test.tar: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors
$ ls
abc.jpg  hello.jpg  v  xjf.jpg
$ rm v
$ ls
abc.jpg  hello.jpg  xjf.jpg
$ tar -cvf test.tar *.jpg
abc.jpg
hello.jpg
xjf.jpg
$ ls
abc.jpg  hello.jpg  test.tar  xjf.jpg

why it gives different response with different sequence of options ? i.e -cfv vs cvf.
from what I have learnt in bash scripting that option sequence does not matter.

  • Note that it's only true of some tar implementations (not the one in Solaris for instance). – Stéphane Chazelas Mar 3 '15 at 10:00
  • 2
    In general, the order of options matters to commands, especially if some of the options take values. GNU blurs this to some extent unless you have POSIXLY_CORRECT set in the environment by reordering options before non-options. Generally, though, options precede non-options and order matters. Order does not always matter, but it often (or is that just 'sometimes'?) matters. – Jonathan Leffler Mar 3 '15 at 13:01
  • @JonathanLeffler - generally sometimes. – mikeserv Mar 3 '15 at 13:10
11

As @jcbermu said, for most programs and in most cases, the order of command line flags is not important. However, some flags expect a value. Specifically, tar's -f flag is:

  -f, --file ARCHIVE
       use archive file or device ARCHIVE

So, tar expects -f to have a value and that value will be the name of the tarfile it creates. For example, to add all .jpg files to an archive called foo.tar, you would run

tar -f foo.tar *jpg

What you were running was

tar -cfv test.tar *.jpg

tar understands that as "create (-c) an archive called v (-fv), containing files test.tar and any ending in .jpg.

When you run tar -cvf test.tar *.jpg on the other hand, it takes test.tar as the name of the archive and *jpg as the list of files.

  • 1
    Just to be exact: -c actually stands for create, not compress. Nice answer, anyway. – Erathiel Mar 2 '15 at 16:52
  • 1
    Actually, GNU tar processes its command-line arguments like a script - and so their order of appearance is very important generally. If they were processed at random, it would make stuff like --checkpoint scripts or multivolume archives a chore, and even simple stuff like: set file[1234]; for f do shift; set -- "$@" "-C$PWD/dir${f#file}" -x "$f"; done; tar -c . | tar "$@" wouldn't work. – mikeserv Mar 2 '15 at 20:08
  • Your edit is better, but still misses the mark, I think: The order of different options relative to one another should not matter, unless the options are documented as mutually-exclusive and such an option is documented to override any incompatible options preceding it. If an option that has option-arguments is repeated, the option and option-argument combinations should be interpreted in the order specified on the command line. Basically, as soon as one option might affect the operation of another, the order matters. Common examples moght include the -[if] options to mv and/or rm. – mikeserv Mar 3 '15 at 12:44
  • And, of course, the order in which the -- flag appears on a command line relative to others is probably always going to matter a great deal. – mikeserv Mar 3 '15 at 12:45
  • @mikeserv for heaven's sake, read what I say: "for most programs and in most cases, the order of command line flags is not important". – terdon Mar 3 '15 at 12:46
9

The order doesn't matter as long as the option doesn't need a value. In your case -f needs to specify a filename.

In the first case (tar -cfv) the command believes that the output filenames is v because is after -f.

  • 1
    And you get the error message you do because it's trying to add test.tar to the archive. – Mark Mar 2 '15 at 22:56
  • @Mark ... test.tar, which does not exist yet at the time the command is typed hence the message «No such file or directory». Just being pedant ;-) . – user86969 Mar 3 '15 at 13:04
5

While others have pointed out that it treated it as -c -f v, I feel I should note that this is only done because the dash was used, and this behavior does not apply to all versions of tar. In legacy mode (no dash), tar treats the first argument specially, and a "f" or "b" within it will consume the next full words after the options (so tar cfb file.tar 20 or tar cbf 20 file.tar). For GNU tar, you can find more details in the full Texinfo documentation by running info tar styles.

In general, you should not rely on either behavior, and always specify f as the last option and put a space between it and the filename. (-b is only important in some situations when writing to physical tape drives, so it can be ignored for this discussion.)

  • Note that the same applies to sh (and possibly other pre-getopt tools). sh -cf noglob 'echo test' works like sh -f -c 'echo test' in the Bourne shell and derivatives (and sh -ocC noglob 'echo test' like sh -o noblob -C -c 'echo test' in most Bourne derivatives). Also note that in some traditional tar, implementations, tar -cfv is the same as tar -cvf. – Stéphane Chazelas Mar 3 '15 at 9:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.