2011-09-01 48 views
2

我正在编写一个脚本,我需要在用户的$ PATH上查找命令并获取命令的完整路径。问题是我不知道用户的登录shell是什么,或者他们的do文件中可能有什么奇怪的东西。我为我的简单小脚本使用了Bourne shell,因为它需要在一些可能没有bash的较早版本的Solaris平台上运行。

“which”和“whence”的某些实现将获取用户的点文件,并且这对于所有用户来说都不是真正可移植的。我很喜欢一个简单的UNIX实用程序,它只是为可执行文件扫描PATH的基本工作并报告第一个匹配的完整路径。

但我会解决任何对所有用户都稳定的/ bin/sh解决方案。

我正在寻找一个比编写我自己的/ bin/sh循环更好的解决方案,这个循环可以截断$ PATH并一次搜索一行。看起来这很普遍,应该有一种可重用的方式来做到这一点。

我的“漫长的道路”第一近似值是这样的:

IFS=: 
    for i in $PATH; do 
     if [ -x $i/$cmd ]; then 
      echo $i/$cmd 
     fi 
    done 

有没有更简单的东西和便携式?

+0

你在找什么? – 2011-09-01 23:20:32

+0

你需要担心他们所有的点文件等吗?脚本运行时,用户是否已经在shell中?也就是说,这些文件已经来源了? –

+0

问题是,如果我的.profile只为ksh设置,并且我的sh脚本最终将它作为运行'which'或'whence'命令的一部分来源。我的Solaris 11机箱上的'whence'手册页是指内置的ksh。我正在寻找一种便携式的方式来做到这一点。 –

回答

0

也许whereis命令可以帮你吗?

whereis -b -B `echo $PATH | sed 's/:/ /g'` -f [commands] 

例如我的电脑上,这个工程:

whereis -b -B `echo $PATH | sed 's/:/ /g'` -f find man fsc 

和结果:

whereis手册页
find: /usr/bin/find 
man: /usr/bin/man 
fsc: /opt/FSharp-2.0.0.0/bin/fsc.exe /opt/FSharp-2.0.0.0/bin/fsc 

警告:

Since whereis uses chdir(2V) to run faster, pathnames given 
    with the -M, -S, or -B must be full; that is, they must begin 
    with a `/'. 
+0

'whereis'在我的Solaris机器上似乎不可用,除非我添加/ usr/ucb软件包。看起来编写可移植脚本的最大窍门是理解可以使用哪些外部二进制文件的子集。 –

3

答案似乎是建立在 '类型' -在。

% /bin/sh 
$ type ls 
ls is /bin/ls 
+0

非常整齐的发现!你有时会说[命令]是否被散列?'$ type find find has hashed(/ usr/bin/find)' –

+0

我还没有见过这样的输出。我确实在ksh中看到了这一点:ls是/ bin/ls的一个跟踪别名。我只关心可能运行在/ bin/sh名下的shell的输出。因为这就是我在#上使用的东西!线。 –

相关问题