連載
» 2018年05月17日 05時00分 公開

Linux基本コマンドTips(207):【 set 】コマンド(応用編1)――ファイルの上書きやシェルの終了、ジョブ終了後の通知動作を変更する

本連載は、Linuxのコマンドについて、基本書式からオプション、具体的な実行例までを紹介していきます。今回は、シェルの設定を確認、変更する「set」コマンドです。

[西村めぐみ,@IT]
「Linux基本コマンドTips」のインデックス

Linux基本コマンドTips一覧

 本連載は、Linuxのコマンドについて、基本書式からオプション、具体的な実行例までを紹介していきます。今回はシェルの設定を確認、変更する「set」コマンドです。

setコマンドとは?

 「set」はシェルの設定を確認、変更するコマンドです。setはbashのビルトインコマンド(シェルの組み込みコマンド)です(※1)。このためmanコマンドではなく、helpコマンドで詳細を表示できます。

 setコマンドの基本的な使い方については、連載第205回をご確認ください。

※1 tcshなど、他のシェルにも同名のコマンドがある。



 今回は、setコマンドのオプションのうち、よく使われる2つを取り上げます。リダイレクトで既存のファイルを上書きしない「noclobber」オプションと、[CTRL]+[D]でログアウトしない「ignoreeof」オプション、終了したバックグラウンドジョブの結果をすぐに表示する「notify」オプションです。

 次回は定義されていない変数を参照したらエラーにするnounsetオプションと、コマンドが実行時にエラーになった場合、直ちにシェルを終了する「errexit」オプションを取り上げます。



setコマンドの書式

set [オプション]

※[ ]は省略可能な引数を示しています。




setの主なオプション

短いオプション 意味
-o シェルオプション シェルオプションを有効にする
-o 設定したシェルオプションを「on」と表示する
+o シェルオプション シェルオプションを無効にする(-oによる設定を打ち消す)
+o 設定したシェルオプションを現在と同様に設定するための全てのコマンド列を一覧表示する
--、- オプションの終わり(「--」および「-」以降は全てファイル名やsetコマンドのオプション以外の引数として扱う)

主なシェルオプションとオプション

シェルオプション オプション 意味
allexport -a シェル変数の定義と同時にexportし、環境変数としても使用可能にする(※2)
braceexpand -B ブレース展開を実行する(デフォルトで有効)
noglob -f 「*」などによるパス名展開を無効にする
nounset -u パラメーター展開中に、設定していない変数があったらエラーとする(特殊パラメーターである「@」と「*」は除く)
noclobber -C リダイレクトで既存のファイルを上書きしない
ignoreeof [CTRL]+[D]で終了しない(「IGNOREEOF=10」相当)
physical -P cdコマンドなどでシンボリックリンクをたどらずに物理的なディレクトリ名を使用する
emacs コマンド行の編集操作をEmacs形式にする(デフォルトで有効)
vi コマンド行の編集操作をviコマンド形式にする
posix bashの動作のうち、デフォルトの動作がPOSIXと異なるものもPOSIX準拠になるように変更する(POSIXモード)

※2 「set -a」は「set -o allexport」と同じ効果を持つ。「set +a」は「set +o allexport」相当だ。他のシェルオプションについても同様。



主なシェルオプションとオプション(ヒストリとジョブ関連)

シェルオプション オプション 意味
history コマンド履歴を有効にする(対話シェルではデフォルトで有効)
histexpand -H 「!番号」によるヒストリの参照を行う(デフォルトで有効)
monitor -m 監視モード。バックグラウンドジョブの結果を表示する(デフォルトで有効)
notify -b 終了したバックグラウンドジョブの結果をすぐに表示する(通常は次のコマンド実行時に表示する)
hashall -h コマンドのパスを全て記憶する(hashコマンド参照)

主なシェルオプションとオプション(エラー処理とデバッグ関連)

シェルオプション オプション 意味
errexit -e パイプやサブシェルで実行したコマンドが1つでもエラーになったら直ちにシェルを終了する
pipefail パイプラインの返り値を、最後のエラー終了値(0以外で終了した際の値、全ての実行が成功した場合は0)にする
errtrace -E エラーをトレースする(シェル関数で、ERRトラップを継承する)
functrace -T デバッグをトレースする(シェル関数で、DEBUGトラップを継承する)
verbose -v シェルの入力行を表示する
xtrace -x トレース情報として、シェルが実行したコマンドとその引数を出力する。情報の先頭にはシェル変数PS4の値を使用

主なシェルオプションとオプション(その他)

シェルオプション オプション 意味
interactive-comments 「#」以降をコメントとして扱う(デフォルトで有効)
keyword -k コマンド名の前にある代入文だけでなく、引数として指定した全ての代入文も、そのコマンドに対する環境変数に追加する
noexec -n コマンドを読み込むだけで実行しない(※3)
onecmd -t コマンドを1つ読み込み、実行してから終了する
privileged -p 特権モード。シェル関数や変数を環境から継承せず、実効ユーザーも再設定しない

※3 シェルスクリプトの文法チェックをする際に使用する。対話シェルでは無視する。





リダイレクトで既存のファイルを上書きしない

 リダイレクトでコマンドの出力をファイルに保存する際、注意することが1つあります。「コマンド > ファイル」のように「>」記号1つでリダイレクトした場合、ファイルを常に新規で作成します(※4)。つまり、既存のファイルがあった場合、上書きされてしまいます。

※4 「コマンド >> ファイル」のように「>」記号2つでリダイレクトした場合、既存ファイルの末尾に追加される。指定したファイルがない場合は新規で作成される。



 これを避けるには、「set -o noclobber」または「set -C」で、「noclobber」オプションを有効にして、ファイルの上書きを禁止できます(画面1)。

 自分のコマンドラインでは常にこのように設定したい場合は、「~/.bashrc」に書いておくとよいでしょう。

 なお、コマンドラインで「set -C」を実行してsetコマンドの「noclobber」オプションを有効にしても、シェルスクリプトの実行には影響がありません。シェルスクリプトではbashが別途起動しているためです(画面2)。

 さらに「~/.bashrc」で「set -C」を設定した場合でも、シェルスクリプトには影響がありません。シェルスクリプトで起動するbashは、非対話シェルなので設定ファイル(~/.bashrc)を読み込まないためです(※5)。

※5 bashは、ログインシェルの場合は起動時に/etc/profileと~/.bash_profileを読み込み、対話シェルの場合はさらに~/.bashrcも読み込む。/etc/bashrcも使用するように設定されていることが少なくないが、その場合でも/etc/bashrcの中で非対話シェルの場合は処理を行わない設定になっていることが多い。



 スクリプトの中でも「noclobber」オプションを有効にしたい場合は、そのスクリプトの中で「set -o noclobber」または「set -C」を実行します。なお、スクリプトの中で上書きを禁止したい場合は、「>」ではなく「>>」でファイルに追記するように記述しておくか、スクリプトの処理として事前にファイルの存在を確認する方法が一般的です。

コマンド実行例

set -o noclobber

(noclobberオプションを有効にして、リダイレクトで既存のファイルを上書きしない)

set -C

(noclobberオプションを有効にする、set -o noclobber相当)(画面1


画面1 画面1 リダイレクト時に既存ファイル(testfile)への上書きを禁止したところ
画面2 画面2 リダイレクトで既存のファイルを上書きすることを禁止しても、シェルスクリプトからは上書きされてしまう


[CTRL]+[D]ですぐにログアウトしない

 bashをログアウトする場合や、仮想端末を終了させる場合には、[CTRL]+[D]というキー入力を実行します。

 [CTRL]+[D]は、ファイルの終了を意味するコード(EOF:End Of File)を出力するキー操作です。bashはEOFを受け取るとログアウトします。

 この処理を禁止するには、「set -o ignoreeof」でsetコマンドの「ignoreeof」オプションを有効にします。このようにすると、bashはEOFを受け取ってもログアウトしません。

 なお、「ignoreeof」オプションの意味はデフォルトでは「EOFを連続10回無視する」というものです。このため、[CTRL]+[D]を連続して入力すると11回目にログアウトします(画面3)。

 回数を変更したい場合は、シェル変数IGNOREEOFに回数を設定します(画面4)。

コマンド実行例

set -o ignoreeof

([CTRL]+[D]ですぐにログアウトしない)(画面3


画面3 画面3 [CTRL]+[D]を押してもログアウトしないように設定したところ 11回目にはログアウトする。
画面4 画面4 [CTRL]+[D]を受け付ける回数を変更したところ


終了したバックグラウンドジョブの結果をすぐに表示する

 バックグラウンドジョブの結果は、ジョブが終了した直後には表示されません。結果が表示されるのは、コマンドラインで次のコマンドを実行したタイミングです(画面5関連記事)。

 バックグラウンドジョブが終了したタイミングで結果を表示するには、「set -o notify」または「set -b」で、setコマンドの「notify」オプションを有効にします(画面6)。

 画面5ではsleepコマンド(第66回)をバックグラウンドで実行しています。これは指定した秒数だけ待機して終了するだけのコマンドです。

 続けて実行しているのはdateコマンド(第77回)で、実行したタイミングの日時を表示して経過時間を確認しています。

コマンド実行例

set -o notify

(notifyオプションを有効にする)

set -b

(notifyオプションを有効にする、set -o notify相当)(画面6


画面5 画面5 バックグラウンドジョブの結果が表示されるタイミングを確認したところ
画面6 画面6 バックグラウンドジョブの結果が、終了後、即座に表示された

 なお、バックグラウンドジョブの終了が通知されるのは、setコマンドのmonitorオプションがデフォルトで有効になっているためです。「set +o monitor」または「set +m」でmonitorオプションを無効にすることで、終了が通知されなくなります(画面7)。

コマンド実行例

set +o monitor

(monitorオプションを無効にする)

set +m

(monitorオプションを無効にする、set +o monitor相当)(画面7


画面7 画面7 バックグラウンドジョブの終了通知を無効にしたところ


筆者紹介

西村 めぐみ(にしむら めぐみ)

PC-9801NからのDOSユーザー。PC-486DX時代にDOS版UNIX-like toolsを経てLinuxへ。1992年より生産管理のパッケージソフトウェアの開発およびサポート業務を担当。著書に『図解でわかるLinux』『らぶらぶLinuxシリーズ』『Accessではじめるデータベース超入門[改訂2版]』『macOSコマンド入門』など。2011年より、地方自治体の在宅就業支援事業にてPC基礎およびMicrosoft Office関連の教材作成およびeラーニング指導を担当。


Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。