IT・技術研修ならCTC教育サービス

サイト内検索 企業情報 サイトマップ

研修コース検索

コラム

WSLで始めるUbuntu

CTC 教育サービス

 [IT研修]注目キーワード   Python  UiPath(RPA)  最新技術動向  Microsoft Azure  Docker  Kubernetes 

第27回 bashの展開機能を知ろう(3) (宮崎悟) 2021年1月

前回はbashの展開機能の、変数の配列と変数の展開について説明しました。今回は算術式展開、コマンド置換、プロセス展開について説明します。

算術式展開

以下のように式を記述すると、算術計算を行い結果を出力します。ここで実行可能な演算は、整数演算のみです。

# 四則演算と剰余(すべて整数演算になる)
$ echo $((1+1)) $((10-5)) $((5*2)) $((10/3)) $((10%3))
2 5 10 3 1
# () を使用した演算
$ echo $(((2*5)/(4-1))) $(((2*5)%(4-1)))
3 1
# 変数の展開も可能
$ AAA=100
echo $(($AAA/3)*3))
99
# 小数点演算は不可能
$ AAA=100.0
$ echo $(($AAA/3*3))
-bash: 100.0/(100.0/33)*3: 構文エラー: 無効な計算演算子です (エラーのあるトークンは ".0/(100.0/33)*3")

数値として使用できるのは、以下の定数です。

定数 説明
n進数 n#で始まる数値。nは2~35の数値。nが10以上の場合、a-zA-Z@の順に使われます。<br />nが36以下の場合は、アルファベットの大文字小文字の区別をしません。<br />n#を省略すると10進数として扱われます。 2#1111<br />16#13abc<br />32#1STUV
10進数 先頭が0で始まらない数値 123456
8進数 先頭が0で始まる数値 012345
16進数 先頭が0xもしくは0Xで始まる数値 0xDEADBEAF

使用できる演算子は以下のとおりです。優先される演算の順に並べています。

演算子 説明
id++ , id-- 変数を評価し、その後 increment (加算)/ decrement (減算) する。
++id , --id 変数を increment (加算) / decrement (減算) してから評価する。
- , + 単項式の負、正
! , ~ 論理的否定、ビット単位の否定
** 指数 (累乗)
* , / , % 乗算、除算、剰余
+ , - 加算、減算
<< , >> 左ビットシフト、右ビットシフト
<= , >= , <, > 左式と右式の比較。左式が大きいか同じ、右式が大きいか同じ、左式が大きい、右式が大きい
== , != 等値、非等値
& ビット単位の AND
^ ビット単位の排他的 OR
` `
&& 論理的 AND
`
expr? expr1:expr2 条件付き実行(exprが正のときexpr1を実行、負の場合にexpr2を実行)
= , *= , /= , %= ,+= , -= , <<= , >>= , &= , ^= , ` =`

小数点演算を行いたい場合は、bc コマンドを使います。bc コマンドのデフォルトは整数演算ですが、-l オプションを指定すると小数点演算を行います。

$ AAA=100.0
$ echo "$AAA / 3 * 3" | bc -l
99.99999999999999999999
コマンド置換

bashでは、以下のように`command`もしくは$(command)のようにコマンドを実行すると、実行した標準出力を文字列として展開します。もちろん、パイプや変数などを使用可能です。

$ ls -1
aaa
bbb
ccc
ddd
eee
fff
# `` を使用した方法
$ AAA=`ls -1`
# ""で囲まないと、改行が空白に置き換えられる
$ echo $AAA
aaa bbb ccc ddd eee fff
# ""で囲むと改行をそのまま使用する
$ echo "$AAA"
aaa
bbb
ccc
ddd
eee
fff
# $()を使用した方法(パイプを使用)
$ BBB=$(echo $AAA | grep -e '^[abe]')
$ echo $BBB
aaa bbb ccc ddd eee fff
# 変数を""で囲むと、改行として使用する
$ CCC=$(echo "$AAA" | tac)
$ echo $CCC
fff eee ddd ccc bbb aaa
プロセス置換

コマンド置換に似ています。>(コマンド)という構文は、コマンドの結果を標準入力として利用します。同様に、標準出力として(<(コマンド))を使用できます。この機能は、色々なコマンドと組み合わせることで価値が出ます。

以下は、プロセス内容を標準入力として使用する例です。

# 標準エラー出力のみを表示し、かつファイルに追記する
$ ls tmp/aaa tmp/ggg 2> >(cut -d' ' -f 4- | tee -a errorlog > /dev/null)
/tmp/aaa
$ ls tmp/aaa tmp/zzz 2> >(cut -d' ' -f 4- | tee -a errorlog > /dev/null)
/tmp/aaa
$ cat errorlog
ls: 'tmp/ggg' にアクセスできません: そのようなファイルやディレクトリはありません
ls: 'tmp/zzz' にアクセスできません: そのようなファイルやディレクトリはありません
# 標準エラー出力の内容のみを変更する
$ export LC_ALL=C 
$ ls tmp/aaa tmp/ggg
ls: cannot access 'tmp/ggg': No such file or directory
tmp/aaa
$ ls tmp/aaa tmp/ggg 2> >(cut -d' ' -f 4- )
tmp/aaa
'tmp/ggg': No such file or directory

以下は、プロセス内容を標準出力として使用する例です。

$ ls tmp tmp2
tmp:
aaa  bbb  ccc  ddd  eee  fff
tmp2:
aaa  ccc  eee  ggg
# diffは、標準入力2つを受け取り差分として使用できる
$ diff -u <(ls -1 tmp) <(ls -1 tmp2)
--- /dev/fd/63  2021-01-09 21:17:25.699834878 +0900
+++ /dev/fd/62  2021-01-09 21:17:25.699834878 +0900
@@ -1,6 +1,4 @@
 aaa
-bbb
 ccc
-ddd
 eee
-fff
+ggg
# lddはコマンドやライブラリが必要とするライブラリの一覧を表示するコマンド
$ ldd /lib/x86_64-linux-gnu/libcurl.so.4
        linux-vdso.so.1 (0x00007ffc19144000)
        libnghttp2.so.14 => /lib/x86_64-linux-gnu/libnghttp2.so.14 (0x00007ffadcb9b000)
        libidn2.so.0 => /lib/x86_64-linux-gnu/libidn2.so.0 (0x00007ffadcb7a000)
        (中略)
        libsqlite3.so.0 => /lib/x86_64-linux-gnu/libsqlite3.so.0 (0x00007ffadb9ad000)
        libcrypt.so.1 => /lib/x86_64-linux-gnu/libcrypt.so.1 (0x00007ffadb972000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ffadb823000)
# ldd の最初のフィールドのみの差分を取得する
$ diff -u <(ldd /lib/x86_64-linux-gnu/libcurl.so.4| cut -d' ' -f 1| sort) \
          <(ldd /lib/x86_64-linux-gnu/libcurl-gnutls.so.4| cut -d' ' -f 1 | sort)
--- /dev/fd/63  2021-01-09 21:20:22.522481235 +0900
+++ /dev/fd/62  2021-01-09 21:20:22.522481235 +0900
@@ -37,7 +37,6 @@
        libsasl2.so.2
        libsqlite3.so.0
        libssh.so.4
-       libssl.so.1.1
        libtasn1.so.6
        libunistring.so.2
        libwind.so.0
終わりに

今回は算術式展開、コマンド置換、プロセス展開について説明しました。プロセス展開は、プロセスの実行結果を変数に入れるなど、役立つパターンが多いので覚えおきましょう。次回は、単語分割とパス展開について説明します。次回をお楽しみに。

 


 

 [IT研修]注目キーワード   Python  UiPath(RPA)  最新技術動向  Microsoft Azure  Docker  Kubernetes