确定shell脚本的函数和文件依赖性?

时间:2010-10-13 18:44:19

标签: shell

我正在寻找一种处理shell脚本的方法来确定:

  1. 在脚本中调用哪些命令,脚本或函数。
  2. 脚本(r或w)访问哪些文件。
  3. 它不需要通过依赖项递归,只需列出它直接运行的内容。我本可以写一些自己这样做的东西,但它必须在之前完成......我只是没找到它。

3 个答案:

答案 0 :(得分:5)

您可以使用'strace'来运行脚本并查看脚本及其子进程所执行的所有操作,包括查找和打开文件。例如:

$ cat foo.sh
#!/usr/bin/env bash

touch /tmp/foon
$ chmod +x foo.sh
$ strace -f -e execve,access,open,stat -o foo.trace ./foo.sh
$ cat foo.trace
32176 execve("./foo.sh", ["./foo.sh"], [/* 42 vars */]) = 0
32176 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
32176 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
32176 open("/usr/local/lib/tls/x86_64/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
...
32176 execve("/bin/bash", ["bash", "./foo.sh"], [/* 42 vars */]) = 0
...
32177 execve("/usr/bin/touch", ["touch", "/tmp/foon"], [/* 41 vars */]) = 0
32177 open("/tmp/foon", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666) = 3
...
32176 --- SIGCHLD (Child exited) @ 0 (0) ---
$ 

我已经修剪了很多其他活动(打开系统库;查找区域设置数据;等等)。查看'man strace',了解选项的含义细节; -f,-o和-e是我经常使用的那些。

答案 1 :(得分:1)

这将是我目前正在开发的Loker项目的一个功能。现在,解析器几乎已经完成,你可以在它上面实现你想要的合理近似值。但是,通常这个任务非常复杂,因为命令的名称可能来自变量扩展,字段拆分等。

如果你描述了你需要什么,以及你要解析什么样的脚本,我将能够说出你现在对Loker能满足的需求有多少。

作为替代选项,某些版本的bash具有--rpm-requires选项,它也可以执行类似的操作。

答案 2 :(得分:0)

你不能用这种动态语言做到这一点,你的静态分析工具将不可靠并错过许多依赖项。请考虑以下代码:

#!/bin/sh

func_foo() { echo 'foo running' ; }
func_bar() { echo 'bar running' ; }
# etc...

printf 'foo, bar,...? ' # for testing
read RPC
# rpc_is_in_rpclist "$RPC" || die "invalid call"
printf 'Calling func_%s\n' "$RPC"
func_"$RPC"

这不是一个错综复杂的例子;我最近在生产环境中添加了一个带有参数的更详细的版本。

如果您确实需要静态分析,那么您首先不应该使用动态语言,它们只是彼此不兼容。对于函数作为参数传递的每种其他函数语言都是如此:静态分析实际上不能预测参数的值。

即使是像Java这样非常静态和简单的语言,如果你努力尝试并使用反射,你仍然可以躲避静态分析。然而,反射在设计上很麻烦而且没有广泛使用,所以Java的分析在实践中非常有用:参见Eclipse等。