我试图用C编写shell。
例如,我已设法处理并将用户输入解析为数组。如果用户输入ls -al
,则会将其解析为|ls|al|\0|
这个小shell的一个要求是能够使用fork()
和execvp
(或其他exec
函数之一)来分叉和执行进程,并且能够用户输入&
&符号时的后台进程。
execvp()系统调用需要2个参数:
这是问题,如何从我创建的创建一个子阵列没有数组中的最后一个元素? ie如果用户键入ls -al &
我的shell生成|ls|al|&|
数组,我只需要传递|al|
的argv数组,而不是|&|
。
根据我对C的经验以及我发现的内容,如果我不想要数组的第一个元素,可以使用指针,例如{{1}或者使用char** subArray = &argv[1]
(SO Q&A here),它允许在没有前n个元素的情况下创建子数组,但不能没有最后一个元素。
但要删除最后一个元素是一个for循环还是while循环唯一的方法?在没有最后一个元素的情况下创建一个新数组。
我还尝试设置memcpy
所在的最后一个元素 &
或NULL
,但是execvp不允许数组要传入的NULL值(它会使程序崩溃)。这可以按预期工作。但实际上并没有创建一个subArray或它的指针。
我正在寻找的一个相关概念可能是其他语言中的数组切片,我认为这些概念不存在于C中。
答案 0 :(得分:1)
dispatch_group_notify
系列函数不像大多数程序员所期望的那样工作。
第一个参数具有可执行文件路径。第二个参数应该也是文件路径(或仅文件路径的一部分)。第三个参数是第一个参数,等等。
对于 execvp 风格,参数数组仍必须具有可执行文件路径的第一个入口点。
您不需要执行任何切片:只需在最后一个参数指针之后在数组中放置一个NULL。
答案 1 :(得分:1)
请忽略最后一个参数。
argv[argc-1] = NULL;
execvep(cmd, args);
答案 2 :(得分:1)
您无需做任何事情。动态构造的C数组只是指向其第一个元素的指针,其他元素位于正确的位置。包含“1”,“2”,“3”的数组也已经是一个包含“1”,“2”的数组和一个只包含“1”的数组。
对于exec函数,它们需要一个最后一个条目为NULL的数组(这就是它们如何确定哪个条目是最后一个)。因此,要将{ "1", "2", "3" }
转换为{ "1", "2", NULL }
,只需将第三个条目设置为NULL。