Anaconda3環境構築自動化への道

# はじめに

Anacondaをインストールするお決まりのやり方としては以下のようなものがあると思います。

・[Anaconda](https://www.anaconda.com/distribution/)のサイトでOSに適したインストーラーのリンクを取得
・curlやwgetでサーバーに持ってくる
・実行して環境変数を設定

一回きりならいいんですが、たくさんのサーバーに対して同様にこれをやろうとすると面倒です。今回はそういう事案が発生したので、それを自動化しようと考え、それ用のBashスクリプトを実装しました。初めはPythonのスクレイピングでやろうとしたんですが、2系と3系でいろいろ面倒なことになったので、勉強もかねてBashにしました。前提としては**「Python2しか入っていないサーバー（初期状態）」**を対象にPython3(Anaconda3)をインストールします。

# 環境とかとか

・サーバー： Ubuntu 16.04.6 LTS(Xenial Xerus)
・Bash： 4.3.48(1)-release(x86_64-pc-linux-gnu)
・curl： 7.65.2 または wget： 1.17.1

とにかくLinuxでBashがあれば動きます。curlはあった方がいいので、なかったらsudo apt-get install curlで手に入れます。それでも手に入らない人は気合いで手に入れてください。

# とりあえずコードを晒す

わりと愚直に書いたので結構長くなってしまいました。。。一応[Github](https://github.com/masato-fullmoon/ml_cars/blob/master/install/bash_anaconda3_installer.sh)にあるので興味があればどうぞ。

## 主要部分についての説明

### 変数定義とかとか

自分が使うOSに適したAnacondaをとってきたいので、この段階でOSの種類を変数に格納しておきます。あとでこれとインストーラーURLを参照して、適したインストーラーをcurlかwgetでとってくるように実装してます。あと将来的にはMacとかGit-for-Windowsとかでもできるようにしたいと思ってるので、現状Darwin、Linux、MINGWで条件分岐してあります。Anacondaを展開する場所はホームディレクトリの直下に設定していますが、個々人で任意の場所に設定できます。

またcurlを使ってAnacondaディストリビューションサイトURLからAnaconda3という情報を持ったhrefを取得します。ここからURLを取り出して後はcurl/wgetで簡単にGetできます。

```Bash:def_vars.sh
if [ `uname -s` == 'Darwin' ]; then
    OS='MacOS' # Macにインストールする人
else
    OSTYPENAME=`expr substr $(uname -s) 1 5`

    if [ ${OSTYPENAME} == 'MINGW' ]; then
        OS='Windows' # Git-for-Windowsとかにインストールする人
    elif [ ${OSTYPENAME} == 'Linux' ]; then
        OS='Linux' # 我らがLinuxにインストールする人
    else
        echo 'Unknown os type: Darwin/MINGW/Linux'
        exit
    fi
fi

ANACONDASAVEDIR=~
ANACONDADLURL='https://www.anaconda.com/distribution/'

URLHREFS=`curl "${ANACONDADLURL}" | grep 'Anaconda3' | grep 'href'`
```

### どうやってインストーラーをとってくるか

先程のhrefを変数URLHREFSに格納し、これをfor文でまわしてOSに適したインストーラー情報の取得を試みます。grepを愚直に使用します。

実装の際にインストーラーURLが**「href="<インストーラーURL>"・・・」**のようになっていることが分かったので、単純にダブルクォーテーション部分を取得すれば、URLが手に入ることが分かります。これはsedコマンドを使うと簡単に抽出できるようです。すごいですね。

実装のイメージとしてはPythonのリストにインストーラーURLを再帰的に格納していく感じです。あとでその中身を選択肢として、どれをインストールするかを標準入力でユーザーに決めさせます。それ自動化かよと思う人もいると思います。悪いとは思っています。

```Bash:get_href_url.sh
# 空配列の宣言
declare -a urlarray=()

for href in ${URLHREFS}
do
    if [ `echo "${href}" | grep 'href' | grep "${OS}"` ]; then
        # ダブルクォーテーションの場合で囲まれた部分を抽出
        url=`echo "${href}" | sed 's/^.*"\(.*\)".*$/\1/'`
        # シングルクォーテーションの場合で囲まれた部分を抽出
        #url=`echo "${href}" | sed "s/^.*"\(.*\)".*$/\1/"`
        urlarray=( "${urlarray[@]}" "${url}" )
    fi
done
```

# 動作確認

実行はbash bash_anaconda3_installer.sh、またはchmodで実行権限を付けてから、./bash_anaconda3_installer.shでできます。

実行すると、まずOSに適したインストーラー情報を取得し、どれをcurl/wgetでとってくるかを選べます。以下のスクショでは0と1番目が同じURLになっていますが、1番目が64-bit用のインストーラーらしいです。まどろっこしくて申し訳ないです。。。

ここでは1を選んでおきます。
![anaconda_installer_0001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299965/e1126b79-0401-6995-d080-da2a813341eb.jpeg)
インストーラーの取得は完了したようです。ちなみに取得する際にサーバーにwgetがあればそれを使うようにしています。特に意味はありません。これも勉強なので。

取得完了後はそのインストーラーを起動してAnacondaをインストールするかどうかを選べます。よくある部分です。また小ネタですが、ここではwhileを使用して適した文字(yes/no)が入力されるまでは同じメッセージが出力されるようにしています。ちょっとこだわりですw。

yesを入力すると、Linux版のAnacondaインストーラーメッセージが続きます。なのでここについては省略します。
![anaconda_installer_0002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299965/8ef50108-fd4f-3570-b6b1-d722f298cca8.jpeg)
最後にシアン色の文字で"Anaconda3 Installation Acomplished."と出力されればインストール完了です。お疲れ様でした。

# 現状の課題

Anacondaインストール中に以下のようなメッセージが表示され、yes/noの入力を求められます。
![anaconda_installer_0003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299965/f29fb194-a0fd-6020-6309-1ccd595739da.jpeg)
簡単に言うと、conda initを有効にするために.bashrcに環境変数の設定をするかどうかというものです。ここでyesを入力すると、以下のようにホームディレクトリ直下にある.bashrcに環境変数が自動的に書き込まれます。
![anaconda_installer_0004.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299965/ab1161ff-9f4a-b894-ffbc-a9ecd18f2279.jpeg)
自分の場合、サーバーごとに.bashrcの設定を分けている点、環境変数系は.bash_profileに書くという点でこれは面倒です。

現状はconda initの箇所はnoを選択し、環境変数は.bash_profileに手打ちするという感じになっています。まだまだ自動化までは程遠い感じです。。。今後はその部分も含め、完全な自動化ができるよう実装していく予定です。

# 最後に

今まではGo言語やPythonでスクレイピングをやってきましたが、シェルスクリプトの方が自分の用途に合った処理を記述しやすい感じがありました。これを機にもう少し勉強してみます(笑)