Bash
Zsh
Mac
samba
NAS

シェルスクリプトでNASからローカルにファイルをDLする(Macで)

デザイナー『これ、組み込みお願いします』

そう言われて、素材を確認しようとしたらNAS上に置いてあったなんてことはないだろうか(いや、よくある)。

NASにいちいち接続して確認するのがめんどくさい、欲を言えば自動でローカルのリポジトリ上のしかるべきところに配置までしてもらいたい…。

MacならNASに接続するためのmountコマンドが使えます。
そして、NASに接続するためのパスワードなどもシェルスクリプトでKeyChainから呼び出せます。

ということは…。

というわけでシェルスクリプト化

nasFileTransfer.sh
#!/bin/bash
set -u

# [使用例]
# ./nasFileTransfer.sh smb://path/to/file/on/nas /tmp

# NASマウント時の一時ディレクトリ名
# ${VOLUMES_DIR}/${TMP_NAS_DIR_NAME}の形式で使われる
readonly VOLUMES_DIR="/Volumes"
readonly TMP_NAS_DIR_NAME="tmpNASMount"
readonly NAS_HOST_NAME="nas.aaabbbccc.private" # nasのホスト名

function echoUsage () {
    echo "$0 <nas_path> <download_dir>"
}

# NASのpath指定
if [ -n "$1" ]; then
    # 日本語の部分だけURLエンコードしてくれるワンライナー
    # FYI: https://hydrocul.github.io/wiki/others/oneliner.html#urlencode-urldecode
    NAS_PATH=`echo ${1} | sed -E 's/^smb:\/\///g' | perl -nlpe 's/([^ -~])/"%".unpack("H2",$1)/eg'`
else
    echoUsage
    exit 1
fi

# ダウンロード先指定
if [ -n "$2" ]; then
    DOWNLOAD_DIR=$2
else
    echoUsage
    exit 1
fi

# Finderなどで開いていて同じNASの階層をマウント済みならアンマウント
MOUNTED_NAS_INFO=`df | grep -i $NAS_PATH | awk '{print $9}'`
if [ "$MOUNTED_NAS_INFO" != "" ]; then
    umount "${MOUNTED_NAS_INFO}"
fi

# このスクリプトで${VOLUMES_DIR}/${TMP_NAS_DIR_NAME}をマウント済みならアンマウント
df | grep "${VOLUMES_DIR}/${TMP_NAS_DIR_NAME}"
if [ "$?" -eq 0 ]; then
    umount  "${VOLUMES_DIR}/${TMP_NAS_DIR_NAME}"
fi

# ReadOnlyでボリュームマウント
# キーチェーンへアカウント名とパスワードを参照
NAS_CONNECT_USER=$(security find-internet-password -s ${NAS_HOST_NAME} | grep acct | sed -E 's/[ \f\n\r\t]+"acct"<blob>="(.+)"/\1/g')
mount -t smbfs -r //${NAS_CONNECT_USER}:"$(security find-internet-password -ws ${NAS_HOST_NAME})"@${NAS_PATH} ${VOLUMES_DIR}/${TMP_NAS_DIR_NAME}

case $? in
    0 | 1 ) ;;
    * ) 
        rmdir ${VOLUMES_DIR}/${TMP_NAS_DIR_NAME}
        echo 'NAS server connection failed.'
        exit 1 ;;
esac

# 画像ファイルコピー
# psdやaiなどの重めのファイルなどがもし入っていた時のためにここで除外指定します
# 隠しファイルなども除外
find ${VOLUMES_DIR}/${TMP_NAS_DIR_NAME} -maxdepth 1 -mindepth 1 ! -name "*.psd" ! -name "*.ai" ! -name ".*" | xargs -J% cp -v -a % ${DOWNLOAD_DIR}

# umount
umount ${VOLUMES_DIR}/${TMP_NAS_DIR_NAME}

使い方

初めて接続するNASには一回Finderで開いてKeyChainにパスワードなど覚えさせときましょう。

$ # nasFileTransfer.shという名前で保存したとして
$ # 実行権限付与
$ chmod +x nasFileTransfer.sh

$ ./nasFileTransfer.sh smb://path/to/file/on/nas /tmp/mynasdlfolder

で、NASのsmb://path/to/file/on/nas以下のファイルを/tmp/mynasdlfolderに展開してくれます。
(PATHは適宜書き換えて下さい)

そして、スクリプト冒頭のperlのワンライナーで日本語混じっててもいけちゃいます。

$ # 日本語が混じっててもいけちゃう
$ ./nasFileTransfer.sh smb://path/to/日本語の/ファイルの/ありか /tmp/mynasdlfolder

自動でNASのファイルを配置までさせたい場合は、このシェルスクリプトをラップさせるように、別のシェルスクリプトから叩かせると、いろんなシェルスクリプトから扱いやすいです。

おまけ

シェルスクリプトで画像の確認しながら配置させたいという場合には、そのラップさせたシェルスクリプト上でqlmanageコマンド(Macだけ利用可)で画像のQuickLookを開かせたりすると更に良いです。

qlmanage -p path/to/image.png >& /dev/null