以下のように単純な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」セクションにこれに関する詳細情報があります。
builtin
command
および:help builtin
とのマニュアルも参照してくださいhelp command
。
答え2
set
bash(およびおそらく他のほとんどのシェル)に組み込まれている機能です。これは、bashが関数を見つけるときにパスを検索しないことを意味します。
ただし、.
セキュリティ上の理由からパスに追加しないことをお勧めします。たとえば、他のユーザーが実行可能ファイルを追加した後に終了すると想像してみてくださいcd
。/tmp
/tmp/cd
答え3
set
いいえただ内蔵されています。POSIX特殊内蔵。コマンド検索で最初に見つかるように標準で指定するいくつかの組み込みコマンドがあります。 -$PATH
検索されない、関数名で検索されないなど。ほとんどの組み込みコマンドは次のとおりです。いいえ 特別な実際には必須POSIX規格に準拠して、次のことができます。$PATH
今後シェルは独自の組み込みプロシージャを実行します。これはecho
ほとんどの人に当てはまります。(これに関連する規格への準拠は、過去のOpen Groupメーリングリストで議論の対象となりましたが)、しかしいいえ、、、、、、、、、、、、、、、、、、、、、または、、、、、、、、、、、、、、、、、、、、set
またはtrap
。break
return
continue
.
:
times
eval
exit
export
readonly
unset
exec
これらはすべてシェル用に予約された名前であり、コマンド検索の優先順位に加えて特別な属性を持っています。たとえば、標準互換シェルでは、これらの名前を使用してシェル関数を定義することはできません。これは良いもの- 人々が移植可能なスクリプトを書くことを可能にします。安全に。これは、経験豊富なシナリオ作家が自分の環境で安全で安全な基盤を構築できる基本的なコマンドです。この名前空間を侵害するのはいいえ提案。
しかし、ハッキングしたい場合は、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
追加せずに使用を提案する他の答えはすべて良い答えです。.