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

2009年9月22日火曜日

find コマンドで該当するファイルを削除する

find コマンドで該当するファイルを削除する方法です。別に削除でなくてもいいんですけど、使いたい目的は削除が多いのかなと思います。他にもパーミッション(permission)の変更にも使えたりします。

使い方の例としては以下の通りです。

find . -name *.sh | xargs ls -l
find . -name *.sh | xargs rm -f
*.sh というファイルを検索し、それを rm コマンドで削除するというコマンドです。(実行するととんでもないことになるようなものなので、試行には十分注意して下さい。)まずは、ls コマンドで対象ファイルを表示してみて、rm コマンドで削除するほうがいいでしょう。

以下の通り、同様のことができます。
  1. 実行権のあるファイルの実行権を落とす
    find . -perm -ugo=x -type f | xargs ls -l
    find . -perm -ugo=x -type f | xargs chmod ugo-x
    permission が +g+x だけだとディレクトリも対象となってしまい、意図と違うので、-type f を付加します。
  2. group にあるパーミッションを other にも付加する
    find . -perm -g=r -type f | xargs ls -l
    find . -perm -g=r -type f | xargs chmod o+r
色々応用できると思います。

2009年4月23日木曜日

awk No.005(変数で条件指定)

awk は、awk の中で変数を持っていますので、シェル変数の持ち込み方(使い方)に工夫が必要です。-v オプションで -v VAR=${VAR} とする方法とは別に、条件指定(/ で括った場合)でもひと癖あります。

$ VAR1="abc"
$ awk '/$VAR1/ {print}' a.dat
上記のようにすると、$VAR1 という文字列を検索して、変数 VAR1 の内容"abc"で検索をしてくれません。そこで、以下のように記述することで、変数 VAR1 の内容"abc"で検索してくれます。
$ VAR1="abc"
$ awk '/'$VAR1'/ {print}' a.dat
シングルクォートで囲ってあげることで、シェル変数として認識してくれます。

2009年4月7日火曜日

sed でコマンド実行結果を使う

sed でコマンド実行結果を指定する方法です。

sed s/abc/def/g a.txt といった指定をしますが、abc や def にコマンド実行結果を指定する場合、以下のようにします。

sed s/`hostname`/`hostname -f`/g a.txt
これで、hostname コマンドの実行結果(例えば host01)を hostname -f の実行結果(例えば host01.hogehoge.local)に変換してくれます。

`command`という文字列として扱いたい(コマンドとして実行しない)場合は、s から g を、シングルクォート( ' )で囲み、コマンドのバッククォート( ` )の前にバックスラッシュ( \ )を挿入します。
sed 's/abc/\`command\`/g' a.txt

2009年3月28日土曜日

awk No.004(条件指定)

awk の条件指定はいろいろあります。

まず、空行を除く場合は、以下のように NF > 0 を指定します。余計なデータを除いて処理する場合の基本です。ここで使っている NF は読み込んだレコードのフィールド数(データ数)を表わしています。NF が 0 よりも大きい、すなわち 1 個以上の場合は処理をするという指定になります。(空行はデータがないので処理しないということになります。)

awk 'NF > 0 {print $1}' a.dat
空行を除く場合は、以下のようにもできます。どちらかといえばこちらの方が本当の意味で空行を判定しています。^$ は正規表現で先頭と行末で、先頭と行末のみということは空行で、それを ! で否定していますので、空行ではない行という条件になります。データが無いという条件より厳密です。
awk '!/^$/ {print $1}' a.dat
何番目のレコードを処理するというように、レコードの順番を指定して処理する場合は、以下のように NR を使います。例えばデータファイルに行タイトルがある場合は、1行目を読み飛ばす等の処理ができます。
awk 'NR > 1 {print $1}' a.dat
基本的な使い方をもう一つ。読み込んだデータの内容によって処理をするかどうかを判定します。1番目のフィールドのデータが 100 より大きい場合に処理をするといった使い方は以下の通りです。
awk '$1 > 100 {print $1}' a.dat

2009年3月24日火曜日

awk No.003(区切り文字、デリミタ、フィールドセパレータを変更)

awk 標準の入力データのデリミタはスペースです。デリミタを変更したいときは、変数 FS を使います。デリミタと書きましたが、FS という変数からわかるようにフィールドセパレータというのが区切り文字の正式名称(?)のようです。

使い方は以下の通りです。

$ cat a.dat
a:b:c
d:e:f
g:h:i

$ awk -v FS=":" '{print $1}' a.dat
a
d
g

2009年3月5日木曜日

df で表示させるファイルシステムを限定する

df コマンドでファイルシステム情報を表示すると、NFS 等のネットワークファイルシステムを多くマウントしていたり、ローカルファイルシステムが多くあったりすると、だらだらと表示されて見づらくなってしまいます。

そこで、-x (--exclude=) オプションで、表示させないファイルシステムを指定することができます。また、複数のファイルシステムタイプを指定したい場合は、-x (--exclude=) オプションを複数回指定します。

df -x nfs -x ext2

2009年1月29日木曜日

PCで作成したCDをUNIXで読む

Windows で作成した CD-ROM(CD-R等)を UNIX で読むとロングファイルネームのファイルが全て 8.3形式に変わってしまっていたり、大文字ばかりになっていたり、小文字ばかりになっていたりします。

Windows で作成した CD-ROM(CD-R等) は、通常 Joliet といわれる形式になっています。Joliet は CD-ROM(CD-R等) の規格である ISO9660 を拡張して、8.3形式以外のファイル名を使えるようにしたものです。

しかし、UNIX では Joliet が認識できず、8.3形式のまま表示されてしまうことがあります。Linux は Windows と親和性が高い傾向にあるので、問題なく読んでくれるものが多いのですが、Solaris などは Joliet を認識できません。

Solaris などの UNIX では RockRidge という Joliet とは異なった規格が使われいることが原因です。

なので、Windows で作成した CD-ROM(CD-R等) を UNIX でも正しく読みたい場合は、RockRidge 形式でライティングすればいいのです。が、簡単にはできません。方法としては、以下の方法が考えられます。

  1. Windows で RockRidge 形式でライティングする。
  2. UNIX(Linux含む)で RockRidge 形式の ISO イメージを作成し Windows でライティングする。
ただ、1. は RockRidge 形式でライティングできるライティングソフトが見当たりません。(あるのかもしれませんが・・・)2. も、UNIX 環境へファイルを転送して ISO イメージを作成できるくらいなら、あえて CD-ROM(CD-R等) にする必要はありません。

主な用途としては、Windows で取得したファイルを UNIX にもっていきたいけれど、ネットワーク環境などが整っていないので CD-ROM に焼いてもっていくということなので、できるだけ Windows 環境だけで CD-ROM を作成しないといけません。そこで、以下の方法であれば、Windows 環境だけで UNIX 向けの RockRidge 形式の CD-ROM が作成できます。(反則気味ですが・・・)
  1. Cygwin で RockRidge 形式の ISO イメージを作成する。
    # mkisofs -R -J -T -o rockridge.iso ./files
    -R RockRidge 形式で ISO イメージを作成
    -J Joliet 形式で ISO イメージを作成(-R -J は同時に指定できます。)
    -T TRANS.TBL を作成(RockRidge 形式が使用できないシステム向けのロングファイルネーム情報)
    -o filename ISO イメージファイル名
    ./files ファイルが格納されているディレクトリ
    【-R -J -T を全て指定しておけば、ほぼ全てのシステムでロングファイルネームが扱えるということになります。】
    Manpage of MKISOFS
  2. RockRidge 形式 ISO イメージをライティングする。
すいません。Cygwin 使うだけでした・・・Cygwin なら Windows 上で処理できますから・・・

2008年7月11日金曜日

ssh鍵認証 No.001(Linuxで鍵作成)

sshで鍵認証する場合の一例です。

  1. ssh-keygen で id_rsa と id_rsa.pub を作成します。
    適当なパスフレーズを入力して作成します。
    ssh-keygen -t rsa -b 2048
  2. id_rsa.pub を authorized_keys に追加します。
    cat $HOME/.ssh/id_rsa.pub >> $HOME/.ssh/authorized_keys
  3. id_rsa を 接続するターミナルソフト側で読み込みます。
    • PuTTYでは、id_rsa を PuTTYgen で private key として保存します。
  4. ターミナルソフトで接続時に id_rsa を指定して接続します。
    • PuTTYでは、private key として保存した、id_rsa.ppk 等を指定します。
    • TeraTermでは、id_rsa をそのまま鍵として指定します。
ちなみに、鍵認証を利用するメリットは、何でしょうか。まあ、「鍵を持ってないと認証を受けられない」という当たり前のことに加え、パスワードがネットワーク上を流れないことでしょうか。パスワードがネットワーク上を流れないことについては、sshを使っている時点で、暗号化されている為、個人的には必要十分だと思いますが、それよりもセキュリティ的には堅牢です。(解読対象がネットワークを流れないわけですから。)

といってしまうと、確かに鍵認証は、パスワード認証に比べて、より強固なセキュリティを提供してくれるわけですが、大きな落とし穴があります。それは、パスワード認証と併用していると、鍵認証よりも低いセキュリティレベルの認証ができてしまい、パスワード認証可能な環境であれば、「鍵を持っていなくても認証ができる」→「誰でもアタックできる」状態となってしまいます。

以下の様に、sshd_config で、パスワード認証を禁止しておかないとメリットは半減です。
PasswordAuthentication no

2008年7月2日水曜日

forを一行で書く

シェルでfor文を一行で書くと結構便利です。

基本は以下のように書くわけです。何らかの連続した動作をさせる時に重宝します。

for i in 1 2 3 4; do date; echo $i; done
例えば、そのままですが、決められたことを順番に動作させる場合、こんな感じです。
  • abc def ghi と順に表示
    $ for i in abc def ghi; do echo $i; done
    abc
    def
    ghi
  • host01 から host10 まで ping を発行
    $ for i in `seq -f "host%02.0f" 1 10`; do ping -c 1 $i; done
セミコロンの位置がややこしいですが、do と done の前にセミコロンと覚えておくとわかりやすいです。

2008年6月24日火曜日

シェルで配列を使う No.003

シェルで配列を使う際、要素でソートする場合、以下のようにするのですが、

HOGE2=(`echo ${HOGE[*]} | sed 's/\s/\n/g' | sort`)
これだと、確かにソートされるのですが、数字としては、うまく処理されません。そこで、以下の通り、一旦、ゼロ付数字に変換してやることで、正常にソートされます。
  • 正常にソートされない
    要素が 1 5 11 2 3 21 31 22 だとすると、以下のようになってしまいます。
    1 11 2 21 22 3 31 5
  • ゼロ付数字に変換してソートする
    要素を 01 05 11 02 03 21 31 22 に変換してソートします。
    # ゼロ付でソート
    HOGE2=(`printf "%02.0f\n" ${HOGE[*]} | sort | sed 's/\n/ /g' | sed 's/\s+$//g'`)
    # ゼロを取り除く
    HOGE3=(`printf "%.0f " ${HOGE2[*]}`)
    1 2 3 5 11 21 22 31
余談ですが、sed で 半角スペースを扱う時は、"\s" と表現しますが、場合によっては、"\ " としないといけない場合があります。なぜかは理解できていません。

2008年6月17日火曜日

シェルで配列を使う No.002

なんでもかんでもシェルでやってしまおうとすると、配列を扱うことが多くなり、配列による複雑な処理が増えてきます。

配列全体を表示する時は、echo ${HOGE[*]} としたりするのですが、そうすると配列の要素がブランク区切りで表示されます。

echo ${HOGE[*]}
a b c d e f g h i j k 1 1 1 1 2 2 2 a b c x y z
いろんな処理をしていると、重複した要素をまとめたいことがあります。また、要素をソートしたい場合もあります。以下、それらの方法です。

  1. 重複した要素をまとめる
    sort と uniq を使いたいので、配列の要素列をスペースを改行に変換します。
    HOGE2=(`echo ${HOGE[*]} | sed 's/\s/\n/g' | sort | uniq`)
  2. 要素をソートする
    1.の例とほとんど同じで、uniqが無いだけです。
    HOGE2=(`echo ${HOGE[*]} | sed 's/\s/\n/g' | sort`)

2008年6月15日日曜日

exprで掛算する場合

exprで四則演算する場合に嵌ってしまうところです。

exprの文法では、+、-、*、/で加減乗除を行うわけです。例えば、シェルスクリプトの中では、カウンタ変数の足算が最もポピュラーな使い方ではないでしょうか。以下のようにやりますね。

cnt=0
while [ #{cnt} -lt 10 ]
do
cnt=`expr ${cnt} + 1`
done
これと同様に減算、除算はできてしまいますが、乗算(掛算)はうまくいかない場合があります。すぐに気付くのですが、‘*’はメタキャラクタとして扱われて、シェルスクリプトが実行されているカレントディレクトリなどが展開されてしまいます。
[NG]
hoge=`expr ${hoge} * 10`
[OK]
hoge=`expr ${hoge} '*' 10`
hoge=`expr ${hoge} "*" 10`
hoge=`expr ${hoge} \* 10`
‘うまくいかない場合がある’と表現したのは、[NG]の書き方でもうまくいく場合があるからです。シェルやそのバージョンなどの環境によるのかもしれませんが、ダメな場合があるので、念のため囲んでおいたほうがいいでしょう。

2008年6月14日土曜日

シェルで配列を使う No.001

シェルスクリプトでも、一般的なプログラミング言語と同様に配列変数を使えます。

使い方は簡単で、値を複数代入することで、配列変数となります。ただし、この簡単さ故に、規則的にコーディングしないと、配列なのかどうかわからなくなってしまったりします。

  1. 初期化
    必須というわけではないですが、一応行っておいたほうが無難でしょう。
    HOGE=()
  2. 初期化(代入)
    ()で初期化すると値は何も入っていない状態ですが、値を代入しながら初期化することも可能です。(括弧で括って、スペースで区切ります。)
    HOGE=(a 1 bcd 123)
  3. 参照(1)
    代入してある値を参照する方法です。

    一つ一つ値を参照
    echo ${HOGE[0]} ${HOGE[1]} ${HOGE[2]}
    a 1 bcd
    まとめて参照
    echo ${HOGE[*]}
    a 1 bcd 123
  4. 参照(2)
    ちょっと変わった参照方法です。

    文字数を参照 (変数名の先頭に#をつけて、要素を指定します。)
    echo ${#HOGE[2]}
    3
    要素数を参照 (変数名の先頭に#をつけて、全要素‘*’を指定します。)
    echo ${#HOGE[*]}
    4
入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界
入門UNIXシェルプログラミング シェルの基礎から学ぶUNIXの世界

図解でわかるLinuxシェルスクリプト・正規表現
図解でわかるLinuxシェルスクリプト・正規表現

2008年6月10日火曜日

cutでデリミタとして連続スペースを使う

cutでデリミタとして連続スペースを使う方法ですが、正確には、cutで連続スペースをデリミタとして使用できません。ですので、連続スペースを1つのスペースにまとめて処理することになります。

まず、sedで連続スペースを1つのスペースにまとめる方法です。

sed 's/\s\{1,\}/ /g' hoge1.txt > hoge2.txt
次に、cutで1つのスペースをデリミタとして使用します。
cut -d' ' -f1 hoge2.txt > hoge3.txt
パイプで続けて実行する場合は、以下の通りです。
cat hoge1.txt | sed 's/\s\{1,\}/ /g' | cut -d' ' -f1 > hoge3.txt

2008年6月1日日曜日

screenならセッションが切れても大丈夫

Linuxなどのターミナルで、screenコマンドを使うことで、セッションが切れても大丈夫ですし、画面を共有したりもできます。

Manpage of SCREEN
Let's use SCREEN!
iandeth. - screen - 仮想端末マネージャーの使い方

[Ctrl]+a は ^A と表しています。(^ は [Ctrl]+? ということです。)
a は小文字、A は大文字です。a は[a] 、A は [Shift+a] です。

【screenの操作】

  1. screenを起動する
    # screen
  2. screenから抜ける
    ^A d
  3. screenに(再)接続する
    # screen -r

【ウィンドウの操作】
  1. ウィンドウを開く
    ^A c
  2. ウィンドウを閉じる
    ^A K
【リージョンの操作】
  1. リージョンを分割する
    ^A S
  2. リージョンを破棄する
    ^A X
  3. カレントのリージョン以外を全て破棄する
    ^A Q
【スクロール・コピー・ペースト】
  1. スクロールモードにする
    ^A Esc
  2. 範囲選択・コピー
    Enter / Space
  3. ペースト
    ^A ]

【その他】
  1. 最下行にウィンドウ一覧を表示
    .screenrcに以下のhardstatus alwayslastlineを指定
    hardstatus alwayslastline %w
  2. エスケープキーバインドの変更
    .screenrcに以下のescapeを指定
    (^Aaを^Zzに変更)
    escape ^Zz