
コマンドが組み込みコマンドであるかどうかを確認するにはksh
?
;をtcsh
使用することができ、一部では。where
zsh
bash
type -a
現代ksh
バージョンが利用可能ですwhence -av
。
私が望むのは、次のように動作するすべてのバージョン(他の「以前の」バージョンを含む)isbuiltin
で動作する関数を書くことです。ksh
ksh88
ksh
- 複数のパラメータを受け入れ、各パラメータが組み込まれていることを確認してください。
0
与えられたコマンドがすべて組み込まれている場合(成功)を返します。- 最初の非組み込みコマンドでスキャンを停止して返却
1
(失敗)した後、stderrにメッセージを印刷します。
私はすでにこのような操作機能を持っており、zsh
上記bash
のコマンドを使用しています。
これが私が望むものですksh
:
isbuiltin() {
if [[ "$#" -eq 0 ]]; then
echo "Usage: isbuiltin cmd" >&2
return 1
fi
for cmd in "$@"
do
if [[ $cmd = "builtin" ]]; then
#Handle the case of `builtin builtin`
echo "$cmd is not a built-in" >&2
return 1
fi
if ! whence -a "$cmd" 2> /dev/null | grep 'builtin' > /dev/null ; then
echo "$cmd is not a built-in" >&2
return 1
fi
done
}
この機能は ksh93 で使用できます。ただし、ksh88バージョンは、それらのオプションがすべて表示されるようにするオプションをwhence
サポートしていないようです。-a
すべての項目を表示できないのでwhence -v
、するコマンドが組み込まれているかどうかを知らせますが、同じ名前のエイリアスや関数がない場合にのみ適用されます。
質問:whence -av
inの代わりに他のものを使用できますかksh88
?
解決策
許可された答え(サブシェルを開く)を使用して更新されたソリューションは次のとおりです。 .kshrcに次の内容を入力します。
isbuiltin() {
if [[ "$#" -eq 0 ]]; then
printf "Usage: isbuiltin cmd\n" >&2
return 1
fi
for cmd in "$@"
do
if (
#Open a subshell so that aliases and functions can be safely removed,
# allowing `whence -v` to see the built-in command if there is one.
unalias "$cmd";
if [[ "$cmd" != '.' ]] && typeset -f | egrep "^(function *$cmd|$cmd\(\))" > /dev/null 2>&1
then
#Remove the function iff it exists.
#Since `unset` is a special built-in, the subshell dies if it fails
unset -f "$cmd";
fi
PATH='/no';
#NOTE: we can't use `whence -a` because it's not supported in older versions of ksh
whence -v "$cmd" 2>&1
) 2> /dev/null | grep -v 'not found' | grep 'builtin' > /dev/null 2>&1
then
#No-op. Needed to support some old versions of ksh
:
else
printf "$cmd is not a built-in\n" >&2
return 1
fi
done
return 0
}
私はこれをSolaris、AIX、HP-UXでksh88でテストしました。テストしたすべての場合に機能します。また、FreeBSD、Ubuntu、Fedora、およびDebianで最新バージョンのkshを使用してテストしました。
答え1
エイリアスが心配な場合は、次の操作を行います。
[[ $(unalias -- "$cmd"; type -- "$cmd") = *builtin ]]
($(...)
サブシェル環境を作成するため、unalias
その環境でのみ機能します。)
command unset -f -- "$cmd"
機能に興味がある場合は、以前に実行することもできますtype
。
答え2
ksh93
そのbuiltin
コマンドの実装に時間が無駄になるのではないかと心配です。例えばksh version 93t 2008-11-04
:
$ builtin
...creates list of all builtins
$ builtin jobs umask
...returns with exit code 0
$ builtin jobs time umask
...returns with exit code 1 and prints "builtin: time: not found"
また、このbuiltin
コマンドは組み込みコマンドなので、コード内でこの特定の組み込みコマンドを除くテストは間違っているようです。
答え3
#! /bin/sh
path_to_your_command=$(command -v your_command)
if [ "${path_to_your_command}" = 'your_command' ]; then
echo 'your_command is a special builtin.'
else
if [ -n "${path_to_your_command}" ]; then
echo "your_command is a regular builtin, located at ${path_to_your_command}."
else
echo "your_command is not a builtin (and/or does not exist as it cannot be found in \$PATH)."
fi
fi