6

I want to get the last 10 lines of multiple files. I know they all end with "-access_log". So I tried:

 tail -10 *-access_log 

But this gives me an error, where as:

tail -10 file-*

Gives me the output I'd expect. I would think this probably has more to do with BASH then tail. However commands like:

cat *-access_log

Work fine.

Any suggestions?

7

I believe you would want:

tail -n 10 *-access.log

As to why:
I don't think it has anything to do with globbing:

tail -10 foo-access.log arf-access.log 
tail: option used in invalid context -- 1

I think it just so happens that your glob expands to one file. It probably has something to do with some archaic options parsing that I am too lazy to try to read, but if you really want to know go look in tail.c in the coreutils source and dissect the following function:

parse_obsolete_option (int argc, char * const *argv, uintmax_t *n_units)
  • or tail -n 10 *-access.log thanks for super fast reply!! – Mitch Apr 30 '10 at 17:22
  • Ya, really you don't even need the 10 because that is the default. – Kyle Brandt Apr 30 '10 at 17:25
  • fyi, it seems it has to do with globbing (please read my answer) – Ring Ø Apr 7 '13 at 10:26
5

While a bit old, the question is still relevant. I met a similar problem

ssh myserver.com 'tail -2 file-header*'

that gave me the error

tail: option used in invalid context -- 2

however, tailing only one file, like

ssh myserver.com 'tail -2 file-header-file-one'

works fine. Looking at the source tail.c shows that tail starts by parsing obsolete options, then parse the rest (i.e. options not processed yet), regular options. However, parse_obsolete_option() expects an "obsolete" usage, with only one file as argument.
So when providing more files, the function returns immediately, and let the regular parser to choke on -2 (expecting -n 2).

  /* With the obsolete form, there is one option string and at most
     one file argument.  Watch out for "-" and "--", though.  */
  if (! (argc == 2
         || (argc == 3 && ! (argv[2][0] == '-' && argv[2][1]))
         || (3 <= argc && argc <= 4 && STREQ (argv[2], "--"))))
    return false;

In conclusion, it is better to always use the -n regular form, knowing that the "obsolete" code only accepts one file.

  • 2
    Love that you dug into the source and found the root cause of this problem! But yeah, in conclusion, use -n 2 instead of -2 when there are wild cards. – ADTC Jul 30 '15 at 5:44

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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