2

I've started using the bash script below, for unpacking archives. How would I go about making the script ask if I would like to specify a folder, or just use the default folder to extract to?

I'd like to be able to run the archive script, and get a prompt saying:

"Extract to default folder Y, or N, instead specify folder (enter folder). Any help appreciated :)

Excerpt from .bashrc

extract () {
if [ -f $1 ] ; then
  case $1 in
    *.tar.bz2)   tar xjf $1     ;;
    *.tar.gz)    tar xzf $1     ;;
    *.bz2)       bunzip2 $1     ;;
    *.rar)       unrar e $1     ;;
    *.gz)        gunzip $1      ;;
    *.tar)       tar xf $1      ;;
    *.tbz2)      tar xjf $1     ;;
    *.tgz)       tar xzf $1     ;;
    *.zip)       unzip $1       ;;
    *.Z)         uncompress $1  ;;
    *.7z)        7z x $1        ;;
    *)     echo "'$1' cannot be extracted via extract()" ;;
     esac
 else
     echo "'$1' is not a valid file"
 fi
}
  • 2
    In general what you're asking is difficult, since not all the tools incorporate this feature. For them, you'll have to extract someplace and then copy over. – muru Aug 30 '14 at 6:35
  • @muru Why? Who forbids you to change working directory? – Dmitry Alexandrov Aug 30 '14 at 19:07
1

As for your code:

  • Do not put error messages to STDOUT, there is STDERR for them.
  • Do not forget to enclose filenames (and veriables in general) in quotes. tar xjf $1 would not work if $1 contains spaces.
  • gunzip and bunzip2 without -k (--keep) option delete compressed file after decomressing. Are you sure you want it?
  • GNU tar can detect compression format by its own, just do not force it: $ tar xf "$1". But let it be as you wish.

As for the task, I would not implement it as a function in .bashrc but as a script. So it may look like that, I think:

#!/bin/bash

# config
DEFAULT_TARGET="."

SCRIPTNAME="${0##*/}"

err() {
    printf >&2 "$SCRIPTNAME: $*\n"
    exit 1
}

ARC="$1"
[[ -f $ARC ]] || err $"'$ARC' does not exist"
ARC="$(readlink -f "$ARC")"

read -p "Extract to [default: $DEFAULT_TARGET]: " TARGET
[[ -z $TARGET ]] &&\
    TARGET="$DEFAULT_TARGET"
[[ -d $TARGET ]] || err $"Directory '$TARGET' does not exist"
[[ -w $TARGET ]] || err $"Permission denied: '$TARGET' is not writable"

cd "$TARGET"
case "$ARC" in
    *.tar.bz2)   tar xjf "$ARC"     ;;
    *.tar.gz)    tar xzf "$ARC"     ;;
    *.bz2)       bunzip2 "$ARC"     ;;
    *.rar)       unrar e "$ARC"     ;;
    *.gz)        gunzip "$ARC"      ;;
    *.tar)       tar xf "$ARC"      ;;
    *.tbz2)      tar xjf "$ARC"     ;;
    *.tgz)       tar xzf "$ARC"     ;;
    *.zip)       unzip "$ARC"       ;;
    *.Z)         uncompress "$ARC"  ;;
    *.7z)        7z x "$ARC"        ;;
    *)           echo "'$ARC' cannot be extracted by $SCRIPTNAME" ;;
esac

Do you need any comments?

| improve this answer | |
  • -f $ARC => -f "$ARC" same with $TARGET several places. – Hannu Aug 30 '14 at 19:25
  • @Hannu Where? In readlink -f "$ARC" it was already quoted. Inside [[]] quotes are superfluous, unless $ is on the right side of ==. – Dmitry Alexandrov Aug 30 '14 at 19:28
  • Well it is inside [[]] - the line after read -p ... - I'd add them still just because of making it be "a good habit". Relying on esoteric "don't need it here" is prone to break things sooner or later. – Hannu Aug 30 '14 at 19:32
  • @Hannu Nothing esoteric here, that’s a syntax of language. But, yes, it would break things sooner or later, if one would put quotes automatically around any $var. E. g. when one would put it inside (()). – Dmitry Alexandrov Aug 30 '14 at 19:39
  • ;-) E. g. when one would put it inside (()) made me curious, wouldn't that depend on how you use quotes rather that automatically breaking it? I currently believe that I need the quotes everywhere; do I have reason to reconsider it? Please point me to an example. Or is that implying due to quoting numbers? – Hannu Aug 30 '14 at 19:53

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.