Функция ping + () в .bashrc не работает - PullRequest
0 голосов
/ 28 ноября 2018

У меня есть эта проблема.У меня машина windows 10, последняя версия.

Я установил Cygwin, и в моем bashrc есть эта функция:

ping+()
{
        host=$1
        par_1=$2
        par_2=$3
        par_3=$4
        ping $host $par_1 $par_2 $par_3 | xargs -n1 -i bash -c 'echo [`date +"%Y-%m-%d | %H:%M:%S"`] " {}"'
}

Работает нормально:

Luca[~] :> ping+ www.google.it
[2018-11-28 | 20:41:23]  Pinging www.google.it [74.125.71.94] with 32 bytes of data:
[2018-11-28 | 20:41:23]  Reply from 74.125.71.94: bytes=32 time=28ms TTL=43
[2018-11-28 | 20:41:24]  Reply from 74.125.71.94: bytes=32 time=31ms TTL=43
[2018-11-28 | 20:41:25]  Reply from 74.125.71.94: bytes=32 time=29ms TTL=43
[2018-11-28 | 20:41:26]  Reply from 74.125.71.94: bytes=32 time=29ms TTL=43
[2018-11-28 | 20:41:26]  Ping statistics for 74.125.71.94:
[2018-11-28 | 20:41:26]  Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
[2018-11-28 | 20:41:26]  Approximate round trip times in milli-seconds:
[2018-11-28 | 20:41:26]  Minimum = 28ms, Maximum = 31ms, Average = 29ms

Но если я помещаю этот код в .bashrc на "файловой системе Windows Ubuntu", я получаю эту ошибку:

luca[/mnt/c/Users/Luca] :> source /home/luca/.bashrc
ping+(): command not found

Скорее всего, "+" после "ping" не принимается.Как я могу решить эту проблему?Спасибо Лука

1 Ответ

0 голосов
/ 01 декабря 2018

Это результат нечетного взаимодействия между функциями оболочки с символом '+' в их именах и опцией bash extglob.Скорее всего, у вас extglob отключено в вашей оболочке под Cygwin и включено в вашей конфигурации "файловой системы Windows Ubuntu".

Я не выяснил, почему extglob имеет именно этот побочный эффект.Это может быть ошибка в bash.Это может быть даже ошибка, из-за которой bash принимает ping+ в качестве имени функции, в зависимости от того, что соответствующие стандарты и другая документация говорят о правильном синтаксисе имени функции.

Самое простое решение состоит в том, чтобыиспользуйте имя, которое не заканчивается символом +.

Если вы действительно хотите использовать имя ping+ для своей функции, обходной путь - отменить параметр extglob при определении функции,(Вы по-прежнему можете вызывать его с именем ping+ независимо от того, установлен extglob или нет.)

Например, это может быть в вашем .bashrc:

shopt -u extglob
ping+() {
    host=$1
    par_1=$2
    par_2=$3
    par_3=$4
    ping $host $par_1 $par_2 $par_3 | xargs -n1 -i bash -c 'echo [`date +"%Y-%m-%d | %H:%M:%S"`] " {}"'
}
shopt -s extglob

(Это заставляет extglob быть установленным. Если вы хотите оставить его в исходном состоянии, это немного сложнее. Вам нужно было бы проанализировать вывод shopt extglob, чтобы определить, установлен он или не установлен. Но вы, вероятно,в любом случае хочу установить его безоговорочно.)

Другое решение - использовать исполняемый скрипт оболочки, а не функцию.Например, этот скрипт эквивалентен вашей функции:

#!/bin/bash

host="$1"
par_1="$2"
par_2="$3"
par_3="$4"
ping $host $par_1 $par_2 $par_3 | xargs -n1 -i bash -c 'echo [`date +"%Y-%m-%d | %H:%M:%S"`] " {}"'

Создайте файл с именем ping+ с указанным выше содержимым, сделайте его исполняемым с chmod +x и скопируйте его в каталог в $PATH например $HOME/bin.(Нет необходимости устанавливать его в системном каталоге, таком как /usr/bin. Если вы хотите, чтобы он был доступен для всех пользователей системы, вы можете установить его в общесистемном каталоге, таком как /usr/local/bin. /usr/bin каталог предназначен для команд, предоставляемых самой операционной системой.)

Это работает, потому что правила для имен команд проще и менее ограничительны, чем правила для имен функций оболочки.

Вот прощеи более надежная версия (она позволяет избежать проблем с метасимволами оболочки в аргументах).

#!/bin/bash

ping "$@" | xargs -n1 -i bash -c 'echo [`date +"%Y-%m-%d | %H:%M:%S"`] " {}"'

или лучше (поскольку xargs может включать атаки подстановки команд, как указывает Чарльз Даффи):

#!/bin/bash

ping "$@" | while read -r line ; do echo "[$(date +'%Y-%m-%d | %H:%M:%S')] $line" ; done
...