cabal替代脚本
由于网络原因,直接使用cabal update不成功,只能自己写脚本直接从网上拖包下来,自己安装。
但是这样做的缺点是需要手动处理dependency,当然,也可以把脚本写的复杂些,自动来处理dependency。
cabal.sh
1 cat<<EOF > .tmp_sed_script 2 s/<\/[^>]*>/&\n/g 3 s/></>\n</g 4 s/a href="\([^"]*\)"/\n[URL: \1 ]\n/g 5 EOF 6 7 home_url="https://hackage.haskell.org" 8 9 item_url=$home_url/"package/"$1 10 11 target_dir="" 12 13 curl $item_url 1> .tmp_page_content 2> /dev/null 14 15 for link in $(sed -f .tmp_sed_script .tmp_page_content | grep URL | awk '{print $2}') 16 do 17 if [[ $link == /*.tar.gz ]] 18 then 19 full_link=$home_url$link 20 echo "wget " $full_link " --no-check-certificate ......" 21 wget $full_link --no-check-certificate 22 archive_file=$(basename $full_link) 23 if [ -f $archive_file ] 24 then 25 tar -xvzf $archive_file 2>&1 > /dev/null 26 fi 27 target_dir=$(tar tzf $archive_file | awk 'NR==1{print}') 28 fi 29 done 30 31 rm .tmp_* 32 rm *.tar.gz* 33 34 cd $target_dir 35 sudo cabal configure 36 sudo cabal install 37 cd ..
不过好像必须要处理dependency了,这样才能真正自动化。
ghc-pkg list | sed -e '/[\/(]/d' | awk 'BEGIN{FS="-"}{print $1}' | sed -e '/Cabal/d' | awk 'NF!=0{print}' | sed 's/ //g' > .installed_pkgs
if [ ! -f .tmp_sed_script ] then cat<<EOF > .tmp_sed_script s/<\/[^>]*>/&\n/g s/></>\n</g s/a href="\([^"]*\)"/\n[URL: \1 ]\n/g EOF fi if [ ! -f .tmp_installed_pkgs ] then ghc-pkg list | sed -e '/[\/(]/d' | awk 'BEGIN{FS="-"}{print $1}' | sed -e '/Cabal/d' | awk 'NF!=0{print}' | sed 's/ //g' > .tmp_installed_pkgs fi home_url="https://hackage.haskell.org" item_url=$home_url/"package/"$1 target_dir="" if [ ! -f $.tmp_page_content_"$1" ] then curl $item_url 1> .tmp_page_content_"$1" 2> /dev/null fi sed -f .tmp_sed_script .tmp_page_content_"$1" | grep "URL: /package/" | sed -e "/$1/d" > .tmp_dependency_"$1" # we should make sure that all the package in .tmp_dependency_XXX file should be installed first than this package # # for dependency in $(cat .tmp_dependency_"$1") do if [[ $dependency == /package/* ]] then #echo $dependency dep=$(echo $dependency | cut -b 10-) b_installed=false for installed in $(cat .tmp_installed_pkgs) do if [[ $installed == $dep ]] then b_installed=true fi done #echo $b_installed " for " $dep if [[ $b_installed == "false" ]] then echo "$1 depends on $dep" echo "$dep" >> .tmp_installed_pkgs bash cabal_ex.sh $dep fi fi done
但是这种以脚本为单位的recursion效率又有点问题,所以最好将其写成一个函数。
home_url="https://hackage.haskell.org" function prepare() { if [ ! -f .tmp_installed_pkgs ] then ghc-pkg list | sed -e '/[\/(]/d' | awk 'BEGIN{FS="-"}{print $1}' | sed -e '/Cabal/d' | awk 'NF!=0{print}' | sed 's/ //g' > .tmp_installed_pkgs fi } function pull_info_page() { # This function will pull info page from web echo "[CABAL_SCRIPT:]Parsing info page for $1 ......" item_url=$home_url/"package/"$1 if [ ! -f .tmp_sed_script_"$1" ] then cat<<EOF > .tmp_sed_script_"$1" s/<\/[^>]*>/&\n/g s/></>\n</g s/a href="\([^"]*\)"/\n[URL: \1 ]\n/g EOF fi if [ ! -f .tmp_page_content_"$1" ] then curl $item_url 1> .tmp_page_content_"$1" 2> /dev/null fi if [ ! -f .tmp_dependency_"$1" ] then sed -f .tmp_sed_script_"$1" .tmp_page_content_"$1" | grep "URL: /package/" | sed -e "/$1/d" > .tmp_dependency_"$1" fi } function calc_dependency() { # This function just calculate the dependency packages of $1 # and append it to the global list echo "[CABAL_SCRIPT:]Resolving dependencies for $1 ......" pull_info_page $1 for dependency in $(cat .tmp_dependency_"$1") do if [[ $dependency == /package/* ]] then #echo $dependency dep=$(echo $dependency | cut -b 10-) b_installed=false for installed in $(cat .tmp_installed_pkgs) do if [[ $installed == $dep ]] then b_installed=true fi done #echo $b_installed " for " $dep if [[ $b_installed == "false" ]] then echo "$1 depends on $dep" echo "$dep" >> .tmp_installed_pkgs #bash cabal_ex.sh $dep install_package $dep fi fi done } function install_package() { # This function just download and install a package $1 # it doesn't care about dependency target_dir="" calc_dependency $1 # Download package for link in $(sed -f .tmp_sed_script_"$1" .tmp_page_content_"$1" | grep URL | awk '{print $2}') do if [[ $link == /*.tar.gz ]] then full_link=$home_url$link archive_file=$(basename $full_link) #target_dir=$(tar tzf $archive_file | awk 'NR==1{print}') target_dir=$(echo $archive_file | sed -re 's/(.*)\.tar\.gz$/\1/g') #echo "target_dir is $target_dir" if [ ! -d $target_dir ] then if [ ! -f $archive_file ] then #echo "wget " $full_link " --no-check-certificate ......" echo "[CABAL_SCRIPT:]Downloading $full_link ......" wget $full_link --no-check-certificate fi if [ -f $archive_file ] then echo "[CABAL_SCRIPT:]Extracting $archive_file ......" tar -xvzf $archive_file 2> /dev/null 1> /dev/null fi fi fi done # rm .tmp_* # rm *.tar.gz* # Install package cd $target_dir echo "[CABAL_SCRIPT:]Installing $1 ......" sudo cabal configure sudo cabal install cd .. } prepare install_package $1 rm .tmp_*
但是仍然有问题,这里没有对dependency的版本做判定,因此仍然失败。