私はソベルの本を読んでいます。Linux コマンド、エディタ、およびシェルプログラミングに関する実用ガイド、4e、私は現在シェルの基本5章を始めています。
135ページで、Sobelは次のように説明しています。
コマンドラインでは、シェルが実行するファイル名を3つの方法で指定できます。絶対パス名(スラッシュ[/]で始まる、90ページ)、相対パス名(スラッシュで終わらないが含む)。 91ページ)または単純なファイル名(スラッシュなし)で表示されます。
その上、彼は次のように書いた。
スラッシュなしで単純なファイル名を指定すると、シェルはディレクトリリストで指定された名前と一致し、ユーザーに実行権限を持つファイル名を検索します。シェルはすべてのディレクトリを検索せず、PATHという変数で指定されたディレクトリのみを検索します。
重要なことに、彼は作業ディレクトリが一般的に次のようになることを指摘しています。いいえパスの一部。
だから私の質問は、単純なファイル名がコマンドとして渡されるのか、それともコマンド引数として渡されるのかによってシェルがどのように異なる動作をするのかを理解することです。
本のこの時点まで、私は単純なファイル名を相対パスの特別なケースとして理解しました。ここでは、指定されたファイルが作業ディレクトリの直接の子であるため、スラッシュは必要ありません。たとえば、foo
私のホームディレクトリにファイルがあり、私がホームディレクトリにある場合、
ls -l foo
(引数として単純なファイル名をfoo
渡しました)の詳細を提供します。foo
ls
今この行動はその他それ自体がプログラム/ファイル/実行ファイルであるコマンドの場合(私の無実と正確さの欠如を許してください)。 Sobellは、コマンドラインに以下を提供すると、シェルは必ずしも作業ディレクトリではなくPATHでディレクトリを見つけると言うようです(PATHの一部ではない限り)。
ls
つまり、単純なファイル名を引数ではなくコマンドとして指定する場合、シェルの外観は異なる動作をします。この理解は正しいですか?
答え1
はい。あなたの理解は正しいです。
/tmp
そのディレクトリに移動して「text」という単語を含むテキストファイルを作成すると、次の内容が表示されます。
cd /tmp
echo 'text' > file.txt
これで、次のコマンドを交換して使用できます。
cat /tmp/file.txt
cat ./file.txt
cat file.txt
各コマンドはファイルのテキスト内容を表示します。
しかし!今実行可能ファイル文書:
cd /tmp
printf '#!/usr/bin/env bash\n\necho "hi"\n' > executable
chmod a+x executable
ファイルはまだファイルなので、以前と同じようにファイルにアクセスできます。
cat /tmp/executable
cat ./executable
cat executable
ただし、Bashシェルでは、次のようにのみ実行できます。
/tmp/executable
./executable
次のようにファイルを実行できません。
executable
これにより、シェルは一致する実行可能ファイルを見つけるためにさまざまな$ PATH場所を検索します。何もないので、シェルは放棄し、エラー127(「コマンド 'executable'が見つかりません」)を返します。
なぜこのように動作しますか?
これは意識的な安全決定です!ハッカーが通常のシェルコマンド(コマンドなど)のいずれかに一致する/tmp
名前を使用してディレクトリに実行可能ファイルを配置すると、ユーザーが知らない間に悪意のあるコマンドを実行する可能性があります。ls
解決策は、$ PATHにインストールされた信頼できるコマンドのみがシェルで実行されるようにすることです。
時間があったらする現在の作業ディレクトリでワンタイムスクリプトを実行したい場合は、実行可能ファイルのパス(たとえば、./executable
または)を指定して/tmp/executable
これを実行できます。追加のパス情報を提供することで、実行可能ファイルが実際にその場所で実行されることを望み、そうするようにだまされていないことを示します。