例如,我的脚本是$HOME/bin/sudo
.我想搜索具有$PATH
相同名称的可执行文件,sudo
并运行它 - 但不是脚本$HOME/bin/sudo
本身,否则我将陷入无限循环!
编辑:这样做的要点是,在某些情况下,我希望我的替换脚本比常规系统命令具有更高的优先级,而在其他一些情况下,我希望相反。因此,我已将“$HOME/bin”设置为路径中的第一个,因此现在我可以单独定义每个命令的优先级。我还想要某种“可移植性”,以便脚本能够在不同的系统中运行。
答案1
不需要脚本或函数。如果您只是将$HOME/bin
最后一个放在路径中,则仅当$PATH
.
例子:
[jenny@sameen ~]$ export PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin
[jenny@sameen ~]$ which foo
/usr/bin/which: no foo in (/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin)
[jenny@sameen ~]$ export PATH=$PATH:$HOME/bin
[jenny@sameen ~]$ which foo
~/bin/foo
[jenny@sameen ~]$ sudo cp bin/foo /usr/local/bin/
[jenny@sameen ~]$ which foo
/usr/local/bin/foo
如果您不相信可以设置自己的 $PATH,以便您仍然想在脚本内进行检查,请参阅以下示例:
#!/bin/bash
export ORIGPATH=$PATH # to revert the path after checking for the binary
export PATH=`echo $PATH |sed -e 's{/home/jenny/bin:{{'`
MYNAME=`basename $0`
if which $MYNAME
then
BINFILE=`which $MYNAME`
export PATH=$ORIGPATH
echo "Found $MYNAME in $BINFILE "
$BINFILE
else
export PATH=$ORIGPATH
echo "Here goes the rest of the script"
fi
答案2
POSIX 定义了-p
内置选项command
...
-p
使用 PATH 的默认值执行命令搜索,保证找到所有标准实用程序。
与可解析或人类友好的-v
和选项一起使用-V
(分别)输出有关 acommand
的位置,并且当您请求它时,您可以很好地依赖它来获得预期的实用程序。这是一个小脚本来演示它是如何工作的:
( cd ~; mkdir -p bin
cat >./bin/cat
chmod +x ./bin/cat
export "PATH=$HOME/bin:$PATH"
command -V cat | cat
) <<\NOTCAT
#!/bin/sh
command -p cat
! printf "I'm not REALLY cat, but '%s' is!\n" \
"$(command -pv cat)"
NOTCAT
输出
cat is /home/mikeserv/bin/cat
I'm not REALLY cat, but '/bin/cat' is!
前几条语句在 ~/bin/cat 中构建了一个可执行脚本。$PATH
也被修改为插入~/bin
在其头部。
所以当我command -V cat | cat
command
写入我的 fakecat
的标准输入时。然而它的输出仍然出现在我的屏幕上。这是因为command -p cat
无论我如何破坏我的$PATH
.
答案3
搜索修改后的命令PATH
:
PATH=$(awk -F: 'sub(FS "'$HOME/bin'","")' <<<"$PATH") which sudo
例如:
$ which sudo
/usr/local/bin/sudo
$ PATH=$(awk -F: 'sub(FS "/usr/local/bin","")' <<<"$PATH") which sudo
/usr/bin/sudo
答案4
如果您的 $HOME/bin 路径不在 $PATH 中,您可以使用以下命令进行测试
if [ ! -a $(command -v $(basename $0)) ]; then
YOUR SCRIPT
else
echo "$(basename $0 already exists in $PATH"
fi