我正在编写一个自定义 shell,我想用我自己的 shell 运行 shell 脚本。我正在尝试检查是否安装了 less 程序,如果是,请使用 less 程序,否则使用more
.但是,我的 shell 没有type
内置程序,因此我必须创建它才能检查是否安装了 less。
int do_type(int argc, const char **argv) {
bool found = false;
char *curr_path;
char *path;
char *path_strdup;
char *path_value;
char *pathValue;
pid_t pid;
pathValue = getenv("PATH");
path_strdup = strdup(pathValue);
if (path_strdup == NULL) {
perror("strdup");
exit(EXIT_FAILURE);
}
path_value = strtok(path_strdup, ":");
path = path_value;
while (path && !found) {
if ((curr_path = malloc(strlen(path) + sizeof(argv[1]))) != NULL) {
if (curr_path == NULL) {
fprintf(stderr, "malloc failed!\n");
}
strcpy(curr_path, path);
strcat(curr_path, argv[1]);
if (file_exist(curr_path)) {
found = true; // we found the program
}
//free(curr_path);
path = strtok(NULL, ":");
} else {
fprintf(stderr, "malloc failed!\n");
return false;
}
}
if (found)
printf("%s\n", curr_path, found);
else
printf("%s: not found\n", argv[1]);
return 1;
}
less
如果我在 shell 中运行代码,aboce 代码将找到该程序(如果已安装):
$ type /blaha
/blaha: not found
$ type /less
/usr/bin/less
$ type /godoc
/usr/local/go/bin/godoc
$
现在我想知道如何进行检查。我已经编写了我的 shell 应该执行的脚本。
type less > /dev/null
printenv|grep $1|$PAGER
我的 shell 还具有接受条件语句的功能,因此如果我可以在 if 语句if
中使用退出代码 0 或 1,那么我可以将变量设置为 less 或 more,整个事情应该可以正常工作。但是内置函数的退出代码应该是什么? 0 表示找到(成功),1 表示未找到,还是反之亦然?还有什么我应该考虑的吗?do_type
PAGER
type
答案1
返回值
我发现您EXIT_FAILURE
在代码中使用了,因此您将stdlib.h
.在该头文件中EXIT_FAILURE
和EXIT_SUCCESS
定义为:
#define EXIT_FAILURE 1 /* Failing exit status. */
#define EXIT_SUCCESS 0 /* Successful exit status. */
这符合 UNIX 程序的典型行为。 man type
在这里也很有用,因为type
是POSIX命令:
EXIT STATUS
The following exit values shall be returned:
0 Successful completion.
>0 An error occurred.
因此,是的,如果失败则返回 1type
是正确且预期的行为。
而且,在 every 中使用EXIT_FAILURE
and代替相当混乱的and会更好。EXIT_SUCCESS
return
return 1
return false
如果
if
按以下方式评估传递给它的命令的返回值:如果命令返回,0
则将其视为 true 并执行then
块;如果命令返回的内容不是0
执行else
的块(假设该块存在)。
因此,您的type
(成功返回 0,失败返回 1)应按预期工作:
if type less > /dev/null
then
echo less exists
else
echo no less we need to use more
fi
另一件事,在你的代码中我担心这部分:
if ((curr_path = malloc(strlen(path) + sizeof(argv[1]))) != NULL) {
if (curr_path == NULL) {
fprintf(stderr, "malloc failed!\n");
}
那一刻if
永远不可能成为现实。仅当curr_path != NULL
您正在测试 时,您才能进入外部块curr_path == NULL
。我相信你想要这个:
if ((curr_path = malloc(strlen(path) + sizeof(argv[1]))) != NULL) {
... /* the actual path matching */
}
else {
fprintf(stderr, "malloc failed!\n");
}
答案2
来自help type
外壳bash
:
type: type [-afptP] name [name ...] Display information about command type. For each NAME, indicate how it would be interpreted if used as a command name. ... Exit Status: Returns success if all of the NAMEs are found; fails if any are not found.