「set」というプログラムが実行されないのはなぜですか?

「set」というプログラムが実行されないのはなぜですか?

以下のように単純なCプログラムを作成しました。

int main(int argc, char *argv[]) {

    if (argc != 5) {
       fputs("Not enough arguments!\n", stderr);
       exit(EXIT_FAILURE);
    }

パスを修正しました等/bash.bashrcこのように:

PATH=.:$PATH

私はこのプログラムをset.cとして保存し、次のようにコンパイルしました。

gcc -o set set.c

フォルダに

~/Programming/so

ところで、電話してみます。

set 2 3

何もしません。テキストは表示されません。

呼ぶ

./set 2 3

予想した結果を与えた

以前は PATH 問題が発生したことはありません。

which set

返品./set。したがって、PATHが正しいようです。どうしたの?

答え1

whichを使う代わりに最も必要なときは動作しませんtype次のコマンドを入力したときに実行する項目を決定します。

$ which set
./set
$ type set
set is a shell builtin

シェルは検索する前に常に組み込み関数を探すので、ここでは$PATH設定は$PATH役に立ちません。

実行可能ファイルの名前を別のものに変更するのが最善ですが、ジョブでプログラム名を指定する必要がある場合は、setシェル関数を使用できます。

$ function set { ./set; }
$ type set
set is a function
set ()
{
    ./set
}

(これはで動作しますbashが、他のシェルではkshこれを許可しない可能性があります。より移植可能な解決策については、mikeservの答えを参照してください。)

これで、入力するとset「set」という関数が実行されます./set。 GNUはbash組み込み関数を見つけ、検索する前に関数を見つけます$PATH。 bashのマニュアルページの「COMMAND EXECUTION」セクションにこれに関する詳細情報があります。

builtincommandおよび:help builtinとのマニュアルも参照してくださいhelp command

答え2

setbash(およびおそらく他のほとんどのシェル)に組み込まれている機能です。これは、bashが関数を見つけるときにパスを検索しないことを意味します。

ただし、.セキュリティ上の理由からパスに追加しないことをお勧めします。たとえば、他のユーザーが実行可能ファイルを追加した後に終了すると想像してみてくださいcd/tmp/tmp/cd

答え3

setいいえただ内蔵されています。POSIX特殊内蔵。コマンド検索で最初に見つかるように標準で指定するいくつかの組み込みコマンドがあります。 -$PATH検索されない、関数名で検索されないなど。ほとんどの組み込みコマンドは次のとおりです。いいえ 特別な実際には必須POSIX規格に準拠して、次のことができます。$PATH 今後シェルは独自の組み込みプロシージャを実行します。これはechoほとんどの人に当てはまります。(これに関連する規格への準拠は、過去のOpen Groupメーリングリストで議論の対象となりましたが)、しかしいいえ、、、、、、、、、、、、、、、、、、、、、または、、、、、、、、、、、、、、、、、、、、setまたはtrapbreakreturncontinue.:timesevalexitexportreadonlyunsetexec

これらはすべてシェル用に予約された名前であり、コマンド検索の優先順位に加えて特別な属性を持っています。たとえば、標準互換シェルでは、これらの名前を使用してシェル関数を定義することはできません。これは良いもの- 人々が移植可能なスクリプトを書くことを可能にします。安全に。これは、経験豊富なシナリオ作家が自分の環境で安全で安全な基盤を構築できる基本的なコマンドです。この名前空間を侵害するのはいいえ提案。

しかし、ハッキングしたい場合は、alias.shellコマンドを使用できます。拡張この回避策を有効にします。aliasコマンドを読んだときに拡張が行われるため、定義で名前を変更することは何でも正しく拡張されますが、setおそらくこれらの名前のいずれかに拡張してはいけません。

だからあなたはこれを行うことができます:

alias set=./set

...これは大丈夫だと思います。

答え4

問題は、これがset組み込みシェルであり、最良の解決策は次のとおりです。別の名前を使う実行可能なプログラムのため。

ところで先週、私が誰かにどのように過ごすか尋ねました。同じ名前のシェル組み込みの代わりにシステムコマンドを実行する私が受け入れた解決策は、次のようにコマンドを実行することでしたenv

env set 2 3

この特別なケースでは、使用するコマンドが現在ディレクトリにあることが既にわかっており、そのパス.(現在の作業ディレクトリを表すために使用されている)を入力して実行可能ファイルを直接実行することをお勧めします。

./set 2 3

上記の両方のソリューションはシェルに拘束されません。つまり、どのシェルを使用しても、動作します。

command組み込みコマンドの使用などの提案は Bash では機能しません。これはシェルをブロックするだけです。機能実行されることから。文書化されていませんが、以下を使用してcommandシェルも抑制されることもわかりました。キーワード。しかし、シェルの場合は同じではありません。組み込み機能たとえばset。私が理解したのは、command他のシェル(zshなど)と組み合わせて使用​​できます。

また、Bashの組み込み機能などのトリックは\set機能しません。"set"'set'ニックネームまたはシェルキーワード

注:この回答はもともとEricの(受け入れられた)回答に対するコメントから始まりましたが、コメントを受け入れるには大きすぎました。 PATHにtype追加せずに使用を提案する他の答えはすべて良い答えです。.

関連情報