Можно ли использовать `type`, чтобы проверить, является ли произвольное имя допустимым именем команды?

Встроенный type bash можно использовать для этой цели, проверяя его статус выхода:

 Exit Status: Returns success if all of the NAMEs are found; fails if any are not found. 

Насколько портативен он? Спецификация POSIX немного менее понятна относительно статуса выхода type :

 EXIT STATUS The following exit values shall be returned: 0 Successful completion. >0 An error occurred. 

Источник: http://pubs.opengroup.org/onlinepubs/009695399/utilities/type.html

ОПИСАНИЕ

Утилита типа должна указывать, как каждый аргумент будет интерпретироваться, если он используется как имя команды.

(…)

Возвращаются следующие значения выхода:

0 Успешное завершение.
>0 Произошла ошибка.

«Успешное завершение» означает, что аргумент можно интерпретировать как имя команды, и в этом случае поиск команды будет успешным. Ошибка означает, что аргумент не может быть интерпретирован как имя команды, и в этом случае поиск команды завершится неудачно.

Статус возврата type является полностью POSIX-переносным способом проверки правильности имени команды или как можно ближе к ней. Существуют более старые системы, где type возвращает 0 на недопустимые команды (например, OSF1 V3, но я думаю, OSF1 V4 совместим с POSIX, по крайней мере, когда среда оболочки находится в режиме POSIX ( BIN_SH=xpg4 )), но системы, совместимые с POSIX, возвращаются 0 только после успеха.

То, на что вы не можете положиться, – это выходной формат, или выход будет на stdout или stderr.

Невозможно получить гарантию того, что результат type соответствует тому, что происходит, если вы попытаетесь запустить программу. Возможно, исполняемый файл был добавлен или удален, или может не загрузиться, потому что файл недействителен или из-за нехватки памяти. Но если вы просто хотите посмотреть, существует ли команда и не беспокоит случаи краев, if type somecommand >/dev/null 2>/dev/null; … if type somecommand >/dev/null 2>/dev/null; … это правильный путь.

Вы правы, используя спецификацию POSIX в качестве руководства, на самом деле невозможно сказать, что считается ошибкой. Таким образом, нет никакого способа гарантировать, что нулевой код выхода означает, что операнд является допустимым именем, а тем более что это команда.

Похоже, что стандартный вывод не очень помогает (мой акцент):

Стандартный вывод типа содержит информацию о каждом операнде в неуказанном формате . Предоставляемая информация обычно идентифицирует операнд как встроенную оболочку, функцию, псевдоним или ключевое слово и, где применимо, может отображать имя пути операнда.

Похоже, вам нужно будет использовать эвристику, например, на основе используемой оболочки.