在C中实现一个Unix shell:检查文件是否可执行

我正在C中实现一个Unix shell,我正在处理相对path的问题。 值得一提的是input命令。 现在我必须每次input可执行文件的完整path,当时我宁愿简单地放上“ls”或“cat”。

我设法得到$ PATH envvariables。 我的想法是将variables分割为“:”字符,然后将每个新string附加到命令名称,并检查文件是否存在并且是可执行的。

例如,如果我的PATH是“/ bin:/ usr / bin”,并且input了“ls”,我想程序首先检查“/ bin / ls”是否存在并且是可执行的,如果不是, USR /斌/”。

两个问题:

1)这是一个好方法吗? (它不一定是最好的,我只是想确保它能工作。

2)更重要的是, 如何检查C,如果文件存在并且可执行?

我希望我已经清楚了,而且……非常感谢:)

别。 执行此检查是错误的; 它固有地受到竞争条件的影响。 相反, 尝试执行适当的exec家庭调用。 如果它不可执行,你会得到一个错误。

还要注意,你不需要自己搜索PATH ; execvp可以为你做这个。

使用stat函数: http : //linux.die.net/man/2/stat

例如:

 struct stat sb; if(!stat(path, &sb)) { if(IS_REG(sb.st_mode) && sb.st_mode & 0111) printf("%s is executable\n", path); } 

调用完整的路径名stat ,如果它返回0(成功),目标存在。 在这种情况下,您可以使用返回结构中的st_mode字段来测试目标是目录,设备,命名管道还是普通文件。 如果它是一个文件, st_mode也将包含权限位。 (如果是目录,可能会设置一些“可执行”位,但这意味着“可搜索”而不是“可执行”)。

编辑:正如其他人已经指出,这是受到竞争条件,并有更好的方法来完成你想要在这个特定的情况下做什么。

stat ? PSH。 比你需要的方式。

检查access()系统调用。

 if (access(filename, F_OK|X_OK) == 0) { /* You can execute this file. */ } 

请注意,任何检查文件访问或文件的存在都有一个固有的竞争条件 。 你不能保证你的电话execve有人没有删除可执行位,改变文件的所有权,删除文件等,在你的检查发生的时间。 在编写代码时请记住这一点,并决定如何处理错误情况。

你是如何创建过程?

使用execlp或execvp。

access()答案是唯一明智的答案。 如果使用stat,则必须解析/ etc / group以找出您在BESIDE getgid()所有组, BESIDE它们与组可执行位一起测试。