Неверное предыдущее регулярное выражение

0

Я получаю ошибку:

awk: bad regex '{|: |}': недопустимое предыдущее регулярное выражение   { "аргументы": {}, "результат": "Успех"}   { "Порт": 37482}

Который я считаю, имеет отношение к этой линии:

PORT=$(echo $json | awk 'BEGIN{r=1;FS="{|:|}"} /port/{r=0; print $3} END{exit r}')
#echo $PORT

Кто-нибудь знает, что это значит и как я могу это исправить? Я новичок в написании сценариев, но, как я понимаю, выражение |: | это неверно. $ json - это файл, который я извлекаю из VPN с информацией о порте для пересылки.

Мой вклад:

#!/usr/bin/env bash
#
# Enable port forwarding when using Private Internet Access
#
# Usage:
#  ./port_forwarding.sh
TRANSUSER=xxx
TRANSPASS=xxxx
TRANSHOST=localhost
error( )
{
  echo "$@" 1>&2
  exit 1
}
error_and_usage( )
{
  echo "$@" 1>&2
  usage_and_exit 1
}
usage( )
{
  echo "Usage: `dirname $0`/$PROGRAM"
}
usage_and_exit( )
{
  usage
  exit $1
}
version( )
{
  echo "$PROGRAM version $VERSION"
}

port_forward_assignment( )
{
  client_id_file="/etc/openvpn/pia_client_id"
  if [ ! -f "$client_id_file" ]; then
    if hash shasum 2>/dev/null; then
      head -n 100 /dev/urandom | shasum -a 256 | tr -d " -" > "$client_id_file"
    elif hash sha256sum 2>/dev/null; then
      head -n 100 /dev/urandom | sha256sum | tr -d " -" > "$client_id_file"
    else
      echo "Please install shasum or sha256sum, and make sure it is visible in your \$PATH"
      exit 1
    fi
  fi
  client_id=`cat "$client_id_file"`
  json=`curl "http://209.222.18.222:2000/?client_id=$client_id" 2>/dev/null`
  if [ "$json" == "" ]; then
    json='Port forwarding is already activated on this connection, has expired, or you are not connected to a PIA region that supports port forwarding'
  fi
  echo $json
}
#trim VPN forwarded port from JSON
PORT=$(echo $json | awk 'BEGIN{r=1;FS="{|:|}"} /port/{r=0; print $3} END{exit r}')
#echo $PORT
#change transmission port on the fly
CURLOUT=$(curl -u $TRANSUSER:$TRANSPASS ${TRANSHOST}:9091/transmission/rpc 2>/dev/null)
REGEX='X-Transmission-Session-Id\: (\w*)'

if [[ $CURLOUT =~ $REGEX ]]; then
    SESSIONID=${BASH_REMATCH[1]}
else
    exit 1
fi
DATA='{"method": "session-set", "arguments": { "peer-port" :'$port' } }'

curl -u $TRANSUSER:$TRANSPASS http://${TRANSHOST}:9091/transmission/rpc -d "$DATA" -H "X-Transmission-Session-Id: $SESSIONID"

EXITCODE=0
PROGRAM=`basename $0`
VERSION=2.1
while test $# -gt 0
do
  case $1 in
  --usage | --help | -h )
    usage_and_exit 0
    ;;
  --version | -v )
    version
    exit 0
    ;;
  *)
    error_and_usage "Unrecognized option: $1"
    ;;
  esac
  shift
done
port_forward_assignment
exit 0

Сценарий взят из: https://www.privateinternetaccess.com/forum/discussion/23431/new-pia-port-forwarding-api/p3 ?

Он предназначен для запроса к их API номера порта, а затем для перенаправления полученного порта в демон передачи.

Dodgexander
источник
Что вы пытаетесь достичь? Каков ваш вклад, каков ваш желаемый результат? Если у вас есть входной JSON, тогда опубликуйте его. Если вы пытаетесь получить номер порта из JSON, скажите так. Постарайтесь не задавать проблему XY meta.stackexchange.com/a/66378/364309
Attie
Я спрашивал здесь ранее, но не получил никаких ответов. Я думал, потому что я сделал вопрос слишком конкретным! superuser.com/questions/1258891/...
Dodgexander
Извините за то, что я нуб, но я пытаюсь узнать, как я могу взять номер порта у json, а затем прочитать указанный номер порта, чтобы я мог переслать его для передачи. Я понимаю, что JSON возвращает порт, но я не уверен, как и как взять этот порт и вставить его в передачу
Dodgexander

Ответы:

2

Если вы спрашиваете Как я могу получить номер порта из этих входных данных? ", со следующими данными:

{"arguments":{},"result":"success"} {"port":37482}

Тогда я бы посоветовал вам взглянуть на jq:

$ echo '{"arguments":{},"result":"success"} {"port":37482}' | jq -s '.[1].port'
37482

jq -s будут " чавкать «вход в массив, это необходимо, так как вы предоставляете два различных объекта:

$ echo '{"arguments":{},"result":"success"} {"port":37482}' | jq -s '.'
[
  {
    "arguments": {},
    "result": "success"
  },
  {
    "port": 37482
  }
]

Затем вы должны обратиться ко второму элементу массива ( .[1] ), а затем port 'элемент ( .[1].port ).


В качестве дополнения для решения некоторых из ваших дальнейших вопросов:

Вы знаете, что такое JSON, вы берете его здесь и можете легко напечатать, перенаправить в файл и т. Д.

client_id=$(cat "$client_id_file")
curl "http://209.222.18.222:2000/?client_id=$client_id" > EXAMPLE.json

Я определил метод для извлечения номера порта выше, но если вы не можете / не хотите использовать jq, затем python будет работать хорошо , но, к сожалению, ваш ввод не совсем-JSON, поэтому нам нужно работать немного усерднее:

Заметка : нам нужно передать JSON в качестве первого аргумента, так как скрипт входит через stdin, поэтому echo xxx | jq Подход выше не будет работать хорошо.

$ python - <<"EOF" '{"arguments":{},"result":"success"} {"port":37482}'
def read_obj(filename):
    from sys import argv
    from json import JSONDecoder
    decoder = JSONDecoder()
    file_content = argv[1].lstrip()
    while file_content:
        obj, eod = decoder.raw_decode(file_content)
        file_content = file_content[eod:].lstrip()
        yield obj

x = read_obj('x')
obj = next(x) # discard the first object
obj = next(x) # use the second object
print(obj['port'])
EOF

Я не могу помочь вам взаимодействовать с передачей.

Attie
источник
Спасибо! Я не уверен, как я могу установить JQ в моей системе, я запускаю помидор на маршрутизаторе, единственный репозиторий, к которому у меня тоже есть доступ, это optware.
Dodgexander
Вы могли бы построить его из источника =)
Attie
Я действительно не знаю, каковы выходные данные от json, я знаю, что json возвращает номер порта, но как я могу найти, как потяните номер порта из JSON? Вот API перенаправления портов: privateinternetaccess.com/forum/discussion/23431/...
Dodgexander
Спасибо за эту информацию. Я думаю, что я разработал, как это сделать, я добавил свой ответ. Я обнаружил, что самый простой способ после обрезки json - передать номер порта в качестве переменной в пакет с именем translation remote, который предназначен для взаимодействия с работающим демоном. Я на самом деле пытался скомпилировать jq, но не смог из-за ошибки. Новая версия gcc, которую я использовал, не поддерживала параметр -qversion. В конце концов я обнаружил, что json возвращал порт: номер порта. После исправления моей строки awk он успешно обрезал ее и передал в качестве переменной $ port, которую я затем передал удаленной передаче!
Dodgexander
Большое спасибо за вашу помощь, я многому научился, плюс я не хочу заканчивать это здесь, я хотел бы привести в порядок скрипт, чтобы сделать его более удобным для пользователя. Это может быть мой первый сценарий, большую часть которого я скопировал откуда-то еще, но он очень рудиментален!
Dodgexander
0

Успех! Рабочий скрипт ниже:

зависимости: translation-remote - вы можете установить пакет translation-remote-openssl через optware. sha256sum - пакет программного обеспечения coreutils-sha256sum

#!/usr/bin/env bash
#
# Enable port forwarding when using Private Internet Access
#
# Usage:
#  ./port_forwarding.sh
# script must be run within 2 mins of connecting to vpn server. Do not forget to reconnect/connect
# fill in your transmission username, password and hostname/ip below:

TRANSUSER=xxxxx
TRANSPASS=xxxxx
TRANSHOST=localhost
#now let the script do the work

Sleep 20
echo pausing to wait for vpn to connect and transmission to start

error( )
{
  echo "$@" 1>&2
  exit 1
}

error_and_usage( )
{
  echo "$@" 1>&2
  usage_and_exit 1
}

usage( )
{
  echo "Usage: `dirname $0`/$PROGRAM"
}

usage_and_exit( )
{
  usage
  exit $1
}

version( )
{
  echo "$PROGRAM version $VERSION"
}


port_forward_assignment( )
{
  client_id_file="/etc/openvpn/pia_client_id"
  if [ ! -f "$client_id_file" ]; then
    if hash shasum 2>/dev/null; then
      head -n 100 /dev/urandom | shasum -a 256 | tr -d " -" > "$client_id_file"
    elif hash sha256sum 2>/dev/null; then
      head -n 100 /dev/urandom | sha256sum | tr -d " -" > "$client_id_file"
    else
      echo "Please install shasum or sha256sum, and make sure it is visible in your \$PATH"
      exit 1
    fi
  fi
  client_id=`cat "$client_id_file"`
  json=`curl "http://209.222.18.222:2000/?client_id=$client_id" 2>/dev/null`
  if [ "$json" == "" ]; then
    json='Port forwarding is already activated on this connection, has expired, or you are not connected to a PIA region that supports port forwarding'
  fi

  echo server returned: $json

#trim VPN forwarded port from JSON
PORT=$(echo $json | awk 'BEGIN{r=1;FS="[{}\":]+"} /port/{r=0; print $3} END{exit r}')
echo if successful, trimmed port is:$PORT

#change transmission port on the fly

transmission-remote $TRANSHOST --auth $TRANSUSER:$TRANSPASS -p "$PORT"
echo here are your transmission credentials: host:$TRANSHOST username:$TRANSUSER password:$TRANSPASS
}
echo remember to run no longer than 2 mins after reconnecting/connecting to vpn server.

EXITCODE=0
PROGRAM=`basename $0`
VERSION=2.1

while test $# -gt 0
do
  case $1 in
  --usage | --help | -h )
    usage_and_exit 0
    ;;
  --version | -v )
    version
    exit 0
    ;;
  *)
    error_and_usage "Unrecognized option: $1"
    ;;
  esac
  shift
done

port_forward_assignment

exit 0
Dodgexander
источник