2012-07-15 9 views
5

Tak wygląda sytuacja. Mam listę adresów URL, które muszę wyodrębnić i skonfigurować. Wszystko jest zmienne, ale po wyodrębnieniu nie wiem, jaki będzie mój folder. Nie mogę włożyć do tego CD, jeśli nie wiem, jak się nazywa.Bash - CD do katalogu Untared ze zmienną URL

$DL_DIR = /opt/ 
$URL = http://nginx.org/download/nginx-1.3.3.tar.gz 
$FILE=${URL##*/} 
$CONFIG = "-- core" 

cd "$DL_DIR" 
wget $URL 
tar xzf $FILE 
cd <HOW DO I GO INTO IT?> 
./configure "$CONFIG" 
make 
make install 
rm $FILE 

Jeśli to nie wyjaśni, proszę powiedz. Naprawdę chcę ominąć ten problem, ale mam trudności z wytłumaczeniem tego.

Ponieważ chcę, aby to działało dla każdego zestawu adresów URL, które mogą mieć dwa formaty, takie jak ".tar.gz" lub jeden format ".zip" i mogą mieć .s w nazwie pliku, np. "Python2.3.4" lub może nie "Nginx", to sprawia, że ​​jest to trochę trudne.

+2

Na marginesie, pierwsze cztery wiersze nie są poprawnymi przypisaniami w bashu. Lewa strona nie powinna być poprzedzona znakami dolara i nie ma miejsca wokół znaku równości. Poprawiony przykład: 'DLDIR =/opt /'. – chepner

Odpowiedz

1
#! /bin/bash 
    # 
    # Problem: 
    # find the path of the "root" folder in an archive 
    # 
    # Strategy: 
    # list all folders in the archive. 
    # sort the list to make sure the shortest path is at the top. 
    # print the first line 
    # 
    # Weak point: 
    # assumes that tar tf and unzip -l will list files in a certain way 
    # that is: paths ending with/and that the file-list of unzip -l 
    # is in the fourth column. 
    # 

    LIST_FILES= 
    FILE=$1 
    case ${FILE##*.} in 
     gz) 
     LIST_FILES="tar tf $FILE" 
     ;; 
     tgz) 
     LIST_FILES="tar tf $FILE" 
     ;; 
     zip) 
     LIST_FILES='unzip -l '$FILE' | awk "{print \$4}"' 
     ;; 
    esac 
    ARCHIVE_ROOT=$(
    echo $LIST_FILES | sh |\ 
     grep '/$'|\ 
     sort |\ 
     head -n1 
    ) 

    # we should have what we need by now, go ahead and extract the files. 
    if [ -d "$ARCHIVE_ROOT" ]; then 
     cd "$ARCHIVE_ROOT" 
    else 
     # there is no path (whoever made the archive is a jerk) 
     # ...or the script failed (see weak points) 
     exit 1 
    fi 
+0

btw, spójrz na/usr/bin/lesspipe, aby uzyskać dobre rozpoznanie archiwum ... esac –

0
extract_dir=$(tar -tf $FILE | cut -d/ -f1 | uniq) 
cd $extract_dir 

lub

extract_dir=$(tar -tf $FILE | head -1 | cut -d/ -f1) 
cd $extract_dir 

lub

ls > .dir_list_1 # save current directory listing as hidden file 
tar xzf $FILE  # extract the $FILE 
ls > .dir_list_2 # save the directory listing after extraction... 
        # ...as another hidden file 
# diff two lists saved in hidden files, this will help you get the created dir 
# grep '>' symbol, to get the inserted line 
# use head to get the dir in case there are multiple lines (not necessary) 
# use cut to remove the '>' and get the actual dir name, store in extract_dir 
extract_dir=$(diff .dir_list_1 .dir_list_2 | grep '>' | head -1 | cut -d' ' -f2) 
# remove temporary files 
rm .dir_list_* 
cd $extract_dir 
+0

Tutaj jest to trudne. Format pliku nie zawsze będzie miał wartość tar, może być .zip lub .tar.gz –

+0

Jestem naprawdę nowy w tej dziedzinie, więc czy mógłbyś wyjaśnić, jak to działa? Nie mogę tego objąć. –

+0

Bardzo dziękuję –

0

Jeśli wiesz, że nie będzie dokładnie jeden katalog w $ DL_DIR, wówczas można użyć:

 
cd `ls -m1` 

Innym podejściem byłoby przechodzenie między plikami pliku katalog:

 
for filename in "$DL_DIR"/* 
do 
    echo $filename 
done; 

Można wykonać testy plików oraz inne kontrole, jak to konieczne.

+0

Dobry pomysł, ale w tym katalogu będzie sporo. Czy możemy to zrobić na podstawie czasu? Skopiuj nazwę najnowszego utworzonego folderu? Wydaje się jednak, że to zły sposób. –

+0

@JamesWillson: W takim przypadku można przechwytywać pliki w $ DL_DIR. Zobacz moją zredagowaną odpowiedź. –

-1

Jak o tym:

rm -rf tmpdir 
mkdir tmpdir && cd tmpdir || exit 
wget "$URL" || exit 1 
case "$(ls)" in 
    *.tar.gz|*.tgz) 
    tar xzf $(ls) 
    ;; 
    *.zip) 
    unzip $(ls) 
    ;; 
esac 
for d in $(ls -d) 
do 
    (cd "$d" 2>/dev/null && ./configure && make && make install;) 
done 
0

Powiedziałbym, rozebrać rozszerzenie pliku z $ {.} * FILE ## i zrobić na odwrót z nazwą katalogu przy użyciu $ {FILE% .ext *}:

case ${FILE##*.} in 
    gz) 
    tar xf $FILE 
    cd ${FILE%.tar.gz*} 
    ;; 
    tgz) 
    tar xf $FILE 
    cd ${FILE%.tgz*} 
    ;; 
    zip) 
    unzip $FILE 
    cd ${FILE%.zip*} 
    ;; 
esac

Tylko jeden mały problem: skąd wiesz, jeśli katalog w archiwum ma taką samą nazwę af samego archiwum?

+0

Do tego można również użyć systemu podstawowego: 'cd $ (basename $ FILE)' – HighKing

Powiązane problemy