.sh ファイル内の 'hash' コマンドを理解できない問題

.sh ファイル内の 'hash' コマンドを理解できない問題

そこで、Linux マシンに Etherpad lite をインストールしたいのですが、実行しようとすると、次のエラーが発生します。

「node.jsをインストールしてください(http://nodejs.org)"

コマンドは、which nodeNode.js への正しいパスを示します。そこで、Etherpad Lite の .sh ファイルに移動して、次の内容を見つけました。

  #Is node installed?
  hash node > /dev/null 2>&1 || { 
  echo "Please install node.js ( http://nodejs.org )" >&2
  exit 1 
}

これは、ノードをチェック --> 利用できない場合は行を印刷して終了する、という意味だと思います。しかし、このコードは正確には何をするのでしょうか? ハッシュは何をするのでしょうか? これらとは何&ですか>?

この3行を説明していただける方がいらっしゃいましたら、大変助かります。

答え1

bash シェル内でコマンドを入力すると、シェルは $PATH 変数全体でそれらのコマンドを検索します。ハッシュは、入力したコマンドとそのコマンドが見つかった場所のインデックスであり、次回コマンドを見つける際の速度を速めるのに役立ちます。

注記: @アンソンの回答ハッシュとは何かについての良い定義を与えてくれます。

たとえば、hash引数なしでコマンドだけを実行すると、以前に見つかったコマンドとその使用回数 (ヒット数) のリストが表示されます。

% hash
hits    command
   2    /usr/bin/host
   1    /bin/more
   1    /home/saml/bin/autossh_mail.sh
   3    /usr/bin/zip
   2    /bin/rm
   2    /bin/date
   2    /usr/bin/vim
   1    /usr/bin/htop
   2    /bin/mv
   3    /bin/ps
   8    /usr/bin/ssh
   1    /usr/bin/yum
   1    /usr/bin/xfreerdp
   1    /bin/cp
   2    /bin/mkdir
   4    /usr/bin/man
   1    /usr/bin/gvim
   1    /usr/bin/unzip
   1    /usr/bin/w
   5    /usr/bin/nslookup
  51    /bin/ls
  15    /usr/bin/find

このコマンドはhash node、その値がハッシュのリストに存在するかどうかに応じてステータス値 (0 または 1) を返します。

hash node私のリストに載っていない

% hash node
bash: hash: node: not found
% echo $?
1

注記:以前に実行されたコマンドのステータスは、環境変数に一時的に保存されます。$?. コマンドが実行された後にステータス (0 = 成功、1 = 失敗) がここに配置されます。

構造 "cmd1" || { "cmd2" ... } は or ステートメントです。ここでは論理から and/or を考えます。つまり、最初のことを実行し、失敗した場合は 2 番目のことを実行し、失敗した場合は 2 番目のことを実行しません。

より詳しい例:

% true && echo "1st cmd ret. 1" || echo "1st cmd ret. 0"
1st cmd ret. 1

% false && echo "1st cmd ret. 1" || echo "1st cmd ret. 0"
1st cmd ret. 0

1 が返されるとコマンドが失敗したことを意味し、0 が返されるとコマンドが正常に実行されたことを意味するため、ロジックは常に混乱を招きます (少なくとも私にとっては)。

答え2

以前投稿された回答に加えて、「2>&1」の部分についての説明を追加したいと思います。

> /dev/null

出力ファイル記述子 (ファイル記述子は、プロセスがファイル、パイプ、および端末の読み取りと書き込みに使用する番号です) をシステムの「ゴミ箱」であるファイル /dev/null にリダイレクトします。このファイルには、書き込まれたものがすべて読み取られ、そのデータが破棄されます。

2>&1

番号 2 の stderr (エラーの出力「ファイル」) ファイル記述子を、/dev/null にリダイレクトされた (つまり無視された) ファイル記述子 1 にリダイレクトします。

したがって、これら 2 つの部分を組み合わせることで、ハッシュ コマンドからの出力が表示されなくなります。

答え3

bash マニュアルより:

Each time hash is invoked, the full pathname of the command name
is  determined  by searching the directories in $PATH and remembered.  
Any previously-remembered pathname is discarded.

hashは bash の内部コマンドであり、ハッシュ テーブルを操作して、bash入力したコマンドの完全なパスを検索するために使用されます。

nodeこのスクリプトはこれを使用して、実行可能ファイルがパス内で検索されることを確認します。

答え4

hash nodePATH で node という名前の最初のコマンドを検索し、記憶されている場所のリストに node の場所を追加または更新します。node が見つからなかった場合は 1 を返します。

次の理由により、which の代わりに hash が使用されます。

  • これは POSIX では定義されていません。
  • 一部の環境では、PATH を変更できる csh スクリプトです。
  • たとえば、bash では hash は組み込みですが、そうではありません。また、hash の方が通常は高速です。

OP がコメントで述べたように、問題はスクリプトの実行時にノードが PATH に実際に存在しなかったことです。したがって、which node同じ結果になったはずです。

関連情報