Regex precedente no válido


0

Recibo un error:

awk: mala expresión regular '{|: |}': Expresión regular precedente no válida {"argumentos": {}, "resultado": "éxito"} {"puerto": 37482}

Lo que creo está relacionado con esta línea:

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

¿Alguien sabe lo que significa y cómo puedo solucionarlo? Soy nuevo en las secuencias de comandos pero, según tengo entendido, la expresión Es incorrecto. $ json es un archivo que estoy extrayendo de mi VPN con información de puerto para reenviar.

Mi entrada:

#!/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

El script está tomado de: https://www.privateinternetaccess.com/forum/discussion/23431/new-pia-port-forwarding-api/p3 ?

Está diseñado para solicitar a su API un número de puerto y luego reenviar ese puerto recibido al demonio de transmisión.


¿Qué está tratando de lograr? ¿Cuál es su entrada, cuál es su salida deseada? Si tiene alguna entrada JSON, publíquela. Si está intentando recuperar el número de puerto del JSON, dígalo. Trate de no preguntar un problema XY meta.stackexchange.com/a/66378/364309
Attie

Pregunté previamente aquí pero no recibí ninguna respuesta. ¡Pensé porque hice la pregunta demasiado específica! superuser.com/questions/1258891/...
Dodgexander

Perdón por ser un novato, pero estoy tratando de aprender cómo puedo tomar el número de puerto del json y luego leer el número de puerto dado para poder reenviarlo a la transmisión. Entiendo que el json devuelve el puerto, pero no estoy seguro de cómo, ni cómo tomar ese puerto e insertarlo en la transmisión
Dodgexander

Respuestas:


2

Si pregunta " ¿Cómo puedo obtener el número de puerto de estos datos de entrada? ", Con los siguientes datos:

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

Entonces te aconsejo que mires jq:

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

jq -s" sorberá " la entrada en una matriz, esto es necesario ya que proporciona dos objetos distintos:

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

Luego debe abordar el segundo elemento de la matriz ( .[1]) y, posteriormente, el portelemento ' ' ( .[1].port).


Como una extensión para abordar algunas de sus preguntas adicionales:

Usted sabe qué es el JSON, lo toma aquí y puede imprimirlo fácilmente, redirigirlo a un archivo, etc.

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

Identifiqué un método para extraer el número de puerto anterior, pero si no puede / no quiere usarlo jq, python funcionaría bien , pero desafortunadamente su entrada parece no ser bastante JSON, por lo que debemos trabajar un poco más duro

Nota : necesitamos pasar el JSON como primer argumento, ya que el script ingresa a través de stdin, por lo que el echo xxx | jqenfoque anterior no funcionará bien.

$ 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

No puedo ayudarte a interactuar con la transmisión.


¡Gracias! No estoy seguro de cómo puedo instalar jq en mi sistema, estoy ejecutando tomate en un enrutador, el único repositorio al que también tengo acceso es el software.
Dodgexander

Puedes construirlo desde source =)
Attie

Realmente no sé cuáles son los datos de salida de json, sé que json devuelve el número de puerto, pero ¿cómo puedo encontrar cómo extraer el número de puerto de json? Aquí está la API de reenvío de puertos: privateinternetaccess.com/forum/discussion/23431/…
Dodgexander

Gracias por esta información Creo que resolví cómo hacerlo, agregué mi respuesta. Descubrí que la forma más fácil después de recortar el json era pasar el número de puerto como una variable a un paquete llamado transmisión remota que está diseñado para interactuar con el demonio en ejecución. En realidad intenté compilar jq pero no pude debido a un error. La nueva versión de gcc que estaba usando no admitía el parámetro -qversion. Al final encontré que el json regresaba port: numberofport. ¡Después de corregir mi línea awk, la estaba recortando y pasando como el puerto $ variable que luego pasé al control remoto de transmisión!
Dodgexander

Muchas gracias por su ayuda, he aprendido mucho, además no quiero terminarlo aquí, me gustaría ordenar el script para que sea más fácil de usar. Puede ser mi primer guión, la mayoría de los cuales copié de otro lugar, ¡pero es muy rudimentario!
Dodgexander

0

¡Éxito! Guión de trabajo a continuación:

Dependencias: transmisión-remota: puede instalar el paquete de transmisión-remota-openssl a través del software. sha256sum - paquete de software 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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.