2012-07-15 112 views
5

這就是這種情況。我有一個需要提取和設置的URL列表。它的所有變量驅動,但在我解壓後,我不知道我的文件夾將被調用。如果我不知道它叫什麼,我不能將CD放入它。Bash - CD變成不可變目錄的可變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 

如果這不解釋,請說。我真的想要通過這個問題,但我很難解釋它。

因爲我希望它適用於任何可能有兩種格式(如「.tar.gz」或一種格式爲「.zip」)的URL,並且可能具有。的文件名如「Python2.3.4」或可能不是「Nginx」,它使它有點棘手。

+2

順便說一下,前四行不是bash中的有效賦值語句。左側不應以美元符號爲前綴,等號周圍不得有空格。一個更正的例子:'DLDIR =/opt /'。 – chepner 2012-07-15 14:42:43

回答

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

順便說一句,看看/ usr/bin/lesspipe一個好的歸檔檢測案例... esac – 2012-09-22 12:46:42

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

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

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

這是棘手的地方。文件格式不會總是焦油它可能是.zip或.tar.gz – 2012-07-15 11:34:48

+0

我對這個東西真的很陌生,所以你能介意解釋它的功能嗎?我無法繞過它。 – 2012-07-15 12:14:55

+0

非常感謝你 – 2012-07-16 09:29:21

0

如果你知道有將是在$ DL_DIR只有一個目錄,那麼你可以使用:

 
cd `ls -m1` 

另一種方法是循環遍歷文件目錄:

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

您可以根據需要執行文件測試和其他檢查。

+0

好主意,但在這個目錄中會有很多。我們可以根據時間來做嗎?複製最新創建的文件夾的名稱?看起來好像是一種糟糕的做法。 – 2012-07-15 11:37:00

+0

@JamesWillson:在這種情況下,您可以遍歷$ DL_DIR中的文件。看到我編輯的答案。 – 2012-07-15 11:46:39

-1

如何:

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

我會說,用$剝離文件的擴展名{FILE ## *},並使用$使用目錄名左右做其他的方式{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

只有一個小問題:如何知道存檔中的目錄是否與存檔本身具有相同的名稱?

+0

你也可以使用basename作爲這個: 'cd $(basename $ FILE)' – HighKing 2012-09-01 09:44:16