103.1 レッスン 2
Certificate: |
LPIC-1 |
---|---|
Version: |
5.0 |
Topic: |
103 GNUおよびUnixコマンド |
Objective: |
103.1 コマンドラインでの作業 |
Lesson: |
2 of 2 |
はじめに
オペレーティングシステムには、作業を行うために必要コマンドラインシェルやGUIなどの基本的なツールが備わっています。それらをユーザーが使用する場合には、さまざまな「変数」にショートカットや規定値を格納して、ユーザー毎の「環境」が定義されます。ここでは、それら変数の値を表示、参照、管理する方法を学習します。
環境変数の検索
最初に、環境を定義する変数の値を調べる方法を説明します。1つは、env
コマンドを使用する方法です。
$ env DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus XDG_RUNTIME_DIR=/run/user/1000 XAUTHORITY=/run/user/1000/gdm/Xauthority XDG_CONFIG_DIRS=/etc/xdg/xdg-ubuntu:/etc/xdg PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin GJS_DEBUG_TOPICS=JS ERROR;JS LOG [...]
実際には、この例よりもはるかに多くの出力が得られるでしょう。この中では、シェルや他のプログラムが(フルパス指定なしで)別のプログラムを検索するディレクトリを含む PATH
エントリが最も重要です。この指定によって、たとえばホームディレクトリに居ても、/usr/local/bin
にあるバイナリプログラムをコマンド名だけで実行できます。
次の方法に進みましょう。echo
コマンドは、ユーザーが指示した内容を画面に出力します。このコマンドが何の役に立つのか、と思うかもしれませんが、何かを文字通り echo
したい場面は少なくありません。
$ echo "Hi. How are you?" Hi. How are you?
echo
は文字列を表示するだけではありません。変数であることを示す $
に続けて変数名を入力すると、シェルが変数を展開して、変数の名前ではなくその値を教えてくれます。例えば、現在のPATHにお気に入りのディレクトリが含まれているかどうかわからない場合には、echo
を実行すると簡単に確認できます。
$ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
新しい変数の作成
独自の変数を環境に追加することもできます。最も簡単な方法は、=
を使用することです。左側の文字列が新しい変数の名前になり、右側の文字列がその値になります。変数名を echo
に与えれば、動作を確認できます。
$ myvar=hello $ echo $myvar hello
Note
|
変数に値を割り当てる時は、等号の両側にスペースを置かないことに注意してください。 |
作成した変数は正しく機能しましたか? ターミナルに bash
と入力すると、新しいシェルが起動します。この新しいシェルは、それまで使用していたものとまったく同じように見えますが、実際には元のシェル(親)の 子 です。次に、この新しい子シェルの中で、echo
を使って、作成した変数を表示してみましょう。今度は、結果に何も表示されません。何が起きているのでしょうか?
$ bash $ echo $myvar $
=
で作成した変数は、作成したシェル 〜 つまり変数を作成したシェルセッション内でのみ使用可能です。新しいシェルを起動した場合、あるいは exit
を使用してセッションを閉じた場合は、この変数の値は引き継がれません。ここで exit
と入力すると、元の親シェルに戻ることができます。これは、bash
を入力する前に作業していたシェルです。もう一度 echo $myvar
を実行すると、変数がまだ有効であることを確認できます。export myvar
と入力すると、後で開く子シェルに変数を引き継ぐことができます。再度 bash
と入力し、新しいシェルを起動した後に、echo $myvar
と入力してみてください。今度は変数の値が表示されます。通常の変数が、シェルの「環境」に追加されたので、子シェルにも引き継がれたのです。通常の変数を「シェル変数」、exportされた変数を「環境変数」と呼びます。
$ exit $ export myvar $ bash $ echo $myvar hello
何の目的もなく子シェルを作っているときは、このようなことは少しばかばかしいと感じるかもしれません。しかし、本格的なスクリプトを書き始めると、システムで変数がどのように伝搬されるかを理解することが非常に重要になってきます。
環境変数の削除
作成した一時的な変数を削除する方法も知っておきましょう。1つ目の方法は、親シェルを閉じるか、コンピューターを再起動することです。2つ目の方法は、unset
を使って(親シェルを閉じたり、コンピューターを再起動すること無く)変数を削除することです。変数名に $
を付けずに unset
と入力してみてください。変数が削除されます。削除されたことは、echo
で確認できます。
$ unset myvar $ echo $myvar $
unset
コマンドがあるということは、それに対応する set
というコマンドも存在します。set
を単独で実行すると多くの出力が得られますが、その中には環境変数も含まれています。PATH
を取り出してみましょう。
$ set | grep PATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin [...]
set
と env
の違いは何でしょう? set
は、すべての変数や関数を出力します。試しに mynewvar
という新しい変数を作成して確認してみましょう。
$ mynewvar=goodbye $ echo $mynewvar goodbye
ここで、grep
を使用して文字列 mynewvar
を取り出しながら、env
と set
を実行してみましょう。env
では(exportしていないので)何も表示されませんが、set
ではシェル変数が表示されます。
$ env | grep mynewvar $ set | grep mynewvar mynewvar=goodbye
特殊文字をエスケープするための引用符
続いて、特殊文字について解説します。英数字(a-zおよび0-9)は通常、Bashによって文字通り解釈されます。myfile
という名前の新しいファイルを作成する場合、touch
に続けて myfile
と入力すれば、Bashはその処理方法を認識します。ただし、ファイル名に特殊文字を含めたい場合は、少し工夫する必要があります。
説明のために、touch
と入力し、その後に my big file
という名前を続けてみましょう。Bashが解釈する単語の間に2つのスペースがあることが問題になります。技術的には、スペースを “文字” とは呼びませんが、Bashが文字通りに解釈しないという意味では特殊文字に似ています。現在のディレクトリ内容を一覧表示すると、my big file
という1つのファイルではなく、my
、big
、file
という名前の3つのファイルが作成されます。これは、Bashが、リストで渡した名前を「複数個のファイルを作成したい」と解釈したためです。
$ touch my big file $ ls my big file
同様に、3つのファイルすべてを1つのコマンドで削除(rm
)すると、スペースが同じように解釈されます。
$ rm my big file
それでは、正しい方法を試してみましょう。touch
に続けてファイル名の3つの部分を入力しますが、名前をダブルクオートで囲みます。今度はうまくいきました。ディレクトリの内容を一覧表示すると、意図した名前のファイルが1つ作成されます。
$ touch "my big file" $ ls 'my big file'
同じ効果を得る別の方法もあります。たとえば、シングルクオート(一重引用符)はダブルクォート(二重引用符)と同じように機能します。シングルクォートはすべての文字をそのままの “文字” として処理しますが、ダブルクォートは $
,`
,\
、と、場合によっては !
を “特殊文字” として処理することに注意してください。
$ rm 'my big file'
特殊文字の前にバックスラッシュを付けると、その文字の特別な意味が “エスケープ” されて、Bashは普通の文字として解釈します。
$ touch my\ big\ file
演習
-
export
コマンドを使用して、PATH変数に新しいディレクトリを追加してください(再起動後には無くなっても構いません)。 -
unset
コマンドを使用してPATH
変数を削除してください。その後、sudo
を使用してコマンド(sudo cat /etc/shadow
など)を実行してみましょう。どうなりますか? またそれは、どうしてですか? (シェルを終了すれば、元の状態に戻ります。)
発展演習
-
インターネットを検索して、特殊文字の完全なリストを調べてください。
-
特殊文字で構成された文字列をさまざまな方法でをエスケープして、コマンドを実行してください。エスケープ方法によって動作に違いはありますか?
まとめ
このレッスンでは、次のことを学びました。
-
システムの環境変数を確認する方法。
-
独自の変数を作成して他のシェルにエクスポートする方法。
-
変数を削除する方法と、
env
コマンドとset
コマンドの違い。 -
Bashが文字通りに解釈するように特殊文字をエスケープする方法。
このレッスンでは、次のコマンドを説明しました:
echo
-
入力した文字列や変数を出力します。
env
-
環境変数を調べたり、(一時的に)変更したりします。
export
-
シェル変数を環境変数に変換します。
unset
-
シェル変数や関数を削除します。
演習の解答
-
export
コマンドを使用して、PATH変数に新しいディレクトリを追加してください(再起動後には無くなっても構いません)。export PATH="/home/yourname/myfiles:$PATH"
によって、一時的に新しいディレクトリ (ホームディレクトリにあるmyfiles
というディレクトリ) をPATHに追加することができます。myfiles/
ディレクトリに簡単なスクリプトを作成し、実行権限を付与して、別のディレクトリから実行してみてください。なお、作業ディレクトリはホームディレクトリであることを想定しています。$ touch myfiles/myscript.sh $ echo '#!/bin/bash' >> myfiles/myscript.sh $ echo 'echo Hello' >> myfiles/myscript.sh $ chmod +x myfiles/myscript.sh $ myscript.sh Hello
-
unset
コマンドを使用してPATH
変数を削除してください。その後、sudo
を使用してコマンド(sudo cat /etc/shadow
など)を実行してみましょう。どうなりますか? またそれは、どうしてですか? (シェルを終了すれば、元の状態に戻ります。)unset PATH
と入力すると、PATH変数が消去されます。そのため、絶対パスを指定せずにプログラムを呼び出そうとしても失敗します。例えば、sudo(それ自体は/usr/bin/sudo
にあるバイナリプログラム)を使用してコマンドを実行しようとすると失敗します。つまり、/usr/bin/sudo /bin/cat /etc/shadow
のように絶対パスを指定しない限り実行できません。PATH
をリセットするには、export
を使用してPATH変数を再設定するか、いったんシェルを終了します。
発展演習の解答
-
インターネットを検索して、特殊文字の完全なリストを調べてください。
次の通りです:
& ; | * ? " ' [ ] ( ) $ < > { } # / \ ! ~
-
特殊文字で構成された文字列をさまざまな方法でをエスケープして、コマンドを実行してください。エスケープ方法によって動作に違いはありますか?
文字
"
を使用してエスケープすると、ドル記号、バッククォート、およびバックスラッシュの特別な意味は無くなりません。一方、'
文字を使用してエスケープすると、すべての 文字がそのまま “文字” として解釈されます。$ echo "$mynewvar" goodbye $ echo '$mynewvar' $mynewvar