ищите команду в ПУТИ с тем же названием сценария

Я поместил Щенка на Dell OptiPlex 170, который я купил за 60,00$. Я поместил Щенка непосредственно на диск на 4 ГБ. Работает отлично для того, чтобы просто просмотреть сеть.

3
26.10.2014, 18:28
6 ответов

POSIX определяет опцию -p для команды -p, встроенной в ....

  • -p Выполните поиск команды, используя значение по умолчанию для PATH, которое гарантированно найдет все стандартные утилиты.

Используйте опции -v и -V для вывода parsable или human-friendly (соответственно) относительно местоположения команды -v, и вы можете вполне положиться на нее, чтобы получить нужную утилиту, когда вы запрашиваете ее. Вот небольшой скрипт для демонстрации того, как он работает:

(   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

OUTPUT

cat is /home/mikeserv/bin/cat
I'm not REALLY cat, but '/bin/cat' is!

Первые пару операторов строят исполняемый скрипт в ~/bin/cat. $PATH также модифицирован для вставки ~/bin в его голову.

Итак, когда я делаю команду -V cat | cat command пишет на мой фальшивый cat stdin. И все же его вывод все равно попадает на мой экран. Это потому, что команда -p cat получает настоящий, независимо от того, как я искалечил свой $PATH.

2
27.01.2020, 21:19

Если ваш путь домой / корзины на дому $ не находятся в $ Path, вы могли бы протестировать его с

if [ ! -a $(command -v $(basename $0)) ]; then
        YOUR SCRIPT
else
   echo "$(basename $0 already exists in $PATH"
fi
-1
27.01.2020, 21:19

Поиск команды с модифицированным 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
0
27.01.2020, 21:19

Нет необходимости в скриптах или функциях. Если вы просто поставьте $ HOME / BIN Последнее на вашем пути, он будет использоваться только в том случае, если в любом из предыдущих каталогов используется только соответствующее имя команды .

Пример:

[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

Если вы не доверяете, чтобы вы могли установить свой собственный путь, чтобы вы все еще хотели сделать чек из скрипта, вот пример:

#!/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
4
27.01.2020, 21:19

Я не совсем уверен, что понимаю, что вы когда-либо следуете, но типа и , которые должны помочь. . Например:

$ type -a sudo
sudo is aliased to `/usr/bin/sudo'
sudo is /home/terdon/scripts/sudo
sudo is /usr/bin/sudo

В примере выше существует 3 возможного Sudo S, один представляет собой псевдоним и два находятся в моем $ PATH . Вы можете просто разбирать, что делать то, что вы хотите. Если вы используете оболочку, у которых нет типа встроенного, вы можете сделать то же самое с , который , который (хотя это не обнаруживает псевдонимы, а не должно быть Вопрос с помощью сценариев Shell в любом случае.):

$ which -a sudo
/home/terdon/scripts/sudo
/usr/bin/sudo

с этим в виду, если ваша цель состоит в том, чтобы избежать бесконечной петли на основе имени текущего скрипта, вы можете сделать что-то вроде:

#!/usr/bin/env bash

## Get the name of the matching command from your
## $PATH, excluding the script itself ($0).
com=$(type -a $(basename $0) | grep -v $0 | head -n 1 | awk '{print $NF'})
## Run the command on the arguments passed
$com "$@"

, как указал @edimaster В комментариях - - не определяется posix, поэтому он не может присутствовать во всех системах. Более портативный подход, будет поискать по каталогам вашего $ PATH :

#!/usr/bin/env bash

## Get the name of the matching command from your
## $PATH, excluding the script itself ($0).
com=$(find $(printf "%s" "$PATH" | sed 's/:/ /g') -name $(basename $0) |
      grep -v $0 | head -n 1)
## Run the command on the arguments passed
$com "$@"
-1
27.01.2020, 21:19

Я только что нашел эту альтернативу, которая кажется вполне надежной.

EXEPATHSLIST="/usr/bin /usr/sbin /bin /sbin /opt/$1/bin /usr/games /usr/local/bin /usr/local/games /system/bin /system/xbin"
for exepath in $EXEPATHSLIST
do
    if [ -x  $exepath/$1 ]; then
        $exepath/"$@"
        exit $?
    fi
done

# alternative using command
command -p "$@"
_ES=$? ; [ $_ES -ne 127 ] && exit $_ES

# more alternative search methods here
# ...

# else command not found
exit 127
0
27.01.2020, 21:19

Теги

Похожие вопросы