情報工学科 3年生対象 専門科目 システムプログラミング 第4回 シェルスクリプト 情報工学科 篠埜 功 シェルスクリプト • シェルに対する命令をファイルに記述したもの • シェルとは – コマンドインタプリタ。UNIX系OSではシェルはユ ーザプログラムであり、自分でシェルを作成する こともできる。 シェル(/bin/sh)に直接打ち込む例 [sasano@oli004 ~]$ sh sh-2.05b$ A=ls sh-2.05b$ $A <lsの実行結果> sh-2.05b$ シェルスクリプトは、シェル(通常 は/bin/sh)に対する命令列をファ イルに格納したものである。ここ ではファイルに入れずにシェル (/bin/sh)上で直接実行してみる。 (補足) shと打つことによって、shというファイルが環境変数 PATHに入っているディレクトリから検索され、その結果 /bin/shが見つかり、それが実行される。 A=ls などのように、変数名=文字列 の形で、変数を定義できる。=の前後にスペースを入れて はいけない。スペースを入れると、この場合、Aをコマンド 名として解釈しようとしてcommand not foundになる。 変数の値の参照は、$変数名とすればよい。 (参考) /bin/tcshの場合 [sasano@oli004 4kai]$ set A=ls [sasano@oli004 4kai]$ $A <lsの実行結果が表示される> [sasano@oli004 4kai]$ /bin/tcsh では、上記のように、set A=lsの形で、set コマンドを用いてシェル変数を定義する。(ここでは= の前後にスペースがあってもよい。) シェル変数の一覧は $ set で画面に表示される。(shでもsetで一覧表示。) 環境変数 /bin/shや/bin/bashの場合: $ export シェル変数名 のようにすることにより、シェル変数が同一の変数名で環境変数となる。 たとえば、 $ A=test $ export A など。環境変数の一覧は $ printenv で表示される。個々の環境変数の値は $ printenv A のように、環境変数名をprintenvコマンドの引数に与えると表示される。 /bin/tcshの場合: $ setenv A test のように、setenvコマンドを用いる。(=はないことに注意) 環境変数一覧、個々の値の表示については/bin/shと同じ。環境変数の 値も$環境変数名で参照できるが、同じ名前のシェル変数がある場合、 そちらが優先される。 環境変数の例 dateコマンド(日時の表示)を実行すると [sasano@oli004 4kai]$ date 2009年 10月 6日 火曜日 13:45:42 JST のようになるが、 [sasano@oli004 4kai]$ setenv LANG C のようにすると、 [sasano@oli004 4kai]$ date Tue Oct 6 13:47:27 JST 2009 のように英語表示になる。 (/bin/shの場合は、LANG=Cとしてからdateを実行 すればよい) シェル変数の例 PATH, HOME, USER, HOSTNAMEなどのシェル変数が 通常使われている。 $ echo $PATH $ echo $HOME $ echo $USER $ echo $HOSTNAME などで確認できる。 /bin/shでも/bin/tcshでも同じ。 シェルスクリプト • ファイルにシェルに対する命令(スクリプト)を書いた もの。 • 1行目に#!/bin/sh と書く。これによって、/bin/shがス クリプトを実行することになる。 – #!/bin/bash, #!/bin/tcshなど、他のシェルを指定し てもよいが、その場合はスクリプトの書き方は異な る。 • ファイルの属性を、実行を許可するように変更する必 要がある。 $ chmod 755 test.sh などのようにして変更できる。 例1(打ち込んで確認) (1)以下を中身とするtest1.shというファイルを作成 #!/bin/sh ls -l (2)ファイルの属性を変更 $ chmod 755 test1.sh (3)実行 $ ./test1.sh これによって、ls –lが実行される。あるいは、 $ /bin/sh test1.sh でもよい。 (4) カレントディレクトリのファイルリストが表示されることを 確認。 シェル変数の使用(打ち込んで確認) (1)以下を中身とするtest2.shというファイルを作成 #!/bin/sh A=ls B=-l $A $B (2)ファイルの属性を変更 $ chmod 755 test2.sh (3) 実行 $ ./test2.sh (4) カレントディレクトリのファイルリストが表示されるこ とを確認。(例1と同じ) for文(例1)(打ち込んで確認) #!/bin/sh for i in 1 2 4 do echo $i done 1 2 4 と表示されればOK。 echoは引数に与えられた文字列 を表示するコマンド。$iが文字列 に展開されてから表示される。 for文の構文、意味 構文 for variable in wordlists; do commands; done wordlists: 要素をスペースかタブで区切る。 commands: コマンドをセミコロンで区切る。 意味 wordlistsの要素を左から順番に変数variableに代 入し、commandsを実行する。 セミコロンは改行で置き換えてよい。 for文はコマンドであり、コマンドが書けるところには自由に書くこ とができる。例えばfor文の本体部分にfor文を書いてもよい。 for文の例2(打ち込んで確認) #!/bin/sh for D in `date` do echo $D done バッククオート`でコマンドを 囲むと、その部分がコマン ドの実行結果で置き換えら れる。 dateコマンドの出力結果に はスペースが含まれており、 スペースで区切られた一つ 一つがDに代入され、echo で1つずつ表示される。 for文の例3(打ち込んで確認) #!/bin/sh for L in * do echo $L done *はカレントディレクトリの ファイルがスペースで区切 られたものに展開される。 $ echo * で確認できる。 Lにはカレントディレクトリの ファイル名が一つずつ代入さ れ、それがechoで表示され る。 for文の例4(打ち込んで確認) #!/bin/sh for F in * do cp $F $F.bak done Fにはカレントディレクトリの ファイルのファイル名が一つ ずつ代入され、それがcp で.bakつきのファイルにコ ピーされる。 for文の例5(打ち込んで確認) #!/bin/sh for F in *.c do echo $F cp $F $F.bak done 第一回目に書いた シェルスクリプトは、 上記のシェルスクリプ トの最後にexit 0を加 えたもの。 *.cは、カレントディレクトリ において、ファイル名の最 後の部分が.cになっている ファイルのファイル名がス ペースで区切られたものに 展開される。 Fにはカレントディレクトリ の.cで終わるファイル名が一 つずつ代入され、それが echoで表示されたの ち、.bakつきのファイルにコ ピーされる。 構文 if文 if commands; then commands; [elif commands; then commands;]… [else commands;] fi commands: コマンドをセミコロンで区切ったもの [ ] はオプション(なくてもよいという意味)。 意味 if の隣に書かれたcommands(の最後のコマンド)の 終了statusが0ならthenパートを実行。そうでなけれ ばelif以下、あるいはelseパートを(もしあれば)実行。 セミコロンは改行で置き換えてよい。 if文はコマンドであり、コマンドが書けるところには自由に書くこと ができる。例えばif文のelseパートにif文を書いてもよい。 終了status コマンドは終了statusを返す。 シェルスクリプトではexit 0 等、exitの右に書く数によって 終了statusを指定する。 Cのプログラムでは、main関数のreturn文あるいはexitシ ステムコールの引数によって終了statusを指定する。 コマンドの終了statusはシェルが受け取り、$?という変数 に保持している。 (例) $ ls aaa $ echo $? もしaaaというファイルがなければlsコマンドの終了status が1になっている。 if文の例1(打ち込んで確認) #!/bin/sh if test $1 -le $2 then echo $1 is less than or equal to $2. else echo $1 is greater than $2. fi testは比較などさまざまな判定を行うコマンド。オ プションによりさまざまな判定が行える。 test arg1 –le arg2 は、arg1がarg2より小さいか どうか判定。 $1はシェルスクリプトの1番目の引数、 $2はシェルスクリプトの2番目の引数を表す。 if文の例2(打ち込んで確認) #!/bin/sh if diff $1 $2 > /dev/null then echo No differences were found between $1 and $2. else echo Some differences were found between $1 and $2. fi diffは2つのファイルの比較を行うコマンド。 終了statusは、同じとき0, 異なるとき1である。 diffコマンドの標準出力への出力は/dev/nullへリダイレクトさ れるので捨てられる。(リダイレクトについて後日解説する) testコマンドについて testコマンドは大小比較などさまざまな判定に使われる。 数値比較、文字列比較、ファイル形式の判定、ファイルの 修正時刻の比較などがある。さらに、条件をand, or, notで 組み合わせることもできる。 testコマンドは非常によく使われるので略記法がある。 test …は [ … ] と略記してよい。 例えば、test $1 –le $2は、[ $1 –le $2 ]と書ける。 [の次の空白と、]の手前の空白は省けないので注意。 if文の例3(打ち込んで確認) #!/bin/sh if [ $1 -le $2 ] then echo $1 is less than or equal to $2. else echo $1 is greater than $2. fi 例1におけるtest $1 –le $2を[ $1 –le $2 ]で置き 換えたもの。 ifコマンドについての補足1 ifコマンドはネストしてよい。例えば、elseパート有りのifコマンドを ネストして、 if … then … else if … then … else … fi fi のような形で使える。これは外側のifコマンドにおけるelseパート のコマンド(赤字の部分)がifコマンドになっているということである。 ifコマンドについての補足2 さきほどのifコマンドのネストは if … then … elif … then … else … fi のように書いてもよい。この場合はifコマンドのネストで はなく、1つのifコマンドである。
© Copyright 2025 ExpyDoc