シェル変数の定義と操作

shell script preprocess 2/N

公開日: 2021-02-09
更新日: 2024-02-29

  Table of Contents

シェルの復習

  • シェルはLinuxでOSとユーザーの仲立ちをするユーザーインターフェース
  • ユーザーが入力したコマンドを解釈&実行するインタプリタのこと
sequenceDiagram
    participant A as User
    participant B as bash
    participant C as command<br>今回はlsコマンド
    B->>A: プロンプト($)の表示
    A->>B: コマンド入力<br>ls command
    B->>B: コマンド解析
    B->>C: プロセス生成
    C->>C: プロセスが処理を実行
    C->>B: プロセス終了
    B->>A: 結果の出力<br>file A file B
    B->>A: プロンプト($)の表示

シェル変数と環境変数

シェルが扱う変数には

  • シェル変数: 設定されたシェルだけが使用する変数.子プロセスには引き継がれない,
  • 環境変数: 設定されたシェルとそのシェルで起動したプログラムが使用する変数,子プロセスに引き継がれる

の2種類があり,それぞれ確認方法や定義に差異があります.

TL;DR

  • シェル変数はsetで確認できるもの
  • 環境変数はexportdeclare -xで定義するもの,envprintrnvコマンドで確認できるもの

コマンドの実行結果をシェル変数に格納する

実行結果の変数定義

コマンドの実行結果をシェル変数に代入するには以下の2通りがある:

  • コマンドを$()で囲んで, その結果をシェル変数に代入する
  • コマンドをバッククォートで囲んで, その結果をシェル変数に代入する $


1
2
3
4
5
6
7
# (1) コマンドを`$()`で囲む場合
% a=$(which bash) && echo $a
/usr/bin/bash

# (2) コマンドをバッククォートで囲む場合
% a=`which bash` && echo $a
/usr/bin/bash

よくある間違いとして, =の前後に空白をいれるとエラーになります.

1
2
% a = $(which bash) && echo $a
a: command not found

これはシェルがaをコマンドと認識して, =以降を引数と解釈してしまっているからです. そのため, エラーメッセージもa: command not foundとなっています.

算術演算の場合

算術演算の結果を格納する場合は

  • exprを用いて上の「実行結果の変数定義」と同じ方法で代入する
  • 二重括弧(( ))を用いて, 変数に代入する $

例として,

1
2
3
4
5
6
7
8
9
10
11
12
% echo $((1+1)) 
2
% echo `expr 1 + 1`
2
% echo $(expr 1 + 1)
2`$`
% echo `((1+1))`

% a=`date +%H%M%S` && b=$(($a+10)) && echo $a $b
172112 172122
% a=2;b=8 && echo $((b<<a))
32

注意としては二重括弧(( ))を用いる場合はバッククォートの参照は上手く行きません.

<<はビットシフト演算子です. 最後の二重括弧の中の変数は$をつけないでも計算することができます. ただし, 基本的には変数は変数とわかるように$をつけたほうが良いと考えます.

Column: 主なシェル変数

変数名 説明
PWD カレントディレクトリの絶対パス
PATH コマンド検索パス
HOME ユーザーのホームディレクトリ
PS1 プロンプト定義
PS2 2次プロンプト定義
HISTFILE コマンド利益を格納するファイルパス
LANG 言語情報

unsetコマンド: 変数を削除する

シェル変数,環境変数問わず以下のコマンドで指定した変数を削除する(=未定義に戻す)ことができます.

1
% unset 変数名

空にするだけの場合は

1
% 変数名=

でも可能です.空にする場合と未定義に戻すことに違いは シェルスクリプトなどでよく見るset -uで未定義の変数を参照した場合にエラーを返すか返さないかの違いとなります.

1
2
3
4
5
$ echo $a

$ set -u
$ echo $a
bash: a: unbound variable
bash zsh
set -u unsetopt unset or set -u
set +u setopt unset or set +u

一時的に変数を作成して続けて実行するコマンドに渡す

一時的にコマンドへ変数を渡す場合

一時的に変数VARを作成し, 続けて実行するCOMMANDにて一時的に変数VARを使用する場合は 以下のようにCLIへ入力する

1
$ VAR="Kirby" COMMAND

bashシェルスクリプトファイル testshellを以下のように独自に定義する

1
2
3
#!/bin/bash

echo $VAR

このとき, シェル変数を定義するのみだとtestshellはシェル変数を参照することができません.

1
2
3
4
5
6
$ set | grep "^VAR"
VAR=Kirby
$ set | grep "^VAR="
VAR=Kirby
$ bash testshell

一方, 以下のように同じラインで定義 & 実行をするとシェル変数を参照してくれます.

1
2
$ VAR="Kirby" bash testshell
Kirby

最後に$ echo $VARを続けて実行すると,あくまで$VARは一時的に定義された変数なので, 次回以降のプロンプトではundefinedとして処理されます.

1
2
3
4
5
6
$ VAR="Kirby" bash testshell
Kirby

# 続けて実行すると何も出力されない
$ echo $VAR

変数の操作

変数の一部を使用する:変数展開

変数名の一部を使用したい場合は, ${変数名:開始位置:長さ} のように指定することで 部分文字列のみを抽出することができます,

指定パターン 挙動
${変数名:開始位置:長さ} 開始位置から指定した長さ分の文字列を切り出す
${変数名#パターン} パターン部分(前方一致)を削除. #の場合は最短一致
${変数名##パターン} パターン部分(前方一致)を削除. ##の場合は最長一致
${変数名%文字列} パターン部分(後方一致)を削除.%の場合は最短一致
${変数名%%文字列} パターン部分(後方一致)を削除.%%の場合は最長一致
${変数名:-文字列} 変数の内容を取得.
変数がセットされていない場合は指定した文字列を返す
${変数名:=文字列} 変数の内容を取得.
変数がセットされていない場合は文字列.
変数がセットされていない場合は変数に指定した文字列をセットした上で返す
${#変数名} 変数の文字数(配列の場合は要素数)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
% echo "$LANG" 
en_US.UTF-8
% echo "${LANG:0:5}" #先頭5文字
en_US
% echo "${LANG#*U}" #前方一致削除(最短)
S.UTF-8
% echo "${LANG##*U}" #前方一致削除(最長)
TF-8
% echo "${LANG%U*}" #後方一致削除(最短)
en_US.
% echo "${LANG%%U*}" #後方一致削除(最長)
en_
% echo ${#LANG}
11

文字列変数の結合

文字列変数の結合

文字列を連結させたいときは大まかに以下2種類の方法がある:

  • $var_A$var_Bと続けて記述
  • 各変数の定義後, var_A+=$var_Bすると, $var_Aの中身が結合した文字列になる
1
2
3
4
% a="Bob"; b="Mary"; echo $a$b
BobMary
% a="Bob"; b="Mary"; a+=$b; echo $a  
BobMary

文字列変数の置換

パターン 挙動
${変数/検索文字列/置換文字列} 最初にマッチしたもののみ文字列を置換
${変数//検索文字列/置換文字列} 全ての文字列を置換
1
2
3
4
5
6
# 前方一致
% a="bobbobobob"; echo $a ${a/ob/ca}   
bobbobobob bcabobobob
# globalで変換
% a="bobbobobob"; echo $a ${a//ob/ca}
bobbobobob bcabcacaca


Share Buttons
Share on:

Feature Tags
Leave a Comment
(注意:GitHub Accountが必要となります)