見出し画像

【Linux】 シェルスクリプトまとめ

シェルスクリプト

実行するコマンドをファイルに記載したもの。ファイルをシェルに読み込ませることで実行できる。コメントは#。

シェル

UNIX系OSのログイン時に最初に動作するプログラムのこと。

UNIX系の標準シェルはsh(Bourne Shell)
Bシェル系:shから派生したものだが、機能が少なく低機能。
Cシェル系:cshから派生したもの。cshはヒストリやエイリアスなどの機能を加えて、C言語風に改変したもの。標準エラー出力のみのリダイレクトができない、シェル関数が使えないデメリットがある。
bush:shの上位互換としてcshの機能を取り入れて、タブによるファイルやコマンド名の補完機能やコマンドライン編集機能を追加したもの。Linuxの標準シェル。
ログインシェルの変更は、chsh -s ファイル名(/bin/bush)で行う。


構築シェル



コマンド

単純コマンド:ls や cp など
複合コマンド:if や for文、シェル関数のこと
パイプライン:コマンドがパイプ(|)で繋がったもの
リスト:パイプラインがセミコロン(改行、;、&、&&、||)で繋がったもの
&&:初めのパイプラインが真の時のみ後のパイプラインが実行される。両方とも真の時のみ &&リストが真になる。
||:初めのパイプラインが偽の時のみ後のパイプラインが実行される。
          どちらかが真の時に ||リストが真になる。


case文(case 文字列 in []  …  esac)

  ・終了は ;; を付ける。最後のリストだった場合は省略ができる。
  ・|で区切ればOR条件となる。
  ・) を各条件の最後につけることで条件の終わりを告げる。
   条件の最後に *) を付けると設定した条件以外のパターンを検証する。
   break文に相当するものが ;& になる。
   一度一致しても継続して検索するときは ;;& をつける。複数のパターンの実行ができる。

for文(for 変数  in …  ; do ; done)繰り返し

  ・カレントディレクトリ内にある全てのファイルに処理を行うときは「for file in * 」がよく使われる。
  ・何も実行したくないときは : を入れる。(doとdoneの間など)
  ・算術式 (exp:i = 0; i < 10; i++)も使える。

while文 ⇄ until文(偽が続く限り)

  ・expr はシェル変数を更新するために使われる
  ・shift はシェルの位置パラメータをシフトする

※for , while文ともにbreak , continue は使える。
 break は引数を指定することで何重かのループも抜け出せるようになる。(break 2 = 二重ループを抜ける)
 continue は引数を指定することで何重かのループも抜け出せるようになる。(continue 2 = 二重ループを抜ける)

select文(select 変数  in …; do リスト; done)

選択内容を表示してユーザーに選ばせることで入力内容によって表示内容を変える時に使うユーザーの入力は「REPLY」に入力される。

( ):サブシェル
元のシェルに影響を出すことなく一時的な処理を行い時に囲む。
{ }:グループコマンド
元のシェルに影響する

シェル関数

  ・設定した関数の解除は unset を使う。
  ・シェル関数内で自分自身の関数を呼び出す再帰呼び出しも行える。
  ・ローカル変数として使いたいときは()を使うことになる。
  ・{ } ないで local を使うことでローカル変数の設定ができる。

(( 算術式 )):算術式で使う
  ・演算結果を終了ステータスではなく、途中で利用した場合は $(( )) とする。

[[ 条件式 ]]:条件式を評価して終了ステータスを返す

組み込みコマンド
 :コマンド:
nullコマンド。0のステータスを返す=true。コマンドを実行したくない時やパラメータだけ設定したい時にも使う。
 : > file とすることでファイルサイズ0のファイルが作られるが、同じファイル名が既にあるときはそのファイルが0になる。なので、ファイルの中身を消去したい時にも使われ、 > file と省略もできる。
 . コマンド ファイル名:指定したファイルを今のシェルに読み込ませる。複数のシェルスクリプトに共通したシェル変数やシェル関数をあらかじめファイルに書き込んでおき、シェルスクリプトに読み込ませて実行すると便利に使える。

 cdコマンド:使い方はシェル上のコマンドラインと同じだが、シェル上でのカレントディレクトリが変更されることはない。()ないで処理することでサブシェルとしても使える。

 eval 変数:引数の解釈が2回行われることになり、配列変数を使わずに配列と同じような処理を行うのに有用。 exp:” \$$var \” と表すことで $var の値をシェル変数として使うことができる。

 exec 外部コマンド:新しいプロセスが作成されずに、今のプロセスIDのままで新しいコマンドに置き換わることになる。余分なプロセスを消費することがなくなる。

 exit (終了ステータス):エラーなどでシェルスクリプトの実行を中断するときなどに使用する。

 export (変数):シェル変数を環境変数として設定する。(2段階の処理が必要)printenv 変数 で現在設定されている環境変数の確認ができる。先にexportした後でシェル変数を設定しても問題なく、複数の変数を同時に設定することもできる。unset で設定解除ができるが、シェル変数まで未設定の状態に戻ることになるので再設定が必要になってくる。環境変数のみ解除するときは export -n を使用する。また、変数と値の後に単純コマンドを入れると一時的に環境変数を変更することができる。

 declare : シェル内の変数と関数を全て表示し、 -xをつけることで環境変数として設定できる。

 getopts オプション 変数:起動時にシェルスクリプトにつけられたオプションを解釈するのに便利。
オプションには、 -c , -v ,  -i file , -o file などがある。
また、オプション解釈が終了するまで繰り返して呼び出して使用するので、while文と使うのが一般的。

 read 変数:ユーザーからキー入力を受け付けたい時に使われる。
       read -p でechoを使わずにプロンプトの表示ができる。
       -r はバックスラッシュを文字として入力できるようになる。
       -t は入力時間を過ぎた時に終了ステータスで終了する。(read -t 5 →5秒まち)
       -s は文字数の入力制限(バイト指定)ができる。

 readonly (変数):シェル変数のみを読み込み専用にする。変数を定数として扱いたいときや、誤って値の変更したりunsetでのプログラムミスを防ぐことにもなる。複数の設定もできる。

 return (終了ステータス):実行中のシェルを終了してシェル関数の呼び出しもとに戻る。読み込んだファイルでも実行を終了できる。主にエラーが出たときの中断として使われる。

 set -or+ オプションフラグ 引数:シェルにオプションフラグや位置パラメータをセットする。- はオプションがセットされ、+ はオプションがリセットされる。引数なしで実行するとシェル変数とその値が一覧表示される。
位置パラメータをセットしたいときは - - をつけてオプションとして認識されないようにする必要がある。

 unset:指定された変数や関数を削除する。シェル変数をexportしていたときは環境変数とシェル変数ともに削除となる。readonly されているものや位置パラメータ、特殊パラメータは削除できない。

 shift シフト回数:while文で引数を順番に解釈しながらループする時に主に使われる。引数の読み込み開始位置を後ろにずらすこと。

 trap コマンド  シグナル信号:シグナルを受け取った時に指定のコマンドを実行させる。コマンドを省略すると指定した信号の設定が解除される。

 type コマンド:各種コマンドが実装されているか、外部コマンドか組み込みコマンドかシェル関数かを判断する。外部コマンドであればPATH上のどのディレクトリにあるのかを調べることができる。

 umask マスク値:umaskの値を設定する。

 wait プロセスID:バックグラウンドで実行中のプロセスの終了ステータスを取得できる。プロセスを指定しなければバックグラウンドで実行中の全てのプロセスを終了する。

 echo:引数で指定された文字列を出力する。引数は基本的に’ ‘ で囲った方が良い。

 false 引数:常に偽を返し、1の終了ステータスを返す。

 true 引数:常に真を返し、0の終了ステータスを返す。

 kill シグナル プロセス:指定のプロセスにシグナルを送り、デフォルトではプロセスの終了となる。-l をつけると指定可能なシグナルの一覧が表示される。

 printf フォーマット文字列 引数:数値や文字列を一定の書式に整形して表示する。(10進数や16進数)

 pwd:カレントディレクトリの絶対パスを表示する。-P を付けると本来の物理的なディレクトリの絶対パスを表示する。

 test or [ ]  条件式:条件判断に使われる。文字列の比較は = 、< > ( ) を使うときは \ を付ける必要がある。

 builtin コマンド名 引数:シェル関数と同名のコマンドを設定しても、組みコマンドを優先させる。
 
 command コマンド名 引数:シェル関数と同名のコマンドを設定しても、組み込みコマンドや外部コマンドを優先させる。さらに組み込みコマンドと外部コマンドでは組み込みコマンドを優先させる。

 let 算術式:指定された算術式を評価して真偽を判定する。(( )) とほぼ同じ。算術式はシングルクォートで囲む必要がある。

 local 変数:指定した変数をローカル変数として取り扱う。( ) サブシェルと同じ機能を持つが移植のことを考えればサブシェルを使った方がいい。値を代入する前にlocal を入れる必要がある。

パラメータ

 シェル関数:値に’ ‘ をつけて代入したり、”$ “ とすることで参照が使えるようになる。

 位置パラメータ:シェルスクリプトやシェル関数の引数を参照する。($1,$2,$3….)setコマンドを使用したり、ファイルを作成することで設定できる。また、10以降の数値になると数値に{ } を付ける必要が出てくる。その他にもshift を使って表示させる。( )も使って元の位置パラメータが失われないようにする。

 特殊パラメータ
  ・”$0” はシェルスクリプトそのものがセットされるもの。
  ・“$@“ はシェルスクリプトやシェル関数の引数を全て引き継ぐ。
  ・”$*” は引数全体を参照することができる。$* は「$1 $2 $3 」と展開され、”$*” は「”$1 $2 $3”」と展開される。
  ・$# はシェルスクリプトやシェル関数の引数の個数を参照する
  ・$? 直前のリストの終了ステータスを参照する。
  ・$! もっとも新しくバックグラウンドで起動したコマンドのプロセスIDがセットされる。wait や killコマンドを実行するときなどに使う。
  ・$$ シェル自身のプロセスIDを参照する。テンポラリファイル名を作る時に使われる。
  ・$- 現在のシェルのオプションフラグを参照する。
  ・$_ 直前に実行したコマンドの最後の引数を参照する。最後の引数を利用して別のコマンドを実行する時に便利になる。

 PATH:外部コマンドの検索パスを設定する。新たに設定するときは過去のものを引き継ぐように、$PATH を入れるといい。

 PS1:プライマリプロンプトでコマンドラインの$ や # のこと
 PS2:セカンダリプロンプトのことで、構文などが途中で改行されてコマンドが完結していない状態を表す。記号は > 。

 HOME:自分自身のホームディレクトリの絶対パスが設定されているシェル変数。

パラメータの展開

 パラメータのデフォルト値を指定する
  “${パラメータ:- 値 }”:パラメータが設定されていない、空文字列の時に指定した値に展開されそれ以外はパワメータの値に展開される。
  “${パラメータ - 値 }”:パラメータが設定されている時に指定した値に展開され、それ以外はパワメータの値に展開される。

 パラメータが設定されている時に指定の値に展開する
  “${パラメータ:+ 値 }”:空文字列以外の時に指定の値に展開され、空文字の場合は空文字列に展開される。
  “${パラメータ + 値 }”:パラメータが設定されている時に指定した値に展開される。それ以外は空文字列に展開される。

 パラメータにデフォルト値を代入する
  “${パラメータ:= 値 }”:パラメータが設定されていない、空文字列の時に指定した値が代入されてその値で展開する。
  “${パラメータ = 値 }”:パラメータが設定されている時に指定した値に代入され、それ以外はパワメータの値に展開される。

 パラメータ未設定時にエラーメッセージを出してシェルスクリプトを終了する。
  “${パラメータ:? 値 }”:パラメータが設定されていない、空文字列の時に指定した値がエラーメッセージとして表示されてシェルスクリプトを終了する。それ以外は通常通りパラメータ自身の値で展開する。
  “${パラメータ ? 値 }”:パラメータが設定されていない時に指定した値がエラーメッセージとして表示されてシェルスクリプトを終了する。単純にパラメータが設定されているかどうかだけで判断している。

 パラメータの値の文字列の長さを求める
  ${#パラメータ }:パラメータの値の文字列の長さの数値に展開される。

 パラメータから一定のパターンを取り除く
  “${パラメータ # パターン }”:パラメータの文字列の左からパターンに一致する最短の部分を取り除く。
  “${パラメータ ## パターン }”:パラメータの文字列の左からパターンに一致する最長の部分を取り除く。
  “${パラメータ % パターン }”:パラメータの文字列の右からパターンに一致する最短の部分を取り除く。
  “${パラメータ %% パターン }”:パラメータの文字列の右からパターンに一致する最長の部分を取り除く。

 オフセットや長さを指定してパラメータから文字列を切り出す
  “${パラメータ : オフセット}”:パラメータの文字列の左からオフセット個の文字を取り除いて展開する。 $ echo “${変数 : 数値}
  “${パラメータ : オフセット : 長さ}”:パラメータの文字列の左からオフセット個の文字を取り除き、長さ分の文字列に展開される。

 パターンを指定してパラメータの文字列を置換する
  “${パラメータ / パターン / 置換文字列}”:パラメータの文字列の左から見て、最初にパターンに一致した文字列を置換する。
                     

$ echo “${変数 / 文字列 / 置換}
  “${パラメータ // パターン / 置換文字列}”:パラメータの文字列の中で、パターンに一致する全ての文字列が置換される。

 現在セットされているシェル変数のうち、特定の文字や文字列で始まるものを表示する。
  ${! 変数 @ or * }:”${! 変数 @ or * }” = “$@“ , “$*”と同じになる。

 パラメータの値をパラメータ名とみなしてその値を参照する
  ${! パラメータ}:シェル変数などを別のシェル変数に代入したときなどに、後のシェル変数をパラメータとして参照すると、最初のシェル変数に代入した値が返される。

クォートとコマンド置換
 ‘ ‘:文字列を表示する。
 “ “:文字列を表示するものの、$ や ‘ などのパラメータ展開やコマンド置換は行われる。
 \:直後の一文字を文字列として表示する。改行も意味がなくなる。
 ` `:バッククォート内で行われたコマンドの出力を表示する。 $ , ` , \ の直前の \ は解釈される。ネスティングもできる。$( ):` ` とほぼ同じ意味。$ , ` , \ の直前の \ は解釈されない。ネスティングもできる。

展開

 :指定の文字列にマッチするファイルと照合して、マッチしたパス名をアルファベット順に展開する。/ をパス名展開に含めて、カレンとディレクト以外のファイルにマッチさせることもできる。

 ?:任意の1文字にマッチするファイルと照合して、マッチしたパス名をアルファベット順に展開する。/ をパス名展開に含めて、カレンとディレクト以外のファイルにマッチさせることもできる。

 文字列 [ 文字 文字 ] (ファイル名など)
 文字列 [ 文字 - 文字 ] (ファイル名など)
 文字列 [ !文字 文字 ] (ファイル名など)
 文字列 [ !文字 - 文字 ] (ファイル名など):いずれもファイルと照合して、マッチしたパス名をアルファベット順に展開する。
 
 文字列 { , , } 文字列:{ }の中に書かれたカンマで区切られた文字列を左から順番に使用して文字列を生成する。規則性のない複数のファイルを一括で指定するときなどに使う。case文では使えない。

 $(( )):算術式を評価して、その結果を数値として展開する。$[ ] でもbashでは使える。

 ~ ユーザー名:ユーザーのホームディレクトリのパス名に展開する。シェルスクリプトでは “&HOME” を使用した方がいい。(移植性が下がる)

 <( ) , >( ):プロセス置換。FIFO(名前付きパイプ)を作り、それに複数のプロセスを起動させそのFIFO名に置換する

 IFS(単語分割):デフォルトでシェル変数IFSにスペース、タブ、改行がセットされていて、それを区切りとして分割が行われ、PATH名などの分割表示が可能となる。


リダイレクト

 <:コマンドの入力をファイルにリダイレクトする。キーボードから文字列を読み込む代わりにファイルから読み込むようになる。

 >:コマンドの出力をファイルに出力する。文字列を画面に出す代わりにファイルに書き込むようになる。ファイルがない場合は新しく作成されるが、すでにあるときはファイルの中身が消去されることになる。

 >>:アペンドモードとなり、コマンドの出力がファイルの最後尾に追加されるようになる。ファイルがない場合は新しく作成されるが、すでにあるときはファイルの中身が消去されることにはならない。

 2>:コマンドのエラー出力をファイルに出力する。/dev/null にリダイレクトすると、エラーメッセージを表示しないようにできる。

 >&:オープン済みの標準出力やエラー出力を複製する。

 &>:標準出力やエラー出力を同時に指定したファイルにリダイレクトする。

 >&- , <&-:左に書かれる番号のファイル記述子がクローズされる。

 <>:左に書かれる番号のファイル記述子が右に指定されるファイルに読み書き両用でオープンされた状態でリダイレクトされる。

 ‘EOF’:ヒアドキュメント本体の内容をコマンドの標準入力にリダイレクトする。

 <<<:ヒアストリング。右側の ’ ‘ で囲まれた文字列をコマンドの標準入力にリダイレクトする。

 

外部コマンド

 expr:シェル変数の値に変化を及ぼすときに使われ、その結果を標準出力に出力する。(( )) , $(( )) で展開することもできるが、移植性を考えて使うのが基本。

 basename:引数で指定されたファイルのディレクトリ部分や拡張子を取り除く。ループ分を使うことで拡張子の変更を行うこともできる。

 dirname:引数で指定されたファイルのディレクトリを取り出す。ループ分を使うことで拡張子の変更を行うこともできる。

 cat:引数で指定したファイルを連結して標準出力に出力したり、ファイルの内容表示する。

 sleep 秒数:指定した秒数だけ待つコマンド。ループ中では一定時間ごとに動作を行う時に使われたりする。

 wc:ファイルの行数、単語数、ファイルサイズの表示
 cmp:ファイルの比較
 diff:ファイルの差分を抽出
 date:日付と時刻を表示
 sed:正規表現による文字列の置換など
 awk:各種文字列処理ができるスクリプト言語
 find:一定条件のファイルの検索
 xargs:標準入力を引数に取り込んでコマンドを起動

配列への代入と参照
 
 array[3]=‘hello world’ ; echo “${array[3]}”  参照するときは{ } で囲む必要がある。
 array=( one two three) ; echo “${array[@]}”   一括代入。
 unset  配列の削除で使われ、個別でも全体でも削除することができる。
 
 ※evel コマンドを使っても配列と同様の処理ができるが、記述が複雑になる。しかし、移植性の高いシェルスクリプトにもなる。

定石

 解釈:1回→ ‘ ‘ 、2回→ \ ‘ ‘ ’ \ ‘ 、3回→\\\ ‘  \ ‘  ‘ ’  \ ‘ \\\ ‘

 文中のシングルクォートの表示: ‘ = ‘ \ ‘ ‘と変換できる。
 文字列中にパラメータ展開を含ませたい:シングルクォートを一旦閉じて、その後にダブルクォートで  “$  “と表記する。

 ラッパースクリプト:環境変数の設定など、前処理を行った上で起動するようにしたシェルスクリプトのこと。シェルの解釈を行わずに引数を全て渡すには、 “$@“ を使う。また、プロセスを無駄にしないためにも、execコマンドは最後に使うのが定石。日付を含むファイル名の作成:date +%Y%M%D%H%M%S で表すことができる。

サンプルスクリプト(シェルスクリプトを作る)

 argcheck:式が長くなると一目でどの引数がコマンドに渡されているのかわからなくなる。argcheck のシェルスクリプトを作っておくことで引数の解釈状況を確認することができる。

 echocheck:標準出力やエラー出力の出力先を確認できる。

 ectract:.tar.gz , .tar.bz 形式の圧縮アーカイブを、引数として使用することで自動で展開が行われる。

 sjistoeuc:ディレクトリ上のShift_JIS で書かれたファイルをEUC-JP に一括変更する。

 kanji:EUCーJPの文字を一覧出力する。


よろしければサポートお願いします!よりいい情報を発信します。