私はインタラクティブシェルとしてBashを使用していて、Bashがシェルビルトインコマンドの代わりにシステムコマンドを実行する簡単な方法があり、両者が同じ名前を共有している場合に疑問に思っていました。
たとえば、システムkill
(util-linux
から)を使用して、シグナルを送信する代わりに、名前付きプロセスのプロセスID(pid)を出力します。
$ /bin/kill -p httpd
2617
...
システムコマンドのフルパスを指定しない場合、システムコマンドの代わりにBashビルトインが使用されます。 kill
ビルトインには-p
オプションがないため、コマンドは失敗します。
$ kill -p httpd
bash: kill: p: invalid signal specification
シェル組み込みではなく外部の「time」コマンドを使用するようにする に記載されている回答を試してみましたが、time
が実際にはシェルであるため、それらのほとんどが機能しますkeyword–シェルではないbuiltin.
enable -n kill
を使用してBashビルトインを一時的に無効にする以外に、これまでに見てきた最善の解決策は次のようにすることです。
$(which kill) -p httpd
Shellビルトインの代わりに外部コマンドを実行する他のより簡単な(少ない入力を伴う)方法はありますか?
kill
は単なる例であり、 generalized ソリューションがcommand
ビルトインの接頭辞を付けて実行される外部コマンドと同じ名前。ほとんどの場合、私は通常、組み込みバージョンを使用することを好みます。これは、新しいプロセスの分岐を節約し、場合によっては組み込みコマンドに外部コマンドにはない機能があるためです。
env
がパスにあると仮定します:
env kill -p http
env
は、(おそらく)変更された環境で、最初の引数で指定された実行可能ファイルを実行します。そのため、Shellビルトインコマンドを認識していないか、動作しません。
これにより、シェルジョブコントロールの残骸が生成されますが、外部コマンドには依存しません。
exec kill -p bash &
exec
は、現在のシェルを置き換えるために実行可能ファイルを必要とするため、組み込みを使用しません。ジョブはバックグラウンドで実行されるため、現在のシェルではなく、フォークされたバックグラウンドシェルを置き換えます。
あなたが望むことをする最も簡単な方法は、行を置くことかもしれません
alias kill="/bin/kill"
~/.bashrc
ファイルに。その後、bashの新しいログイン/呼び出しごとに、「kill」が/bin/kill
として解釈されます。
この非常に特殊なケースでは、コマンドpgrep
はニーズに完全に一致します。
一般的な意味では、関数は機能します。 「ファイルコマンド」から:
fcmd(){ local a=$1; shift; $(which "$a") "$@"; }
呼びます
fcmd kill -p httpd
しかし、入力が少なくて済むのであれば、良いエイリアスよりも短い方法はありません。
「リストpid」(lp)の概念から:
alias lp='/bin/kill -p'
次に、次のように入力します。
lp httpd
いくつかのタイピングを必要とするソリューションを知っていて、より少ないタイピングを必要とするソリューションが必要な場合は、それをビルドします。
runFile() { local cmd="$1"; shift; cmd="$(which "$cmd")" && "$cmd" "$@"; }
通常ある程度の労力を必要とするものを短縮することは、コンピュータが優れていることです。
(zshの場合)コマンド名の前に=記号を付けて、組み込みではなくシステムバージョンを取得できます。これは、特定のシナリオを混乱させるエイリアスを回避するための便利な方法でもあります。
$ =kill -p httpd