UNIX/Linuxの部屋 用語集:シェル記号類まとめ

TOP UNIX/Linuxの部屋 UNIX/Linuxコマンド一覧 用語集 新版 由来/読み方辞書 環境変数マニュアル Cシェル変数 システム設定ファイル システムコール・ライブラリ ネットワークプログラミングの基礎知識 クラウドサービス徹底比較・徹底解説




用語集 シェル記号類まとめ sh・csh・tcsh・bash などのシェル・シェルスクリプトの記号まとめ (> >> 2>&1 < << $$ >& & && ( ) | || <<- <& >| <>) このエントリーをはてなブックマークに追加

最終更新


UNIX/Linux の sh・bash、csh・tcsh など、シェルやシェルスクリプト関連の記号類をまとめてみる。



> >> 2>&1
リダイレクト。> はファイルへの出力を、>> はファイルへの追記を表す。

$$: プロセスID
プロセス ID を表すシェルの変数。sh 系・csh 系を問わず、あらゆるシェルで利用可能。

<<: ヒアドキュメント
ヒアドキュメント。シェルスクリプトなどにおいて、複数行にわたるファイルへの出力内容をスクリプト内に記述する場合などに使用される。
#!/bin/sh
cat <<END
line1
line2
line3
END
このとき、最後の END の前後に空白やタブを付けてはならない。

ヒアドキュメントの中は $foo などの変数展開や、`〜` のコマンド行置換が行われる。これを抑止したい場合は <<'END' などとクォートで囲むとよい。
#!/bin/sh
cat <<END
path is $PATH (no quote)
END
cat <<'END'
path is $PATH (quoted)
END
実行結果は以下の通り。
path is /sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin
⇒ クォートで囲まないと変数が展開される
path is $PATH
⇒ クォートで囲むと変数展開は行われない

sh・bash の場合、<< の部分を <<- とすることで、ヒアドキュメント中の行頭のタブ (TAB) を自動的に削除する。
#!/bin/sh
cat <<-END
a
(TAB)b
(TAB)(TAB)c
END
実行すると以下のように行頭のタブが削除される。
a
b
c

; & && ||
「;」「&」「&&」「||」は同じ仲間で、複数のコマンドの間にこれらの文字を挟むといろいろな動作をさせることができる。

複数のコマンドを ; (セミコロン) でつなぐと、前のコマンドが終わり次第、次のコマンドが実行される。
% command1 ; command2
⇒ command1 を実行し、その実行が完了次第 command2 を実行する。
% command1 ; command2 ; command3
⇒ 3つ以上のコマンドを記述しても OK

|| と && は、; と似ているが、前のコマンドの終了ステータスによって、後続のコマンドを実行するか否かが決まる。
% command1 && command2
⇒ command1 が 0 を返した場合、command2 を実行する。
% command1 || command2
⇒ command1 が 1 以上を返した場合、command2 を実行する。
一般的にコマンドは正常終了時に終了ステータス 0 を返し、異常時に 1 以上を返すため、
% command1 && 正常終了時に実行したいコマンド
% command1 || 異常終了時に実行したいコマンド
という使い方をする。典型的な例として以下のようなものがある。
% configure && make && make install
⇒ configure が成功したときのみ make を実行し、さらに make が成功したときのみ make install を実行する
% command || mail -s "error" foo@example.co.jp
⇒ command が失敗したらエラー通知メールを送信する。

~: ホームディレクトリ
チルダは自分自身のホームディレクトリ・もしくは特定ユーザのホームディレクトリに展開される。
% echo ~
/home/68user
⇒ 自分自身のホームディレクトリに展開される
% echo ~/bin/
/home/68user/bin/
⇒ ~ の後に好きな文字列をつけてもよい。
% echo ~foo
/home/foo
⇒ そのサーバ内に foo というユーザがいるなら、~foo は foo のホームディレクトリに展開される。

{}
{} は下記のように 3つの使われ方をする。
1. 変数名の区切りを表すもの
2. ブレース展開
3. グループコマンド
以下に詳細を説明する。

{} その1. 変数名の区切り
変数の区切りを表すために {} を下記のように使用する。
echo "${VAR}"
上記の例では ${VAR} でも $VAR でも結果は変わらないが、
echo "${VAR}_1.dat"
という場合に $VAR_1.dat と書いてしまうと $VAR_1 という変数として扱われてしまう。$VAR_1 ではなく $VAR という変数であることを明示するために ${VAR} とブレースで囲むわけである。

{} その2. ブレース展開
ブレースにて文字列展開が行える。例えば以下のように使用する。
% mkdir /foo/bar/{dir1,dir2,dir3}
⇒ mkdir /foo/bar/dir1 /foo/bar/dir2 /foo/bar/dir3
複数個の文字列のうち、一部分のみ異なる場合に有用。なお、ブレース展開はファイル・ディレクトリが存在するかどうかをチェックしているわけではなく、単に文字列として展開しているだけである。

{} その3. グループコマンド
グループコマンドは
% { command1; command2; }
というふうに複数コマンドをグループ化する際に使用する。グループ化するだけだと意味はないが、複数コマンドの出力をまとめてリダイレクトしたり、ひとつにまとめることでジョブ制御しやすくするなどの利点がある。

なお "()" はサブエシェルで実行されるが、"{}" は現在のシェルで実行されるという違いがある。
% { command1; command2; }
→ 現在のシェルで実行
% (command1; command2)
→ サブシェルで実行

なお、"{" の後、"}" の前には空白が必要であることと、最後のコマンドの後に ";" セミコロンが必要であることに注意。
% {command1; command2;}
→ NG。{ の後に空白がない。} の前に空白がない。
% { command1; command2 }
→ NG。command2 の後に ; がない。

sh・bash は ()・{} が使える。csh・tcsh は () のみである。

#: コメント
シャープ以降はコメント扱いとなり動作には影響しない。
# ここはコメント
ls -l # ここもコメント

sh・bash では、コメント末尾に \ (エスケープ) を置いても継続行とみなされないため、途中をコメントアウトすることができない。
#!/bin/sh
echo a \
  b \
  c \
というスクリプトがあり、
#!/bin/sh
echo a \
#  b \
  c \
と途中をコメントアウトしてしまうと、
echo a を実行
c を実行
と意図しない挙動になってしまう。

なお、csh・tcsh だと該当部分のみコメント化され、
a c
と表示される。

はまりがちなこととして、下記のように "\" の後に空白を入れてしまうと、改行コードのエスケープではなく空白のエスケープになってしまい、結果的に
単なる空白と扱われてしまう。
echo a \(空白)
b
そうすると、意味としては下記のようになり、echo a ' ' を実行した後に b コマンドを実行、となってしまう。
echo a ' '
b

ブラウザからスクリプトをコピペした場合などに、行末に空白が入ることはよくあるので注意しよう。

:
":" は「何もせず、必ず正常終了する」というコマンドである。sh・bash・csh いずれも内部コマンドとして用意されている。

bash では、下記の then〜else にように空のブロックを書くと "syntax error near unexpected token `else'" とエラーになってしまう。
#!/bin/bash
if [ $var = 0 ]; then
# 問題ないので何もしない
else
echo "ERROR"
exit 1
fi
こういうときに : を入れておくと、空ブロックにならずエラーを回避できる。
#!/bin/bash
if [ $var = 0 ]; then
# 問題ないので何もしない
:
else
echo "ERROR"
exit 1
fi

無限ループを書きたい場合にも重宝する。
#!/bin/sh
while :
do
if [ XXXXX ]; then
break
fi
done

空ファイルを作る、または存在するファイルを 0 バイトに truncate したい場合。
% : > foo.txt
別案として
% cp /dev/null foo.txt
などがあるが、外部コマンドを実行しない分だけ処理は軽い。

複数行コメントアウトに使うこともできる。
:<<'EOT'
コメント
コメント
コメント
EOT

なお、: コマンドの代わりに true コマンドを使っても同じ結果になる。