3

I had three RAR files in the same directory: file1.rar, file2.rar and file3.rar. I wanted to extract them with one command using expansion, bearing in mind that asterisks have to be escaped in arguments for unrar, unzip, 7z, etc.

I tried this command:

unrar x file\*rar

It resulted in:

UNRAR 5.00 beta 8 freeware      Copyright (c) 1993-2013 Alexander Roshal

No files to extract

However, this command worked:

unrar x file\*

And this command works:

ls file*rar

It results in:

file1.rar file2.rar file3.rar

So why doesn't the first command work?

2
  • 3
    The asterisk is actually preventing shell expansion, passing the unexpanded string to unrar. So your question is actually why unrar doesn't handle that pattern.
    – derobert
    Commented May 13, 2015 at 19:38
  • Good point. I'll change the question.
    – EmmaV
    Commented May 13, 2015 at 19:40

3 Answers 3

4
unrar x '*.rar' 

this works for me, I had the same issue.

if I omitt the ' unrar will try to add all the files on the same command line

ex : I have 1.rar 2.rar 3.rar if I do

unrar x *.rar

the command pass to linux will be

unrar x 1.rar  2.rar 3.rar 

and result in an error but if I use the ' like this

unrar x '*.rar' 

the command passed will be

unrar x 1.rar
unrar x 2.rar
.......
3

It doesn't work in 5.2.7 (newer version) either. I'd suggest trying unrar x file\*.rar, note the dot before rar. That goes down a slightly different code path, at least in 5.2.7, and it works in 5.2.7.

Why? Well, after a few minutes of looking through unrar's source (take a look at match.cpp if you want to try!), I can comfortably say "because Alexander Roshal really, really, reallly should have used glob(3) instead". Why didn't he? Probably because its not available on Windows, where AFAIK rar originates.

On Windows extensions are special, and it seems the unrar code treats it as sort-of-not-really part of the filename—a plain, final trailing * will match one, but a * in the middle will not. Not sure if this is expected behavior on Windows, but its surely not on Unix.


Workaround

The sane way to deal with brokenness like this is probably something like:

for f in file*rar; do
    unrar x "$f"
done

Let the shell expand the glob and give unrar one file at a time. Just hope none of your files have * in their names...


I at first said it worked in 5.2.7, that was mistaken: I lost the backslash while testing…

1

When you enter unrar x file\*rar, the unrar program receives the literal string file*rar. It's probably easier to just enter unrar x file*rar, which will cause your shell to expand the pattern (unrar will receive the list of files that match the pattern).

Now, how come unrar x file\*rar doesn't work while e.g. unrar x file\*.rar does? My guess would be that unrar includes its own code to do pattern expansion, to run on systems where the shell doesn't do it, and the rules are not the same as on Unix. If I remember correctly, that would match the rules on MS-DOS, where *rar will not match files with names that end in .rar.

3
  • 2
    file*rar doesn't work. unrar takes the first file argument as the archive, then the rest as (I'd guess) which files to extract from the archive—not as additional archives to extract.
    – derobert
    Commented May 13, 2015 at 20:17
  • @derobert: My (admittedly old) version of unrar in fact appears to handle all arguments to x as rar archives. I wrote that unrar x file\*.rar works (note the dot, it definitely doesn't work without it).
    – dhag
    Commented May 13, 2015 at 20:21
  • Ah, nice to know different unrar versions behave differently. (You may also have the very ancient free version of unrar, that could be quite different. After all, someone may have patched it to behave sanely, unlike the non-free version...)
    – derobert
    Commented May 13, 2015 at 20:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .