ラベル bash の投稿を表示しています。 すべての投稿を表示
ラベル bash の投稿を表示しています。 すべての投稿を表示

2013-05-10

indented-text handling by using echo and here-document of bash on os x lion

KeyRemap4MacBookの調整の時に、動的に替わるxmlや複雑なxmlを作る事が多くなって来た。一般に、xmlが多量になるとインデント(indent)を確実にしないと、見通しが極度に低下する。更にKeyRemap4MacBookの特殊性として、「<autogen>タブ階層構造」と「<item>タブの階層構造」とが別々に意味を持つので、正しくインデントの必要性が高まって来た。

これらの「インデントされたテキスト(indented text)」を生成するときには、エスケープ・シークエンス(escape sequences)による出力 ;
  • 「エスケープ・シークエンスのオプションの付いたエコー・コマンド」
    • echo -e "\tHoge.$JJJ hoge\n"
を使っていた。しかし、量が増えて来たり、変数(variable, $JJJ)が入ってくると、作り間違えが急造して、修正が大変になってしまう。

そこで、不得意な「ヒア・ドキュメント(here document)」を使った具体例、echo_and_here-documentを作製したので、以下に説明する。なお、変数(variable, $JJJ)の処理は最後に触れます。

u1@mmX75:~/bin $ cat echo_and_here-document
#!/bin/bash

ex5() {

# EXAMPLE 5: basic "here document" wrapped in function, ex5    ###########
JJJ=$((JJJ+1))
cat <<EOF

<!-- EXAMPLE $JJJ: basic "here document" wrapped in function, ex5 -->
    <abc>
        efg, hij
    </abc>
   
EOF

}

################ Main ####################################################
echo  "$(basename $0): start"


# EXAMPLE 1: direct "echo with -e option" ################################
JJJ=1
echo -e "\n<!-- EXAMPLE $JJJ: simple \"echo with -e option\"\c"
echo -e " -->\n\t<abc>\n\t\tefg, hij\n\t</abc>"

# EXAMPLE 2: basic "here document" #######################################
JJJ=$((JJJ+1))
cat <<EOF

<!-- EXAMPLE $JJJ: basic "here document" -->
    <abc>
        efg, hij
    </abc>
   
EOF

# EXAMPLE 3: command substitution includes "here document" ###############
JJJ=$((JJJ+1))
ex3="$(
cat <<EOF

<!-- EXAMPLE $JJJ: "here document" included
                 by "command substitution:\$(...)"
                 and saved to variable, \$ex3.-->
    <abc>
        efg, hij
    </abc>
   
EOF
)"
echo "$ex3"

# EXAMPLE 4: basic "here document" redirect file, ex4. ###################
JJJ=$((JJJ+1))
cat <<EOF > ex4

<!-- EXAMPLE $JJJ: basic "here document" redirects to file, ex4 -->
    <abc>
        efg, hij
    </abc>
   
EOF
cat ex4
rm -f ex4

# EXAMPLE 5: basic "here document" redirect file in function ex5. ########
ex5 # just call function, ex5


# EXAMPLE 6: basic "here document" redirect file
#                 in external function ex6 at myUtuities ########
. myUtilities
ex6 # just call function, ex6

echo ""
echo "============= myUtilities ====================="
cat $HOME/bin/myUtilities | sed -e "s/^/contents: /"
echo "==============================================="

################ Main ####################################################
u1@mmX75:~/bin $


この実行結果は;

u1@mmX75:~ $ echo_and_here-document
echo_and_here-document: start

<!-- EXAMPLE 1: simple "echo with -e option" -->
    <abc>
        efg, hij
    </abc>

<!-- EXAMPLE 2: basic "here document" -->
    <abc>
        efg, hij
    </abc>
   

<!-- EXAMPLE 3: "here document" included
                 by "command substitution:$(...)"
                 and saved to variable, $ex3.-->
    <abc>
        efg, hij
    </abc>
   

<!-- EXAMPLE 4: basic "here document" redirects to file, ex4 -->
    <abc>
        efg, hij
    </abc>
   

<!-- EXAMPLE 5: basic "here document" wrapped in function, ex5 -->
    <abc>
        efg, hij
    </abc>
   

<!--
    EXAMPLE 6: basic "here document" wrapped
    in function, ex6() at external file, myUtilities
-->   
    <abc>
        efg, hij
    </abc>
   

============= myUtilities =====================
contents: #!/bin/bash
contents:
contents: ex6(){
contents:
contents: # EXAMPLE 6: basic "here document" wrapped in function, ex6 at myUtulities    ###########
contents: JJJ=$((JJJ+1))
contents: cat <<EOF
contents:
contents: <!--
contents:     EXAMPLE $JJJ: basic "here document" wrapped
contents:     in function, ex$JJJ() at external file, myUtilities
contents: -->   
contents:     <abc>
contents:         efg, hij
contents:     </abc>
contents:    
contents: EOF
contents: }
===============================================
echo_and_here-document: end
u1@mmX75:~ $

使った感想としては、利用目的に応じて;
  • 超簡単なら、EXAMPLE1
  • 簡単なら、EXAMPLE2
  • 繰り返しの利用なら、EXAMPLE3
  • ファイルとして保存なら、EXAMPLE4
  • 開発途中のファイルなら関数が使いよいかも、 EXAMPLE5
  • 開発が終わって、共通なユーティリティ・ファイルにするのもよい、EXAMPLE6
といった感じです。KeyRemap4MacBook関係では、圧倒的にEXAMPLE5らしそうです。

最後に変数(variable, $JJJ)の定義と演算ですが;
  • 数値代入:JJJ=5
  • 数値演算:KKK=$((JJJ*2))
実例;

u1@mmX75:~ $ JJJ=5
u1@mmX75:~ $ KKK=$((JJJ*2))
u1@mmX75:~ $ echo -e "\tJJJ=$JJJ, KKK=JJJ*2=$KKK"
    JJJ=5, KKK=JJJ*2=10
u1@mmX75:~ $

感想
  •  自信を持って、明確にヒア・ドキュメントを使えるようになった。
  • 「echo -e」の解説; 下記の本の「p71,72」が簡明で、その様に動作した。
    • Arnold Robbins, "bash Pocket Reference", O'REILLY, 2010
    •  ISBN: 978-1-449-38788-4 
  • 動作環境
    • Mac mini (mid 2011), Lion 10.7.5
    • bash --version
      • GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin11)
____
この記事の履歴
  1. 開始 2013-05-10(金) 14:57:11 
  2. 修正 2013-05-12(日) 02:30:18 
  3. 追加 2013-05-13(月) 17:11:01 EXAMPLE6

2013-04-07

スクリーンショット、tiffからpngへ変換

最近、「Excel for Mac 2011」で作成した大きい表を幾つも画像にして、ブラウザで見る事が多くなった。初めの頃は「⇧•⌘•4」のショートカットで大雑把に切り出していた。慣れるに連れて、より正確にする為に「/Applications/Utilities/Grab.app」のお世話になっているのだが、不思議と出力は「tiff」でありbloggerでは撥ねられるので、いちいちPreviewで読み込み「png」にexportしていた。

面倒なので、「sips」コマンドを用いて、変換するようにした;
 #!/bin/bash

# transform .tiff to .png in a current dir.
# exp. abc.tiff → abc.png(overwritten)

# 2013-04-07(日) 16:52 by mNeji


myTiffList=$(echo *.tiff)

if [ $myTiffList = "*.tiff" ]
then
    echo "$0 : no tiff in this dir"
    exit 1
fi

echo "$myTiffList"

num=0

for fileTiff in $myTiffList
do
    (( num ++ ))
    filePng=$(echo $fileTiff | sed -e "s/.tiff$/.png/")
    echo "$num  $fileTiff to $filePng"
    sips -s format png "$fileTiff" --out "$filePng" > /deev/null 2>&1
done

でも、本来ならば 「Excel for Mac 2011」で指定領域を画像としてexportするのが筋だろうな。残念な事にMSは耳を貸さんだろう。

出来れば、KeyRemap4MacBookの「Mouse Key」で精密なマウス・カーソルの制御が出来るだけでも大分違うのだが……。

折角だから、KeyRemap4MacBookでの「my flipped around APPLE Wireless Keyboard」 のレイアウト画面を一括読み出しをするスクリプトも作ってみた;

#!/bin/bash

# Show Keyboard Layouts within a Preview

open -F /Users/u1/Library/Application\ Support/KeyRemap4MacBook/myPrivateXml/PrivateXml_1.1.2/tiffs/Fig.*.png

————
この記事の履歴
  1. 開始 2013-04-07(日) 17:39





2013-01-20

bashスクリプトの作成支援スクリプト、 new

この所、「Mac mini」の内蔵ドライブを「SSD x 2」にして、その管理やバックアップなどのスクリプトを作っている。前から小廻の良いツールの必要性は感じてたので、そのツール、newを紹介します;

#!/bin/bash

# new :bashで実行可能なファイルを作り、エディタで開く

# start: 2013-01-05  (土) 18:08 by mNeji

#### debug
#set -x

# new(ret)で起動した場合、ファイル名$fileを"untitled"そし、入力があればそれを採用する。
if [  $# = 0 ]; then
    file="untitled"
else
    file="$1"
fi

# カレントなディレクトリ中の中で、既存のファイル名と衝突していれば、注意を出して終了
if [ -f "$file" ]; then
    echo "new: \"${file}\" exists already!"
    exit 1
fi

# ファイル名$fileをカレントなディレクトリ中に作成し、
echo "#!/bin/bash " > $file

# 実行権を与えて
chmod 766 $file

# editorで開く
edit $file
使い方;
  •  $ new(ret)
    • ファイル名"untotled"のファイルが作られる。
    • 以前のファイルと衝突していれば注意を出して終了。
  •  $ new file_name(ret)
    •  file_nameが、以前のファイルと衝突していれば注意を出して終了。
    •  存在しなければ、ファイル名をfile_nameとする。
  • 現在のディレクトリ中に、
    • ファイル名がfile_nameのファイルを生成、
    • 実行権を付与し、
    • エディタで開く
理想は、このスクリプトをFinderからこのスクリプトをスマートに呼び出したい訳です。そういえば、Pythonから簡単にGUIを呼び出す、といった本の宣伝が在った様な気がする。調べると;
の様だが、書評をみるとKindleの表示がダナな模様。

ーーーー
この記事の履歴
  • 開始 2013-01-20  (日) 16:51
  • 追加 2013-01-23  (水) 23:13 Easy GUI Programming in Python [Kindle版] 

2012-06-15

簡単なbashスクリプト: ユーティリティ・スクリプト

漸くBashの感じが掴めてきた。特に汎用性の高いファンクション群を纏めることで、再利用が効率的になると思った。

取り敢えず、次のスクリプト・ファイル、「$HOME/myBash/My_Utilities」を作成した。
#!/bin/bash

###################################################################
# 目的:このユーティリティ・ファイルに、小さな関数群を纏めておく。                     #
# 開始:   2012-06-14  (木) 10:00                                           #
###################################################################
#
#   要件: ~/.bashrcに、下記を追加する。
#            「. myBash/My_Utilities」
#            「myBash」は$HOMEの直下で$PATHが通っている。
#
#   使い方:
#           通常の関数としてコール
#           引数は個別の「利用」を参照。
#           作り終えたら、ClipMenu → my用語 →「関数説明の雛形」を用いて説明する。
#
###################################################################

#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# My_Home #
#機能: show "Users home directory"
#利用:引数はなし。"$HOMO"と同じだった。;-P)
#       1) MyHome(ret)
#       2) cd `MyHome`
#
#効能: スクリプト中で「~」を使うと「/var/なんとか」に飛ばされるので。
#
#制作:
#   1) 開始 2012-06-14  (木) 10:42 by mNeji
#
#------------------------------------------------------------------------#
My_Home()
#------------------------------------------------------------------------#
{
    echo /Users/$( whoami )
}

#------------------------------------------------------------------------#


#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# My_LogTouch #
#機能:    $HOMEの下のディレクトリ;引数のDirectoryName(無ければ作り);の配下に、
#       現在のタイムスタンプ名の.logをtouchする。
#具体例:
#       $MyLogTouch abc
#       $cd ~/ab
#       $cd ~/abc
#       $ ll
#       total 0
#       -rw-r--r--  1 u1  staff  0  6 14 18:22 2012-06-14-182257.log
#:
#依存: My_Date2
#
#制作:
#   1) 開始 2012-06-14  (木) 19:08 by mNeji
#
#------------------------------------------------------------------------#
My_LogTouch()
#------------------------------------------------------------------------#
{
# Usage: MyLogTouch DirectoryName
#   touch YYYY-MM-dd-hhmmss.log
#
# DirectoryName: Relative to $HOME
    #set -x
    local dn="$HOME/$1"
    #
    # Check and Make Directory $dn
    #
    if [ -d "$dn" ]
    then
        #echo "alredy exist $dn"
        :
    else
        # echo "not exist $dn"
        mkdir $dn
    ls -l $HOME | grep $1
    fi
    #
    # fileN
    #
    local fileN=`My_Date2`.log
    echo $dn/$fileN
    touch $dn/$fileN
    echo "---> touchd `ls $dn/$fileN`"
}
#
#------------------------------------------------------------------------#


#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#
# My_Date #
#-----------------------------------
# 表示: "2012-06-15(金)15:48:03"
#
#-------------------------
#制作:
#   1) 2012-06-15(金)15:48:03 by mNeji
#
#------------------------------------------------------------------------#
My_Date()
#------------------------------------------------------------------------#
{
    date +'%Y-%m-%d(%a)%H:%M:%S'
}
#
#------------------------------------------------------------------------#


####################################################################
# My_Date2 #
#-----------------------------------
# 機能:# Output: "YYYY-MM-DD-hhmmss"
#
#-------------------------
#制作:
#   1) 2012-06-14  (木) 19:23 by mNeji
#
#------------------------------------------------------------------------#
My_Date2()
#------------------------------------------------------------------------#
{
    date +'%Y-%m-%d-%H%M%S'
}
#
#------------------------------------------------------------------------#


#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# My_UtilsList #
#-----------------------------------
# 機能:
#       「~/myBash/MyUtilities」中の関数名だけの行をリストする。
##             関数名の定義として
##             行頭に、#,数字は無く
##             行尾に、()がついている 
#     
#------------------------
# 具体例:
#       $ MyUtilsList(ret)
#     
#

#-------------------------
#制作:
#   1) 開始 2012-06-15  (金) 00:38 by mNeji
#   2) 追加 2012-06-15  (金) 12:51 sort
#------------------------------------------------------------------------#
My_UtilsList()
#------------------------------------------------------------------------#
{
    cat $HOME/myBash/My_Utilities | grep \(\)$ | grep ^[^#] | sort
}
#
#------------------------------------------------------------------------#


#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#

# 次のスクリプト予定地

#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Bashの立ち上げ表示スクリプト
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# ターミナル.appが開く毎に、.bashrcから呼びさされる。
# 制作:2012-06-15(Fri)16:04:31
echo "`My_Date`  Functions are ready at 'My_Utilities';"
echo "--------------------------------------------------------------------"
echo $(My_UtilsList |sed 's/\(\)..$/, /')| sed 's/,$/./'
echo "--------------------------------------------------------------------"

#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#




#MyHome
#MyDate2
#MyLogFile abc
#test() grep \(\)$
#test()
#1abc()
#xyz()
なお、「.bshrc」に次の行を追加した;
# Read the MyUtiliteis directory within current shell
. myBash/MyUtilities
新しいターミナルを開き、動作の確認をした;
Last login: Fri Jun 15 16:11:40 on ttys006
2012-06-15(Fri)16:13:01  Functions are ready at 'My_Utilities';
--------------------------------------------------------------------
My_Date, My_Date2, My_Home, My_LogTouch, My_UtilsList.
--------------------------------------------------------------------
u1@div-mmX74:~ $
u1@div-mmX74:~ $ My_Date
2012-06-15(金)16:13:17
u1@div-mmX74:~ $
u1@div-mmX74:~ $
u1@div-mmX74:~ $ My_Date2
2012-06-15-161332
u1@div-mmX74:~ $
u1@div-mmX74:~ $
u1@div-mmX74:~ $ My_Home
/Users/u1
u1@div-mmX74:~ $
u1@div-mmX74:~ $
u1@div-mmX74:~ $ My_LogTouch abc
/Users/u1/abc/2012-06-15-161415.log
---> touchd /Users/u1/abc/2012-06-15-161415.log
u1@div-mmX74:~ $
u1@div-mmX74:~ $
u1@div-mmX74:~ $ My_UtilsList
My_Date()
My_Date2()
My_Home()
My_LogTouch()
My_UtilsList()
u1@div-mmX74:~ $
u1@div-mmX74:~ $
u1@div-mmX74:~ $
今後、関数群を製作する毎に、「$HOME/myBash/My_Utilities」に追加して、「$ My_UtilsList」コマンドで関数群のリストを出せる訳だ。

これらのユーティリティを使って当面の課題である「Time Machine」の手動バックアップ・スクリプトは書けそうだ。でもbashに突き進むより、zshやPythonに移行するのが善いと思えるようになってきた。

いずれにしろ正規表現は本腰をいれて練習をせねば...。


ーーーー
このポストの履歴
  1. 開始: 2012-06-15-01:22(JST)
  2. 修正: 2012-06-15  (金) 16:23



2012-06-11

簡単なbashスクリプト: タイムスタンプをペースト・バッファに入れる

キーボード・ショートカットの検索中に、「ペースト」関連を探索する際に「pbcopy」なるコマンドに出会った。コマンドの出力をパイプで「pbcopy」に渡すだけらしい。以前から欲しかったコマンドなので、「dateClip」というのを作ってみました;
#!/bin/bash

# dateClip: put 'formated-date' to clip-board(paste board)-V
#
# usage: dateClip(ret)
#        「(command)-(V)」
#
# 2012-06-11(月)20:50:00 by mNeji
#

echo -n `date +'%Y-%m-%d(%a)%H:%M:%S'` | pbcopy
 今のところ、ターミナルで「dateClip(return)」と打、必要なところで「(command)-(V)」でペーストします。GUIから簡単に呼び出せれば、面白そうなのだが...。現状では「ClipMenuの.js」の方が、使い勝手は良い。

ーーーー
このポストの履歴
  1. 開始: 2012-06-11-23:00(JST)


2012-06-06

簡単なbashスクリプト: 簡易ストップウォッチ

二つの時刻の間隔を計る簡易ストップウォッチ・スクリプトをBashで作ってみました。計測の単位は「sec」だけです。

#!/bin/bash

# mySec: A Stopwatch script
#
# usage:    mySec 0 ←     Start-time in unit of sec.
#            mySec   ←     Time-interval from Start-time in unit of sec.
#           mySec now ←    Current Time in unit of sec.
#
# example:
#            $ mySec 0; sleep 3;mySec    # Check#
#            3sec
#            $ mySec 0     # Start the Stopwatch
#            ... Somothing done ...
#            $ mySec     # Stop the Stopwatch
#            81sec
#            $mySec now    # Curent Time in unit of sec.
#            1339041714
#
# 2012-06-06  (水) 20:07, by mNeji

#set -x

if [ "$1" = "now" ]
then
# for "mySec now" ------------------------------------------------
    echo `date +%s`
    exit 0
fi

if [ -z $1 ]
then
# for "mySec" -----------------------------------------------------
    Stop=`date +%s`
    Start=`cat ${0}.start`
    time_interval=`expr ${Stop} - ${Start} `
    echo "${time_interval}sec"
    rm -f ${0}.start   
else
# for "mySec 0" --------------------------------------------------
    # echo `date +%s` | tee ${0}.start
    date +%s > ${0}.start
fi


【関連記事】
  1. 簡単なbashスクリプト 
  2. 外付けHDDの特定パーティションのマウント/アンマウント・スクリプト
  3. bashとpythonとの連携スクリプトで「du」を観易くする


ーーーー
このポストの履歴
  1. 開始: 2012-06-06-20:30(JST)
  2. 修正: 2012-06-07  (木) 13:06


2012-06-04

外付けHDDの特定パーティションのマウント/アンマウント・スクリプト

切っ掛けはアップルのサポートコミュニティ、Mac OS X v10.7 Lionでの論議;
で、「timeutil」コマンドを使えば、GUIの「Time Machine」の「今すぐバックアップを作成」を開ける事無く、CUIからのコマンドでバックアップを開始できると思えるようになった事だ。とりあえず最小のコマンド;
#! /bin/sh

# tmback: Manually execute "Time Machine Backup"
# 2012-05-04 by mNeji

echo "+ Script($0) start at `myDate` ++++++++++++++"
tmVol=`tmutil machinedirectory`
#echo "tmVol: ${tmVol};"
noVol=""
#echo "noVol: ${noVol};"

if [ "$tmVol" = "$noVol" ]; then
    echo "Please wakeup External HDD for Time Machine Backup, Try again!"
else
    echo "+ Time Machine Backu Up for `tmutil machinedirectory` "
    #echo "+ sudo tmutil uniquesize \`tmutil listbackups\` ---------------------"
    #sudo tmutil uniquesize `tmutil listbackups`
    echo "+ sudo tmutil startbackup --block  ---------------------------"
    sudo tmutil startbackup --block
    echo "+ sudo tmutil uniquesize \`tmutil listbackups\` ---------------------"
    sudo tmutil uniquesize `tmutil listbackups`
fi   
echo "+ Script($0) finish at `myDate` +++++++++++++"
echo
 で保存するようになった。かれこれ1ヶ月ほど安定的にバックアップがとれている。

問題は、手動でFinderを経由して外付けHDDの内の「Time Machine」のパーシションを起動する必要がある事だ。そこで、今回は『必要なパティション、$tmVol、をマウント/アンマウントするスクリプト』を作ろうと考えた。


手元の資料としては
であった。svensonさんの記事では「/Volumes/」でのパーティション名(partition name)もしくはヴォリューム名(volume name)とディバイス名(/dev/diskNsM)とを必要と読める。

でもユーザがFinderで認識してしているのは、あくまで「パーティション名(partition name)」なのだからと思い、「diskutil」を弄り回した。その結果;
  • 電源が入っている外付けのリストは「diskutil list」で確認できる。この中にパーティション名($NAME)があれば、次に進む。ここに無ければ電源の投入を注意する。
  • マウントの状況は「diskutil info $NAME」で判るが、直裁に「ls /Volumes」を取って、その中に$NAMEがあるかどうかで判定できる。
  • 具体的tmutilコマンドでは、パーティションはフルパス表現は不要の様子;
    • マウント: diskutil mount $NAME
    • アンマウント: diskutil umontDisk $NAME
      • 一部のアンマウントだけに止
      • めたければ、
      • 「umontDisk → umont」
とすれば善い事が判った。

そこでマウント用のHDDonと、アンマウント用のHDDoffとを作った;

マウント用のHDDon
#!/bin/bash

#
# usage: myHDDon Volume_Name
#              ↑ /Volues/に出てくるパーティション名(partition name)、ヴォリューム名(Volume name)。
#
#               引数なし(no argument)だと、get "diskutil list"
# 2012-06-03 by mNeji
#

# debug ################
# set -x

# Refered Information
# A bash script  to mount and unmount the Windows partition in Mac OS X
# http://forums.macrumors.com/showthread.php?t=195891

# Volume Name of the Partition
NAME=$1

# 無引数(no argument) ######################################
if [ -z $NAME ] ; then
    diskutil list
    exit 1
fi

# 引数(argument)=パーティション名(partition name in /Volumes/) ################

# /Volumes/中にパーティション$NAMEがあるかの判定
### p_name=`ls -1 /Volumes/ | grep ${NAME}`
### echo "p_name: '${p_name}'" # debugging output
if [ -z `ls -1 /Volumes/ | grep ${NAME}` ] ; then
    # パーティション$NAME が存在していない
    # check the $NAME in "'diskutil list'"
    ### echo "--> `basename $0`: Checking $NAME in "'diskutil list'" at `myDate`"
    if [ -z `diskutil list | grep " $NAME " | awk '{print $3}'` ] ; then
        # no $NAME in "diskutil list"
        echo "--> `basename $0`: Turn on POWER SW and Retry ----------------"
        diskutil list
        echo "--> `basename $0`: Turn on POWER SW and Retry ----------------"
        exit 1
    else
        # already Powerd the HDD, then mounting
        diskutil mount $NAME > /dev/null
        ### echo "--> `basename $0`: '${NAME}' mounted now."
        exit 0
    fi
else
    # already mounted the partition
    ### echo "--> `basename $0`: '${NAME}' mounted already."
    exit 0
fi


  アンマウント用のHDDoff
#!/bin/bash

#
# usage: myHDDoff Volume_Name
#              ↑ /Volues/に出てくるパーティション名。
#              そのVolune_Nameのmount/unmoutのトグル・スイッチ
#
#               引数なし(no argument)だと、get "diskutil list"
# 2012-06-03 by mNeji
#

# debug ################
### set -x

# Refered Information
# A bash script  to mount and unmount the Windows partition in Mac OS X
# http://forums.macrumors.com/showthread.php?t=195891

# Volume Name of the Partition
NAME=$1

# 無引数(no argument) ######################################
if [ -z $NAME ] ; then
    diskutil list
    exit 1
fi

# 引数(argument)=パーティション名(partition name in /Volumes/) ################
# p_name=`ls -1 /Volumes/ | grep ${NAME}` # for debugging
# echo "p_name='${p_name}'"

# Check existing of directory of /Volumes/$NAME ##############
partition_name=`ls -1 /Volumes/ | grep ${NAME}`
if [ -z ${partition_name} ] ; then
# there is no /Volumes/$NAME:
    # check the $NAME in "'diskutil list'"
    ### echo Checking $NAME in "'diskutil list'" at `myDate`
    if [ -z `diskutil list | grep " $NAME " | awk '{print $3}'` ] ; then
        # no $NAME in "diskutil list"
        echo "--> `basename $0`: Confirm Volume(Partition)-name! ----------------"
        diskutil list
        echo "--> `basename $0`: Confirm Volume(Partition)-name! ----------------"
        exit 1
    fi     
else
# there is /Volumes/$NAME:
    # unmounting the its all Disk
    diskutil unmountDisk $NAME >/dev/null
    ##### echo "--> `basename $0`: '${NAME}' unmounted Disk now."
    exit 0
fi
なお、判定文の”[  -n $string ]"は上手く動かなかったので、仕方なく”[  -z $string ]"のタイプに統一しました。

ーーーー
  1. 開始 2012-06-04  (月) 12:53 
  2. 修正 2012-06-05  (火) 13:38  「HDDoff: partition_name」←「binary operator expected」対策

2012-04-09

bashとpythonとの連携スクリプトで「du」を観易くする

最近、「python shell」でpythonの練習をしていると、ちょっと複雑なスクリプトをチューニングしようとすると、Aquamacsで.pyとして書き出し、terminalで動作確認する方が楽である事に気がついた。

慣れるにつれて、bashもpythonもターミナルから見ればスクリプトである事を実感して来た。数値処理は、若い頃にFortranやHP-BASICなどを使っていた事も在り、bashでやるよりはpythonの方が使い易い事にも気がついた。

そんな折り、「Time machine」によるバックアップに並行して、ディレクトリごとのバックアップ(rsync)をしたいと思うようになった。ついては以前、iMac間で、データの転送する時に、「du -h -d 1」をして、印刷用紙上で、転送の有無と、サイズの確認をしたものの見辛かったのを思い出した。

今回は、このコマンドをサイズの大きい順にソートして、「-h」に近い形式で見易くする事を考えた。大部分は下記の参考書を見ると、bashでできる;
  •  UNIXシェルスクリプト 逆引き大全 333の極意
    • 中橋 一郎・著
    • 秀和システム、2009-08.
    • ISBN-10: 4-7980-0884-2
が、計算処理はpythonの方が楽そうだ。そこで、bashスクリプトからpythonスクリプトを「バックコートで括る」形式で読みだす事にトライした。

まず、bashスクリプト本体は;

u1@div-mm:~/bin$ cat myDU
#!/bin/bash 

# Finderで、ディレクトリ右クリックで「情報」を見るのは面倒だ。そこで
# 現在のディレクトリ中の全てのディレクトリのサイズを求め、
# ブロックの順にソートし、
# バイト単位(kB=1000B, MB=1000kB, GB=1000MB)で表示する。
#    2012-04-08  (日) 15:44 by mNeji/irt
#    on Lion/10.7.3 at Mac mini(mid 2011)

# 参考: 「UNIXシェルスクリプト 逆引き大全 333極意」
#          中橋 一郎 著
#          秀和システム、2009-08
#          ISBN-10:4-7980-0886-2
# 参考箇所:unix333, (p223, Tips#194), (p112, Tips#084)

# 説明の表示
echo "+ Script($0) at `myDate` start +++++"
echo "+ action: 'du -d 1 | sort -gr' for dir:'`pwd`' " 
printf '+ Size \t\t Directory Name ----------------------\n'

# 現在のディレクトリと直下のディレクトリのサイズを求め、ブロックの順にソートする
du -d 1 |sort -gr > temp_du

# unix333, (p223, Tips#194): ファイルを行に分割
IFS=$'\n'               #改行区切り 
file=(`cat temp_du`)    #fileはアレイ構造

rm -f temp_du           # 中間ファイルを削除

# アレイの第一列にあるブロック数を適切なバイト数に変換して、
# 表として再度、表示する。

for line in "${file[@]}";do

    # unix333, (p112, Tips#084): 1行をタブで分割
    IFS=$'\t'       #タブ区切り
    set -- $line    #$1はブロック数(512Byte) , $2は相対ディレクトリ 
 
    #ブロック数からkByte, MByte, GByteへの変換には、
    #「Python script: myBlock2Byte.py」を作成して、用いた。
    ByteSize=`myBlock2Byte.py "$1"`  
    
    # 行表示
    printf '%s\t %s\n' "$ByteSize" "'$2'"

done

echo "+ Script($0) at `myDate` stop +++++"
u1@div-mm:~/bin$ 


ここで、「pythonスクリプトの呼び出し」は第42行目の;

  • ByteSize=`myBlock2Byte.py "$1"`

です。

 そのpythonスクリプト「myBlock2Byte.py」は;

u1@div-mm:~/bin$ cat myBlock2Byte.py 
#! /usr/bin/python
# coding: utf-8

# usage: $ myBloch2Byte.py block_number
#         The parameter, block_number indicates in the unit of 1block = 512Byte

# input: Size in the unit of Block
# output: Size in the unit of kB, MG, GB
# 2012-04-06 by mNeji
#   Python/2.7.1 on Lion/10.7.2 at Mac mini(mid 2011)


# 引数の受け入れ
import sys
myArg= sys.argv

# ブロック数を整数型に変換し、
blockSize=int(myArg[1])

# module math
import math

# バイト数に変換
byteSize=math.floor(blockSize*512)  # 1block = 512Byte
kSize=byteSize/1000.    # 1kB = 1000Byte for Lion/10.7.3
MSize=kSize/1000.       # 1MB = 1000kB for Lion/10.7.3
GSize=MSize/1000.       # 1GB = 1000MB for Lion/10.7.3



# 使用サイズの補助単位選択

if GSize >= 1.:
    print '%7.2f%s' % (GSize,"GB")
elif MSize >= 1.:
    print '%6.1f%s' % (MSize,"MB")
else:
    print '%5.0f%s\t' % (kSize,"kB")


    
u1@div-mm:~/bin$ 



です。

このスクリプトで自分のホーム・ディレクトリのディレクトリ容量を出した結果は;

u1@div-mm:~$ myDU
+ Script(/Users/u1/bin/myDU) at 2012-04-09(月)14:02:28 start +++++
+ action: 'du -d 1 | sort -gr' for dir:'/Users/u1' 
+ Size    Directory Name ----------------------
 129.61GB  '.'
  64.22GB  './Library'
  57.51GB  './Music'
   5.76GB  './VirtualBox VMs'
 714.6MB  './Sites'
 564.1MB  './Documents'
 465.9MB  './Pictures'
 143.2MB  './myLocal'
 111.6MB  './Kabe-Gamis'
  88.3MB  './tmp'
  11.5MB  './bin'
   8.3MB  './backup'
   4.6MB  './.npm'
   2.9MB  './.gem'
   1.4MB  './myBash'
   1.3MB  './RRwork'
   1.1MB  './solarized'
  569kB   './Public'
  172kB   './.zsh.d'
  164kB   './DLしたプログラム資料'
   66kB   './function'
   53kB   './zsh_back0'
   20kB   './.ssh'
   16kB   './mytest'
   16kB   './Downloads'
   16kB   './Desktop'
    4kB   './.pip'
    4kB   './.idlerc'
    4kB   './.cups'
    0kB   './NTT_PR-S300SE'
    0kB   './Movies'
    0kB   './.emacs.d'
    0kB   './.bundler'
    0kB   './.Trash'
+ Script(/Users/u1/bin/myDU) at 2012-04-09(月)14:02:30 stop +++++
u1@div-mm:~$ 

です。なお、上記の容量値を、Finderで該当するディレクトリを右クリックして情報を見てみますと;




サイズの項にでている「129.61 GB」 と一致します。それぞれ小さい場合も完全に一致しています。今後、気楽にバックアップを検討する事ができそうです。


慣れてしまえば、完全にpythonスクリプトで処理する方が楽そうである。いよいよ、Calcのマクロをpythonで作る事も可能な気がして来た。



ーーーー このポストの履歴
  1. 開始 2012-04-09 (月) 13:53


2012-03-25

簡単なbashスクリプト

自分のネットワーク環境を整備する為に、幾つかのスクリプトを作りました。忘れる前にメモしておきます。
  1. myDate: 自分のタイムスタンプ
  2. myHost: 自分のマシンのホスト名、localhostのIPアドレス
  3. myNet: 自分のマシンが属するネットワーク情報
  4. myScanIP: PINGを連続的にスキャンする。
  5. myDiskutil_list: 「diskutil list」のまんま
  6. myMount_disk1: 外付けhdd, disk1のマウント
  7. myUnmount_disk1: 外付けhdd, disk1のアンマウント
この内、1〜4は便利なので、公開しておきます。

1 myDate
#!/bin/bash
date +'%Y-%m-%d(%a)%H:%M:%S'

2 myHost
#!/bin/bash
#
# myHost: 動作例=>「HOST: name=(div-mm.local); ip=(10.0.1.2)」 
#
# 参考: UNIXシェルスクリプト 逆引き大全 333極意
#        p112, #84 文字列を指定した区切り文字で分割する。


getHostIP() {
 hostName=`hostname`
 localIP=`netstat -r -f inet |grep "localhost" | grep "UHS"`

 _IFS="$IFS"    # save $IFS
 IFS=' '
 set -- $localIP
 IFS="$_IFS"

 # 分割結果:
 # $1: host's IP address
 # $2: localhost
 # $3: UHS
 
 echo "HOST: name=($hostName); ip=(${1})"
              
 return
}

# 実行
getHostIP

3. myNet
#!/bin/bash

echo '"netstat -r -f inet"'
echo " at `myDate`"
netstat -r -f inetdiv

4. myScanIP
#!/bin/bash
#
# myScanIP [ipSpace ipStart ipWidth ] 
#

#localIP=`netstat -r -f inet |grep localhost | grep UHS`
localIP=`myHost`
echo $localIP

declare -i j k ipStart ipStop ipWidth noa

j=1 #start
k=5 #width


# Default values
ipSpace="192.168.1"
ipStart=j
ipWidth=k
noa=$#

#echo "  Number of Arguments = $noa"
#echo "    ipSpace=${ipSpace}"
#echo "    ipStart=${ipStart}"
#echo "    ipWidth=${ipWidth}"

if [ $noa -eq 0 ]; then
    damy=1
elif [ $noa -eq 1 ]; then
    ipSpace=$1
elif [ $noa -eq 2 ]; then
    ipSpace=$1
    ipStart=$2
elif [ $noa -eq 3 ]; then
    ipSpace=$1
    ipStart=$2
    ipWidth=$3
fi

ipStop=$ipStart+$ipWidth-1


if [ $ipStop -gt 256 ]; then
    ipStop=255
    ipWidth=ipStop-ipStart+1
fi


file="ipScan_${ipSpace}.${ipStart}~${ipStop}.txt"
echo "======= myScanIP for ${ipSpace}.${ipStart}~${ipStop}" > $file
echo "===== ping from ${localIP}" >> $file
echo "  Number of Arguments = $noa" >> $file
echo "    ipSpace=${ipSpace}" >> $file
echo "    ipStart=${ipStart}" >> $file
echo "    ipStop=${ipStop}" >> $file
echo "    ipWidth=${ipWidth}" >> $file
echo "=== save file:'${file}'" >> $file

timeStamp=`date +'%Y-%m-%d(%a)%H%M%S'` 

echo "* Scan start:_${timeStamp} " >> $file

echo "======= scanIP for ${ipSpace}.${ipStart}~${ipStop} =============="

echo "===== ping from ${localIP}"

echo "  Number of Arguments = $noa"
echo "    ipSpace=${ipSpace}"
echo "    ipStart=${ipStart}"
echo "    ipStop=${ipStop}"
echo "    ipWidth=${ipWidth}"

echo "=== save file:'${file}' "
echo "* Scan start:_${timeStamp} "

j=ipStart

while [ $j -le $ipStop ];
do
    result=`ping -c 2  "${ipSpace}.$j"`
    yes_response=""
    yes_response=`echo "$result" |grep 'round-trip min/avg/max/stddev'`
    if [ "$yes_response" != "" ]; then
        echo "#ip=${j}: ${yes_response}"  >>$file
        echo "#ip=${j}: ${yes_response}"
    else
        echo  "_ip=${j}:non___" 
    fi
    j=j+1

done

timeStamp=`date +'%Y-%m-%d(%a)%H%M%S'` 
echo "* Scan stopped:_${timeStamp} " >> $file
echo "* Scan stopped:_${timeStamp} "

echo "========= myScanIP finished =============="

上記のスクリプトの28行目の「dummy=1」と言う無意味は命令は、本来コメント「#」でしたが、そうすると次の「elif」がエラーとなるので挿入しました。この経験から、現在zshへ乗り換えをしようとしています。

【関連記事】

  1.  
  2. 簡単なbashスクリプト: 簡易ストップウォッチ 

ーーーー このポストの履歴
  1. 開始 2012-03-25 (日) 13:59

2012-03-24

bashからzshへの移行での簡易設定

iTerm2にしてからbashスクリプトでチョコチョコとネットワーク関連の小さなスクリプトを書いているうちに、bashは意外と脆い事に気がついた。探すとzshが堅牢そうなので、zshを試している。

そこで、bashからの環境移行をしてみた;
  • .bashra → .zshrc
  • .bash_profile → .zshrc
  •  に統合(.zprofileでは駄目だった)
この内、「prompt」部分はbashの設定『マシン名:ディレクトリ名 アカウント名 $』に合わせるように変えた。なお、ディレクトリ名はホーム・ディレクトリを「~」とする形式にした;

.bashrc
export LANG=ja_JP.UTF-8

export PS1='\h:\w \u\$ '
.zshrc
 export LANG=ja_JP.UTF-8

#PROMPTs
PROMPT='%m:%~ %n$ '
PROMPT2="%_%% "
SPROMPT="%r is correct? [n,y,a,e]: "
参考書が手に入る前には、この手の初歩の設定で十分な気がする。


ーーーー このポストの履歴
  1. 開始 2012-03-24 (土) 02:06



注目の投稿

Terminalでの、なんちゃってViモドキ

近頃、ようやくKarabiner-Elementsに慣れてきたので、 Terminalで動作する「擬似Vi-Mode」を作って見たので、ご紹介します。 『概要』 「擬似Vi-Mode」の所以は、方向キー「←↓↑→」を通常の「hjkl」ではなくて「jkil」としました。これ...