在 shell script 判別發行套件

一般來說,可以用 lsb_release -i ,但是如果沒安裝 lsb-release 的話,就不會有這個指令可以用;uname 只會提供架構、核心版本等資訊;/etc/issues 的話,每個發行套件對這個檔案的內容都不盡相同,難以用規則來解析。

這時候倒是可以利用 /etc/os-release ,我檢查了 Arch Linux、Ubuntu、Raspbian、Debian 幾個發行套件,發現都會有這個檔案。在檔案裡,就有不少資訊可供判別,至少都會有 ID 跟 NAME ,有些則會多了 ID_LIKE 。

  • ID 是標識,以 Ubuntu 為例,ID=ubuntu
  • NAME 是發行套件名稱,以 Ubuntu 為例,NAME=”Ubuntu”
  • ID_LIKE 是描述從哪個發行套件繁衍出來的,以 Ubuntu 為例,ID_LIKE=debian

透過 . /etc/os-release 或 source /etc/os-release ,就可以藉著使用 ID、NAME、ID_LIKE 這些變數來判別發行套件了。

參考自:command line – How to get Ubuntu distribution’s full code name? – Ask Ubuntu

minidlna + rmvb 與 archlinux pkg

minidlna 預設是不找 rmvb 檔案的,網路上有人已經加上 patch (让 minidlna 支持 rmvb、gb2312 mp3 标签) 了,只是那是在 1.0.23 上做修改。現在已經 1.1.4 了,所以我參考了它的 patch,幫 1.1.4 也做了一次。

另外就是第一次在 Arch Linux 上做 package,基本上有 PKGBUILD 檔案就沒啥問題了。minidlna 的 PKGBUILD 可透過 git 下載:git clone git://projects.archlinux.org/svntogit/community.git ,接著就是修改 PKGBUILD,我改了以下項目:

  1. 在 source 添加新檔案,就是新的 patch 檔案
  2. 因為有新檔案,md5sums 也需要用 md5sum 去取得 patch 檔案的校驗碼,然後填到這裡
  3. prepare() 的最後,加上 patch -i $srcdir/999-realmedia-support.patch 。
  4. 改 pkgrel ,這是方便自己辨識用,反正改一個比原來大的數字就可以。

修改完以後,執行 makepkg ,就可以得到 .xz 的檔案,用 pacman -U xxx.xz 就可以安裝了。

後記:重新啟動 minidlna 之後,發現 rmdb 的檔案還是沒有納入。根據 Log 去追程式,才知道 minidlna 是拿之前產生好的 sqlite3 資料庫裡的資料去回應,知道原因之後,就好解決了,試著去 touch 所有的 rmvb 檔案,觸發 minidlna 的 inotify ,這樣 minidlna 就會把這些檔案納入資料庫裡了。Log 的層級可以在 minidlna.conf 裡修改,例如 log_level=general=debug,artwork=info,database,inotify,scanner,metadata,http,ssdp,tivo=warn ,而程式裡輸出 Log 的函式則是 DPRINTF。

BubbleUPnPServer

Server 部份是免費,主要是輔助 app transcoding (轉換格式)用的。
Windows/Linux 都可以安裝,安裝指南:http://bubblesoftapps.com/bubbleupnpserver/

依照指南,有提供 Ubuntu/Arch Linux 以及其他 distro 的安裝方法,在 Arch Linux 下要先裝 ffmpeg,這是用來轉換格式用的。用 yaourt -Ss 搜索 bubbleupnpserver,就可以找到,但結果顯示 out of date ,後來我就沒有用 yaourt 來安裝。
後來直接拿 tarball 來手動安裝,tarball 裡有提供 script 與 jar,這很簡單,Java 跨平台,再搭配 supervisord 就可以在開機時自動啟動。

因為 BubbleUPnPServer 並不是 Media Server,它算是一個 Proxy Server,所以不會跟 minidlna 衝突,但你用 BubbleUPnP app 找網路上 DLNA Server 時,會看到兩個,一台是 BubbleUPnPServer,一台是 MiniDLNA Server。指南裡是說,他可以幫你修正原來 DLNA Server 傳錯的資訊。

BubbleUPnPServer 啟動以後,可以用 Web 進去修改設定,使用的 Port 有兩個:

  • udp 1900
  • TCP 58050 (http), 58051 (https)

License 也是一個 app,在 Google Play 上可以找到,是個需要付費的 app,關鍵字一樣是 BubbleUPnP ,或是用 com.bubblesoft.android.bubbleupnp.unlocker 來找就能找到。

在 Linux 下摹擬 Serial Port

之前試 java rxtx 函式庫時找到的方法,雖然在 Linux 下都是操作檔案,不過檔案跟真的 Serial port 有點差異,後來我是用 socat 指令來摹擬。

socat -d -d pty,raw,echo=1 STDOUT

這行指令會在 /dev/pts 下建立一個 node,假若是 PTY is /dev/pts/7,那麼就 sudo ln -s /dev/pts/7 /dev/ttyS0 ,這樣 /dev/ttyS0 就可以當作 Serial Port 來用了,可以設 baud rate 等等 serial port 特有的參數。接著執行程式,可以在執行 socat 的 console 看到程式寫到 serial port 的訊息。

要對接也是可以的,這時要用:

socat -d -d pty,raw,echo=1 pty,raw,echo=1

這會在 /dev/pts 下建立兩個 node。

備註:

  1. 要用 ln 建 symbolic link 的原因是 rxtx 只檢查 ttyS*, ttySA*, ttyUSB* 資料來源

GitLab 與 Docker

之前就想要裝 GitLab,無奈,裝 GitLab 的相依性實在太多,後來就不了了之。時間飛快,今年年初時,知道了 Docker 這個東西,然後最近想到應該是可以把 GitLab 裝到 Docker 裡,這樣子 GitLab 的環境乾淨,也不會動到原本伺服器上的設定。於是就上網 Google ,果然已經有人做好了 (sameersbn/docker-gitlab),那就不囉唆,立刻來試試看。

網站上的安裝步驟其實已經蠻清楚了,這裡我就紀錄我改的部份。我用 fig 來進行客製化,所以就先下載他的 fig.yml,原本的 fig.yml 裡有三個 container,一個是 gitlab,一個是 postgresql,一個是 redis。我移掉了 postgresql 跟 redis,這邊我改用 host 的 mysql 與 redis,並且設定必要的環境變數。fig 的安裝一定要用 python2 的 pip 來安裝,否則會有問題,目前還沒移植到 python3 上。

要存取 host 的 mysql 與 redis,要注意幾點:

  1. 確定 host 的 mysql 跟 redis 是可以以 port 的方式存取,另外也要允許外部 IP 的連線。mysql 是修改 my.cnf 裡的 [mysqld] section,主要是設定 port ,重新啟動之後應該就可以;至於 redis,則是改 redis.conf 裡的 bind,將其改為 bind 0.0.0.0 ,重新啟動以後就可以。
  2. host 的 IP,在 docker container 裡,照理說是用 gateway 的 IP 就可以。一般都是找到 netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2}' 這指令,但這得在 docker container 裡執行,fig.yml 裡沒辦法指定這個。後來是看到說直接用 host IP 也可以,所以我就直接指定,看起來是沒問題。

等設定好之後,直接 fig up,fig 就會幫你 pull image、建立 image 然後開始執行,第一次執行需要花一點時間。這邊我碰到的怪情況:

  1. docker 有問題,執行有問題,去查看 log ,看到 operation not supported 。查了很久,查不出來什麼問題,後來重開機,居然就沒問題了。事後猜想,可能是因為在 docker run 之前有更新過 kernel,archlinux 更新 kernel 都是使用 replace 的方式,或許是因為這樣而有問題。
  2. 使用預設的帳號跟密碼無法登入,這個得使用 docker exec -it gitlab_gitlab_1 bash 進入 container 裡,執行 sudo -u git -H bash -c “bundle exec rake gitlab:setup RAILS_ENV=production” 以後,就可以解決。

更換 Ubuntu 開機過程的佈景主題

Ubuntu 開機過程其實是可以更換圖片的,甚至已經提供了不少佈景主題可以使用:apt-cache search plymouth-theme

plymouth-theme-ubuntu-logo - graphical boot animation and logger - ubuntu-logo theme
plymouth-theme-ubuntu-text - graphical boot animation and logger - ubuntu-logo theme
mythbuntu-default-settings - default settings for Mythbuntu
plymouth-theme-edubuntu - Plymouth is an application that runs very early
plymouth-theme-fade-in - graphical boot animation and logger - fade-in theme
plymouth-theme-glow - graphical boot animation and logger - glow theme
plymouth-theme-kubuntu-logo - graphical boot animation and logger - kubuntu-logo theme
plymouth-theme-kubuntu-text - graphical boot animation and logger - kubuntu-text theme
plymouth-theme-lubuntu-logo - plymouth theme for Lubuntu
plymouth-theme-lubuntu-text - plymouth text theme for Lubuntu
plymouth-theme-sabily - plymouth theme for Sabily (graphical theme)
plymouth-theme-sabily-text - plymouth theme for Sabily (text theme)
plymouth-theme-script - graphical boot animation and logger - script theme
plymouth-theme-solar - graphical boot animation and logger - solar theme
plymouth-theme-spinfinity - graphical boot animation and logger - spinfinity theme
plymouth-theme-text - graphical boot animation and logger - text theme
plymouth-theme-ubuntu-gnome-logo - graphical boot animation and logger - ubuntu-gnome-logo theme
plymouth-theme-ubuntu-gnome-text - graphical boot animation and logger - ubuntu-gnome-text theme
plymouth-theme-ubuntustudio - Ubuntu Studio Plymouth theme
plymouth-theme-xubuntu-logo - graphical boot animation and logger - xubuntu-logo theme
plymouth-theme-xubuntu-text - graphical boot animation and logger - xubuntu-text theme

你可以使用 apt-get install 來安裝,這些佈景主題會被安裝到 /lib/plymouth/themes/ 目錄下,安裝以後,該如何使用呢? 可以用 update-alternative 來替換,在 terminal 輸入 sudo update-alternative default.plymouth 以後,就可以選擇你喜愛的佈景主題了。

網路上也有人自行去修改 theme,調整字的位置、圖形等等的,用 ubuntu plymouth 去找,就可以找到相關的資訊了。

git 不能加空目錄的變通方法

git 沒辦法加空目錄,沒有任何選項可以用。Stackoverflow (How do I add an empty directory to a Git repository? – Stack Overflow) 上提到的變通方法就是為這些空目錄添加一個空白的檔案,檔名看是要用 .gitignore 或是 README 之類的就可以。

那要找所有空目錄的話,該怎麼找?find 就可以做到這點 (參考 bash – finding empty directories unix – Stack Overflow) :

find . -type d -empty -print

那麼,要為每個空目錄加上空白檔案的話,再利用 -exec 參數就可以了:

find . -type d -empty -exec touch {}/README \;

編譯 gcin (Ubuntu 14.04)

在 Ubuntu 14.04 編譯 gcin,需要安裝這些套件:

  • libgtk-3-dev
  • libgtk2.0-dev
  • libanthy-dev
  • libqt4-dev
  • libqt4-dev-bin
  • qtbase5-private-dev
  • libxtst-dev
  • libappindicator3-dev
  • libchewing3-dev (Optional)
  • qt5-default (Optional)
  • qtchooser (Optional)

gcin 的原始碼可以在這裡取得,在 2.8.2 裡,新酷音的支援被關掉,可以自己修改 configure 來打開設定。qt5-default 跟 qtchooser 是可以不用安裝的,這是 QT5 使用的標頭檔與工具。

docker 小記

最近試著寫 Dockerfile,遇到了一些問題,也順利解決了,所以紀錄在這裡:

  1. 使用 apt-get install 時,會因為某些套件的安裝設定而跳出對話方塊,這會導致安裝被阻塞住。這可以藉著 debconf 來避免:
    ENV DEBIAN_FRONTEND noninteractive
    ENV TERM linux
    RUN echo ‘debconf debconf/frontend select Noninteractive’ | debconf-set-selections
    其中那兩行設置環境變數似乎不起作用的樣子,主要還是第三行。
  2. 找不到 add-apt-repository 指令。這是因為基礎的 image 裡沒有的關係,得使用 apt-get install python-software-properties 來安裝,在 Trusty ,也就是 14.04 裡,得再多安裝 software-properties-common
  3. 用 14.04 時,無法安裝 ia32-libs 。到 13.10 以後,ia32-libs 被移除了,改以 multiarch-support 替代,同時,得用 dpkg 聲明要使用 i386 architecture 才能使用 :i386,例如:
    RUN dpkg –add-architecture i386
    RUN apt-get install multiarch-support gcc-multilib g++-multilib libncurses5-dev:i386
  4. webupd8 的 Java installer 實際上是個安裝的腳本,會詢問是否同意 Oracle 的 license,才開始下載並安裝。同樣,詢問時也會阻塞住,得用下列指令事先回答同意:
    RUN echo oracle-java6-installer shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections
    RUN apt-get install -y oracle-java6-installer
  5. apt-get install 時,都加上 -y 選項以避免詢問。
  6. 不要更動 sources.list,原因是我有試著更換為台灣的替換來源,但卻會出現無法下載某些套件的情況。
  7. 如果是要搭 Android 開發環境,下面是我在 14.04 裡試出來該要裝的套件:
    RUN apt-get install -y build-essential openjdk-7-jdk multiarch-support
    RUN apt-get install -y vim ctags cscope id-utils curl gnupg flex bison gperf zip curl libc6-dev libswitch-perl libncurses5-dev:i386 x11proto-core-dev libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-glx:i386 libgl1-mesa-dev gcc-multilib g++-multilib mingw32 tofrodos dialog python-markdown libxml2-utils xsltproc zlib1g-dev:i386 zlib1g-dev
  8. 清理 container 與 image 的步驟是先刪除 container,再刪除 image。用 docker ps -a -q 可以看 container id,然後用 docker rm 刪除 container,最後再用 docker rmi 去刪除 image,要砍光光,可以這樣用:
    docker ps -a -q | xargs docker rm
    docker images -q | xargs docker rmi
  9. Dockerfile 最後最好是來個 apt-get clean,可以減少 image 空間。
  10. 由於 docker 特性,image 是一層一層疊上去的,只要有指令更動,就會多一層,這有點像 git/svn repository 的概念。在用 docker build 做好 image 以後,你會想只要一個 image 就好,這時候你需要的關鍵字是 flatten 。使用的指令是 export 跟 improt:
    docker export red_panda | docker import – exampleimagelocal:new

關於 Docker push/pull

  1. 首先需要有 server,在安裝上非常簡單,你可以參考這篇 How to use your own Registry,但我發現不用那麼麻煩,有 python virtualenv 在手,可以很快裝好。
    virtualenv docker-registry-env
    cd docker-registry-env
    source bin/activate
    pip install docker-registry
    cp ./lib/python2.7/site-packages/config/config_sample.yml ./lib/python2.7/site-packages/config/config.yml
    打完上面指令就裝完了。啟動的話,接著打 docker-registry 就可以。上傳以後的 image/repository 會放在 /tmp/test ,使用的資料庫是 sqlite3 ,則是放在 /tmp/docker-registry.db。如果要調整位置,可以改 ./lib/python2.7/site-packages/config/config.yml 裡的 sqlalchemy_index_database 與 dev/test/prod 區段的 storage_path 。
  2. push 的方法,就我感覺是有點隱晦。要 push ,得先為 image 加上 tag,例如:
    docker tag 06a3d360b8e2 localhost:5000/myrepo
    docker push localhost:5000/myrepo
  3. pull 的話,就這樣用:
    docker pull localhost:5000/myrepo

資料來源: