シェルスクリプトサンプルコードでよく見かけるtypesetやdeclareってなに?

2019-03-09Bash, Cygwin, Linux, Ubuntu

後日投稿したエントリで、サンプルコードとともに検証をしてみました。
興味があればそちらも御覧ください。


古いシェルスクリプトコードでは、以下のような命令で変数を宣言する方法が取られていることが多いです。

# 宣言
$ VAR1=123

# 出力
$ echo "$VAR1"
123

一方、Web上でシェルスクリプトのサンプルを見ていると、
typesetdeclare を使って変数を宣言している例をよく見かけます。

それぞれの違いと使い方について調べてみました。

変数宣言の方法は3つ

改めて Bash の変数宣言方法を列挙してみます。

Bashでは 宣言なしに変数を生成 することができるが、 明示的に宣言し変数を生成 することもできます。
変数の生成方法は以下の3つ。(だと思っている)

  • VAR1=123
  • typeset VAR1=123
  • declare VAR1=123

それぞれの違いは何?宣言型の場合、便利な機能もありそうなので調べてみました。

typeset / declare なしの変数宣言

最もよく見る変数宣言方法。
記述もシンプルで流れるようにコーディングしているときにはよく記述します。

$ X=hello

$ echo "$x"
hello

typeset を使った変数宣言

$ typeset X=hello

$ echo "$x"
hello

一緒に見えますね。

declare を使った変数宣言

$ declare X=hello

$ echo "$x"
hello

これも一緒!?
困ったので man ページを見る!

typesetコマンドとは

こちら Bash のビルトインコマンドのようですね。

% type typeset
typeset is a shell builtin

man コマンドで bash のマニュアルをのそいてみます。

$ man bash
...(一部省略)...
       declare [-aAfFgilnrtux] [-p] [name[=value] ...]
       typeset [-aAfFgilnrtux] [-p] [name[=value] ...]
              Declare  variables  and/or give them attributes.  If no names are given then
              display the values of variables.  The -p option will display the  attributes
              and  values  of  each name.  When -p is used with name arguments, additional
              options, other than -f and -F, are ignored.  When  -p  is  supplied  without
              name  arguments,  it will display the attributes and values of all variables
              having the attributes specified by the  additional  options.   If  no  other
              options are supplied with -p, declare will display the attributes and values
              of all shell variables.  The -f option will restrict the  display  to  shell
              functions.  The -F option inhibits the display of function definitions; only
              the function name and attributes are printed.  If the extdebug shell  option
              is enabled using shopt, the source file name and line number where each name
              is defined are displayed as well.  The -F option implies -f.  The -g  option
              forces  variables  to  be created or modified at the global scope, even when
              declare is executed in a shell function.  It is ignored in all other  cases.
              The  following  options can be used to restrict output to variables with the
              specified attribute or to give variables attributes:
...(一部省略)...

と表示され、答えは一目瞭然。両者に違いはありません。

ただ、 Shell Style Guide のサイトを調べてみると、 declare 命令に関する記述はいくつか見つかりますが、 typeset に関する記述が皆無なので、 declare を使うのが良さそう。別のサイトには、 typeset は非推奨となったビルトインコマンドだという記述もありました。(ソースは見失った、、、)

declareコマンドとは

上記で見てきたとおり、 bashビルトインコマンド

manコマンドを見ると、オプションが多数あります。
オプションを指定して変数の宣言時に型をできます。
その他、プリントデバッグ(変数の型や中身を確認)できたり、読み取り専用にしたり、大文字、小文字への変換を強制するなど、変わった機能もあります。

declareコマンドのオプション

オプションと機能の概要をざっと列挙してみます。

オプション 機能の概要
-A 連想配列として変数を宣言
-a 配列として変数を宣言
-i 整数として変数を宣言。 = の右辺を数式として認識し評価結果を代入。
-l 大文字を自動的に小文字に変換する変数 を宣言
-u 小文字を自動的に大文字に変換する変数 を宣言
------------ ---------------------------------------------------------------------
-r 読込専用な変数を宣言。値を代入したり unsetしたりできなくなる。
------------ ---------------------------------------------------------------------
-x 変数をエクスポート。 export と同義
-f 定義されている関数名を出力
-p 定義されている変数を出力(プリントデバッグ)

オプション無しの変数宣言はみんな一緒!

オプションを指定して初めて typeset / declare 命令が生きてきます。
オプション無しでは VAR1=123 の記述でも十分なんですね。

オプション機能がとっても便利そうだがここでは書ききれない

使いこなせるとシェルスクリプトがとても書きやすくなりそうなので、今後のエントリでサンプルコードとともに取り上げていこうと思います。

一旦ここまで。


後日投稿したエントリで、サンプルコードとともに検証をしてみました。
興味があればそちらも御覧ください。

2019-03-09Bash, Cygwin, Linux, Ubuntu