Bashで変数を使用する方法

  • 変数は、文字列または数値を表す名前付きのシンボルです。コマンドや式で使用されると、値として扱われます。
  • 変数名は記述的で、数字で始まったり、スペースを含んだりすることはできません。アンダースコアで始まり、英数字を使用できます。
  • 変数は値を格納して参照するために使用できます。変数の値は変更でき、変数名の前にドル記号$を使用して参照できます。

スクリプトを作成したり、Webからコピーして貼り付けたコードがLinuxコンピュータにどのような影響を与えるかを理解したい場合、変数は不可欠です。始めましょう!

変数の基礎

変数は、文字列または数値を表す名前付きのシンボルです。コマンドや式で使用すると、変数名の代わりに保持されている値を入力したかのように扱われます。

変数を作成するには、名前と値を指定するだけです。変数名は記述的で、保持されている値を思い出させるものでなければなりません。変数名は数字で始めることはできず、スペースを含めることもできません。ただし、アンダースコアで始めることはできます。それ以外は、大文字と小文字の英数字を組み合わせて使用できます。

Bash変数の例

ここでは、5つの変数を作成します。形式は、名前、等号=、および値を入力することです。等号の前後にスペースがないことに注意してください。変数に値を与えることは、多くの場合、変数に値を代入することと呼ばれます。

4つの文字列変数と1つの数値変数を作成します。

my_name=Dave

my_boost=Linux

him=Popeye

his_boost=Spinach

this_year=2019

変数に保持されている値を確認するには、echoコマンドを使用します。値を参照する場合は、常に$というドル記号を先行させる必要があります。以下に示します。

echo $my_name

echo $my_boost

echo $this_year

変数をすべて一度に使用してみましょう。

echo "$my_boost is to $me as $his_boost is to $him (c) $this_year"

変数の値が名前を置き換えます。変数の値を変更することもできます。変数my_boostに新しい値を代入するには、最初の値を代入したときと同じ操作を繰り返します。

my_boost=Tequila

前のコマンドを再実行すると、別の結果が得られます。

echo "$my_boost is to $me as $his_boost is to $him (c) $this_year"

つまり、同じ変数を参照する同じコマンドを使用し、変数に保持されている値を変更すると、異なる結果を得ることができます。

変数の引用については後で説明します。ここでは、覚えておくべきことがいくつかあります。

  • 単一引用符'で囲まれた変数は、変数ではなくリテラル文字列として扱われます。
  • 二重引用符"で囲まれた変数は、変数として扱われます。
  • 変数に保持されている値を取得するには、ドル記号$を指定する必要があります。
  • ドル記号$のない変数は、変数名のみを提供します。

既存の変数または複数の変数から値を取得する変数を作成することもできます。次のコマンドは、drink_of_the_Yearという新しい変数を定義し、my_boostthis_year変数の値を組み合わせて代入します。

drink_of-the_Year="$my_boost $this_year"

echo drink_of_the-Year

スクリプトでBash変数を使用する方法

スクリプトは変数なしでは完全に機能しません。変数は、スクリプトを特定のソリューションではなく、一般的なソリューションにする柔軟性を提供します。違いを説明するために、/devディレクトリのファイル数をカウントするスクリプトを次に示します。

テキストファイルにこれを入力し、fcnt.sh(「file count」の略)として保存します。

#!/bin/bashfolder_to_count=/devfile_count=$(ls $folder_to_count | wc -l)echo $file_count files in $folder_to_count

スクリプトを実行する前に、以下のように実行可能にする必要があります。

chmod +x fcnt.sh

スクリプトを実行するには、次のように入力します。

./fcnt.sh

これにより、/devディレクトリのファイル数が印刷されます。仕組みは次のとおりです。

  • folder_to_countという変数が定義され、文字列「/dev」を保持するように設定されます。
  • file_countという別の変数が定義されます。この変数は、コマンド置換から値を取得します。これは、括弧$( )で囲まれたコマンドフレーズです。最初の括弧の前にドル記号$があることに注意してください。この構造$( )は、括弧内のコマンドを評価してから、それらの最終的な値を返します。この例では、その値がfile_count変数に代入されます。file_count変数に関しては、保持する値が渡されますが、値がどのように取得されたかは関係ありません。
  • コマンド置換で評価されるコマンドは、folder_to_count変数にあるディレクトリに対してlsファイルリストを実行します。これは「/dev」に設定されています。したがって、スクリプトは「ls /dev」コマンドを実行します。
  • このコマンドからの出力がwcコマンドにパイプされます。-l(行数)オプションにより、wclsコマンドからの出力の行数をカウントします。各ファイルは別々の行にリストされるため、これは「/dev」ディレクトリのファイルとサブディレクトリの数です。この値はfile_count変数に代入されます。
  • 最後の行はechoを使用して結果を出力します。

しかし、これは「/dev」ディレクトリでのみ機能します。スクリプトを任意のディレクトリで動作させるにはどうすればよいでしょうか? 1つの小さな変更だけで済みます。

スクリプトでコマンドラインパラメータを使用する方法

lswcなどの多くのコマンドは、コマンドラインパラメータを受け取ります。これらはコマンドに情報を提供するため、コマンドはあなたが何を求めているのかを知ります。lsをホームディレクトリで動作させ、隠しファイルも表示したい場合は、次のコマンドを使用できます。チルダ~-a(すべて)オプションはコマンドラインパラメータです。

ls ~ -a

私たちのスクリプトはコマンドラインパラメータを受け入れることができます。それらは、最初のパラメータの場合は$1、2番目の場合は$2、9番目の場合は$9まで$1として参照されます。(実際には$0もありますが、それは常にスクリプトを保持するために予約されています。)

通常の変数と同様に、スクリプトでコマンドラインパラメータを参照できます。以下のようにスクリプトを変更し、新しい名前fcnt2.shで保存してみましょう。

#!/bin/bashfolder_to_count=$1file_count=$(ls $folder_to_count | wc -l)echo $file_count files in $folder_to_count

今回は、folder_to_count変数に最初のコマンドラインパラメータ$1の値が代入されます。

スクリプトの残りの部分は、以前とまったく同じように機能します。特定のソリューションではなく、スクリプトは今では一般的なソリューションです。それは「/dev」でのみ動作するようにハードコーディングされていないため、任意のディレクトリで使用できます。

スクリプトを実行可能にする方法は次のとおりです。

chmod +x fcnt2.sh

それでは、いくつかのディレクトリで試してみましょう。最初に「/dev」を実行して、以前と同じ結果が得られることを確認できます。次のように入力します。

./fnct2.sh /dev

./fnct2.sh /etc

./fnct2.sh /bin

「/dev」ディレクトリの場合、以前と同じ結果(207ファイル)が得られます。これは心強く、他のすべてのコマンドラインパラメータに対してディレクトリ固有の結果が得られます。

スクリプトを短縮するには、変数folder_to_countを完全に削除し、次のように$1を参照するだけで済みます。

#!/bin/bash file_count=$(ls $1 wc -l) echo $file_count files in $1

特殊変数を使用する

常にスクリプトのファイル名に設定される$0について説明しました。これにより、スクリプトを使用して、名前が変更された場合でも、その名前を正しく印刷するなどの処理を行うことができます。これは、エントリを追加したプロセスの名前を知りたいロギング状況で役立ちます。

以下は、他の特別なプリセット変数です。

  • $#: スクリプトに渡されたコマンドラインパラメータの数。
  • $@: スクリプトに渡されたすべてのコマンドラインパラメータ。
  • $?: 実行された最後のプロセスの終了ステータス。
  • $$: 現在のスクリプトのプロセスID(PID)。
  • $USER: スクリプトを実行しているユーザーのユーザー名。
  • $HOSTNAME: スクリプトを実行しているコンピュータのホスト名。
  • $SECONDS: スクリプトが実行されてからの秒数。
  • $RANDOM: 乱数を返します。
  • $LINENO: スクリプトの現在の行番号を返します。

それらをすべて1つのスクリプトで見たいと思いませんか? できちゃいます! special.shという名前のテキストファイルとして次を保存します。

#!/bin/bashecho "There were $# command line parameters"echo "They are: $@"echo "Parameter 1 is: $1"echo "The script is called: $0"# any old process so that we can report on the exit statuspwdecho "pwd returned $?"echo "This script has Process ID $$"echo "The script was started by $USER"echo "It is running on $HOSTNAME"sleep 3echo "It has been running for $SECONDS seconds"echo "Random number: $RANDOM"echo "This is line number $LINENO of the script"

実行可能にするには、次のように入力します。

chmod +x special.sh

これで、以下のように、さまざまなコマンドラインパラメータを使用して実行できます。

環境変数

Bashは、起動時に作成する環境のプロパティを定義および記録するために環境変数を使用します。これらは、ユーザー名、ロケール、履歴ファイルに保持できるコマンド数、デフォルトのエディタなど、Bashが容易にアクセスできる情報を保持します。

Bashセッションでアクティブな環境変数を確認するには、このコマンドを使用します。

env | less

リストをスクロールすると、スクリプトで参照すると役立つものが見つかるかもしれません。

変数をエクスポートする方法

スクリプトが実行されると、それ自体がプロセスとして実行され、そのプロセスで使用される変数はプロセス外からは見えません。スクリプトが起動する別のスクリプトと変数を共有したい場合は、その変数をエクスポートする必要があります。2つのスクリプトを使用して、その方法を紹介します。

まず、次の内容をscript_one.shというファイル名で保存します。

#!/bin/bashfirst_var=alphasecond_var=bravo# check their valuesecho "$0: first_var=$first_var, second_var=$second_var"export first_varexport second_var./script_two.sh# check their values againecho "$0: first_var=$first_var, second_var=$second_var"

これにより、2つの変数first_varsecond_varが作成され、値が割り当てられます。これらはターミナルウィンドウに出力され、変数がエクスポートされ、script_two.shが呼び出されます。script_two.shが終了し、プロセスフローがこのスクリプトに戻ると、変数が再びターミナルウィンドウに出力されます。その後、それらが変更されたかどうかを確認できます。

2番目に使用するスクリプトはscript_two.shです。これはscript_one.shが呼び出すスクリプトです。次のように入力します。

#!/bin/bash# check their valuesecho "$0: first_var=$first_var, second_var=$second_var"# set new valuesfirst_var=charliesecond_var=delta# check their values againecho "$0: first_var=$first_var, second_var=$second_var"

この2番目のスクリプトは2つの変数の値を出力し、新しい値を割り当て、再度出力します。

これらのスクリプトを実行するには、実行可能にするために次のように入力する必要があります。

chmod +x script_one.shchmod +x script_two.sh

そして、script_one.shを起動するには、次のように入力します。

./script_one.sh

出力は次のとおりです。

  • script_one.shは変数の値を出力します。これはalphaとbravoです。
  • script_two.shは変数の値(alphaとbravo)を受信したとおりに出力します。
  • script_two.shはそれらをcharlieとdeltaに変更します。
  • script_one.shは変数の値を出力します。これはまだalphaとbravoです。

2番目のスクリプトで起こったことは、2番目のスクリプトにとどまります。変数のコピーが2番目のスクリプトに送信されるようなものですが、そのスクリプトが終了すると破棄されます。最初のスクリプトの元の変数は、2番目のスクリプトのコピーに起こったことによって変更されません。

変数を引用する方法

スクリプトが変数を参照する場合、それらが引用符"で囲まれていることに気付いたかもしれません。これにより、変数が正しく参照され、スクリプトでその行が実行されるときにその値が使用されます。

変数に割り当てる値にスペースが含まれている場合、変数に割り当てるときにそれらを引用符で囲む必要があります。これは、デフォルトではBashがスペースを区切り文字として使用するためです。

例を次に示します。

site_name=How-To Geek

Bashは「Geek」の前にスペースがあることを、新しいコマンドの開始の指示とみなします。そのようなコマンドはないと報告し、その行を放棄します。echoは、site_name変数には何も保持されていないことを示しています。「How-To」テキストでさえありません。

以下のように、値を引用符で囲んでもう一度試してください。

site_name="How-To Geek"

今回は、単一の値として認識され、site_name変数に正しく割り当てられます。

echoはあなたの友達です

コマンド置換、変数の引用、およびドル記号を含めるタイミングを覚えるには、時間がかかる場合があります。

Enterキーを押してBashコマンドの行を実行する前に、その前にechoを試してください。この方法により、何が起こるかを確実に確認できます。構文で犯した間違いを見つけることもできます。