在 PATH 中搜索与脚本同名的命令

在 PATH 中搜索与脚本同名的命令

例如,我的脚本是$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

相关内容