Phi*_*rly 7 shell-script command-not-found
我有一个 shell 脚本
echo "Type your command"
read command
echo "You typed $command"
$command
Run Code Online (Sandbox Code Playgroud)
所以它运行一个命令很简单。我的问题是如果输入是错误的,假设lw
终端说,command not found
那么我如何将这些信息检索到我的 shell 脚本并打印到终端Try again wrong command
。我是否必须将命令的输出重定向到某个文件并读取或是否有任何类型的陷阱信号传递给我的脚本。这是您关于如何以最有效的方式执行此操作的建议。
当未找到命令时,退出状态为 127。您可以使用它来确定未找到命令:
until
printf "Enter a command: "
read command
"$command"
[ "$?" -ne 127 ]
do
echo Try again
done
Run Code Online (Sandbox Code Playgroud)
虽然命令通常不会返回 127 退出状态(因为它会与 shell 使用的标准特殊值冲突),但在某些情况下,命令可能真正返回 127 退出状态:最后一个命令的脚本找不到。
bash
并且zsh
有一个特殊的command_not_found_handler
函数(在bash
's 中有一个拼写错误,因为它在command_not_found_handle
那里被调用),当没有找到命令时,它会在定义时执行。但它是在子shell上下文中执行的,也可能在执行函数时未找到的命令上执行。
您可能会想使用type
or预先检查命令是否存在command -v
,但请注意:
"$commands"
Run Code Online (Sandbox Code Playgroud)
被解析为一个简单的命令,别名不会被扩展,而type
orcommand
也会为别名和 shell 关键字返回 true。
例如, with command=for
,type -- "$command"
将返回 true,但"$command"
(最有可能)返回命令未找到错误。
which
可能会因为许多其他原因而失败。
理想情况下,如果命令作为函数、shell 内置命令或外部命令存在,则您希望返回 true 的内容。
hash
至少会满足这些标准ash
和bash
(不是yash
也不ksh
是zsh
)。因此,这将适用于bash
或ash
:
while
printf "Enter a command: "
read command
do
if hash -- "$command" 2> /dev/null; then
"$command"
break
fi
echo Try again
done
Run Code Online (Sandbox Code Playgroud)
一个问题是hash
对于目录(对于包含 a 的目录的路径)也返回 true /
。而如果您尝试执行它,虽然它不会返回命令未找到错误,但它会返回一个Is a directory
或Permission Denied
错误。如果你想覆盖它,你可以这样做:
while
printf "Enter a command: "
read command
do
if hash -- "$command" 2> /dev/null &&
{ [ "${command#*/}" != "$command" ] || [ ! -d "$command" ];}
then
"$command"
break
fi
echo Try again
done
Run Code Online (Sandbox Code Playgroud)