0

I am trying to unzip bzip file using bash this way

tmp1 = #(bzcat all.tbz)
echo tmp1 | tar x

But this fails with

tar: Unrecognized archive format
tar: Error exit delayed from previous errors.

But if I do this

bzcat all.tbz | tar x

and that works

What is the problem with my earlier way.

Thanks!

Abdul Rahman
  • 1,294
  • 22
  • 41
  • `#` is the comment character. Why are you using that before `(bzcat all.tbz)`? – Barmar Dec 15 '16 at 23:31
  • 1
    You seem to have several misunderstandings of basic shell syntax. You can't have spaces around the `=` in an assignment. You need `$` before a variable. To execute a command and return the output, use `$(command)`, not `#(command)`. – Barmar Dec 15 '16 at 23:32
  • And since the output of `bzcat` contains spaces, you should quote the variable. – Barmar Dec 15 '16 at 23:33
  • Also, the contents of a bzip file contains binary information, which probably includes null bytes. Bash variables can't have null in them, so this won't work.[ – Barmar Dec 15 '16 at 23:34
  • Agreed, it's generally a bad idea to start storing arbitrary binary data in a bag variable. And you wouldn't want it to anyway. Bzip2 is a block compression algorithm I think. Youd want the steam of compressed data to be decompressed on the fly, our you'll eventually run out of RAM when the contents get too big. Makes much more sense to pipe the file in without storing to a variable. – erik258 Dec 15 '16 at 23:53

1 Answers1

2

You have numerous syntax mistakes.

tmp1=$(bzcat all.tbz)
echo "$tmp1" | tar x
  1. Assignments can't have spaces around =.
  2. Use $(...) to execute a command and substitute its output.
  3. Put $ before the variable name when echoing it.
  4. Put " around the variable to prevent word splitting and wildcard expansion of the result.

But this most likely still won't work because tar files contain null bytes, and bash variables can't hold this character (it's the C string terminator).

If you just want to capture the error message if there's a failure, you can do:

tmp1=$((bzcat all.tbz | tar x) 2>&1)
if [ ! -z "$tmp1" ]
then echo "$tmp1"
fi

See Bash script - store stderr in a variable

Community
  • 1
  • 1
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • There's no reason c data can't have null bytes within it, but obviously in that case you're no longer treating it like a string. There's no elegant way to do that in bash, so you'd typically keep such binary data in pipelines or in files. Temp files work well for this too if you can manage to clean them up in every termination path of your program (a PITA in bash) – erik258 Dec 15 '16 at 23:56
  • 1
    @DanFarrell But bash treats variables as C strings, not arbitrary data, so they can't have nulls. – Barmar Dec 16 '16 at 00:01
  • Basically I want to capture error if bzcat fails and return that. is there a way i can do that? – Abdul Rahman Dec 16 '16 at 00:20
  • 1
    @AbdulRahman Error messages go to `stderr`, you're only capturing `stdout`. – Barmar Dec 16 '16 at 01:54
  • @Barmar Would you mind explaning your edited code (the new stuff you put in) as in how it works – Abdul Rahman Dec 16 '16 at 02:28
  • Did you try reading the answers at the linked question? I think they explain it. – Barmar Dec 16 '16 at 02:31
  • yeah. what does if [ ! -z "$tmp1" ] mean – Abdul Rahman Dec 16 '16 at 02:34
  • 1
    It tests if `$tmp` is not empty. This is basic shell scripting. – Barmar Dec 16 '16 at 02:34
  • @Barmar Thanks. I am a noob with shell script – Abdul Rahman Dec 16 '16 at 02:37