我正在用C实现一个Unix shell,我正在处理相对路径的问题。特别是在输入命令时。现在我每次都必须输入可执行文件的完整路径,而我更愿意简单地输入“ls”或“cat”。
我设法获得$ PATH env变量。我的想法是将变量拆分为“:”字符,然后将每个新字符串附加到命令名称并检查文件是否存在且是否可执行。
例如,如果我的PATH是: “/ bin:/ usr / bin”我输入“ls”,我希望程序首先检查“/ bin / ls”是否存在并且是可执行的,如果没有移到“/ usr / bin /”。< / p>
两个问题:
1)这是一个好方法吗? (它不一定是最好的。我只是想确保它能够发挥作用。
2)更重要的是,如果文件存在且可执行,我如何签入C?
我希望我足够清楚,并且......非常感谢:)
答案 0 :(得分:9)
别。执行此检查是错误的;它固有地受到竞争条件的影响。相反,尝试使用适当的exec
- 系列调用执行它。如果它不可执行,您将收到错误。
另请注意,您无需自己搜索PATH
; execvp
可以为您做到这一点。
答案 1 :(得分:4)
使用stat
功能:
http://linux.die.net/man/2/stat
e.g:
struct stat sb;
if(!stat(path, &sb))
{
if(IS_REG(sb.st_mode) && sb.st_mode & 0111)
printf("%s is executable\n", path);
}
答案 2 :(得分:4)
在完整路径名上调用stat
,如果它返回0(成功),则目标存在。在那里面
您可以使用返回结构中的st_mode
字段来测试是否存在
target是目录,设备,命名管道或普通文件。如果它是文件,st_mode
也将包含权限位。 (如果它是一个目录,一些“可执行”位可能
设置,但这意味着“可搜索”而不是“可执行”。)
编辑:正如其他人所说,这是一个竞争条件,在这种特殊情况下有更好的方法来完成你想做的事情。
答案 3 :(得分:4)
stat
? PSH。超出你需要的方式。
查看access()
系统调用。
if (access(filename, F_OK|X_OK) == 0)
{
/* You can execute this file. */
}
请注意,对文件访问或文件存在的任何检查都包含固有竞争条件。在您的检查发生时,您无法保证在致电execve
时有人未删除可执行位,更改文件的所有权,删除文件等。编写代码并决定如何处理错误条件时请记住这一点。
答案 4 :(得分:0)
你是如何创建这个过程的?
使用execlp或execvp。
答案 5 :(得分:0)
access()
答案是唯一明智的答案。
如果您使用stat,则必须解析/ etc / group以查找BESIDE
getgid()
中的所有组,并将其与组可执行位一起测试。