Ungültiger vorangegangener regulärer Ausdruck

0

Ich erhalte eine Fehlermeldung:

awk: bad regex '{|: |}': Ungültiger vorangegangener regulärer Ausdruck {"arguments": {}, "result": "success"} {"port": 37482}

Was meiner Meinung nach mit dieser Zeile zusammenhängt:

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

Weiß jemand, was es bedeutet und wie ich es beheben kann? Ich bin neu in der Skripterstellung, verstehe aber den Ausdruck |: | ist falsch. $ json ist eine Datei, die ich aus meinem VPN mit Portinformationen für die Weiterleitung ziehe.

Meine Eingabe:

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

Das Skript stammt von: https://www.privateinternetaccess.com/forum/discussion/23431/new-pia-port-forwarding-api/p3 ?

Es wurde entwickelt, um eine Anforderung an die API für eine Portnummer zu richten und diesen empfangenen Port dann an den Übertragungsdämon weiterzuleiten.

Dodgexander
quelle
Was versuchst du zu erreichen? Was ist Ihr Input, was ist Ihr gewünschter Output? Wenn Sie JSON-Eingaben haben, posten Sie diese. Wenn Sie versuchen, die Portnummer aus dem JSON abzurufen, sagen Sie dies. Versuchen Sie nicht, ein XY-Problem zu stellen meta.stackexchange.com/a/66378/364309
Attie
Ich habe vorher hier gefragt, aber keine Antworten erhalten. Ich dachte, weil ich die Frage zu spezifisch gemacht habe! superuser.com/questions/1258891/...
Dodgexander
Es tut mir leid, dass ich ein Noob bin, aber ich versuche zu lernen, wie ich die Portnummer aus dem JSON entnehmen und dann die angegebene Portnummer lesen kann, damit ich sie zur Übertragung weiterleiten kann. Ich verstehe, dass der JSON den Port zurückgibt, aber ich bin nicht sicher, wie oder wie ich diesen Port nehmen und in die Übertragung einfügen soll
Dodgexander,

Antworten:

2

Wenn Sie fragen " Wie kann ich die Portnummer aus diesen Eingabedaten abrufen? ", Mit den folgenden Daten:

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

Dann rate ich dir mal jq:

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

jq -sWird die Eingabe in ein Array " schlürfen ", ist dies erforderlich, da Sie zwei unterschiedliche Objekte bereitstellen:

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

Sie müssen dann das zweite Element des Arrays ( .[1]) und anschließend das portElement ' ' ( .[1].port) adressieren .


Als Erweiterung, um einige Ihrer weiteren Fragen zu beantworten:

Sie wissen, was der JSON ist, und können ihn einfach ausdrucken, in eine Datei umleiten usw.

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

Ich habe oben eine Methode zum Extrahieren der Portnummer identifiziert, aber wenn Sie diese nicht verwenden können / möchten jq, python funktioniert sie einwandfrei , aber Ihre Eingabe scheint leider nicht ganz JSON zu sein. Wir müssen also arbeiten etwas schwieriger:

Hinweis : Wir müssen JSON als erstes Argument übergeben, da das Skript über stdin eingeht, sodass der echo xxx | jqoben beschriebene Ansatz nicht gut funktioniert.

$ 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

Ich kann Ihnen bei der Übertragung nicht helfen.

Attie
quelle
Vielen Dank! Ich bin mir nicht sicher, wie ich jq auf meinem System installieren kann. Ich verwende tomato auf einem Router. Das einzige Repository, auf das ich Zugriff habe, ist optware.
Dodgexander
Sie könnten es aus der Quelle bauen =)
Attie
Ich weiß nicht wirklich, wie die Ausgabedaten von JSON lauten. Ich weiß, dass JSON die Portnummer zurückgibt, aber wie kann ich herausfinden, wie die Portnummer von JSON abgerufen wird? Hier ist das Port - Forwarding API: privateinternetaccess.com/forum/discussion/23431/...
Dodgexander
Danke für diese Info. Ich glaube, ich habe herausgefunden, wie es geht, und habe meine Antwort hinzugefügt. Nach dem Trimmen des JSON fand ich den einfachsten Weg, die Portnummer als Variable an ein Paket mit dem Namen transmission remote zu übergeben, das für die Interaktion mit dem laufenden Daemon ausgelegt ist. Ich habe tatsächlich versucht, jq zu kompilieren, konnte es aber aufgrund eines Fehlers nicht. Die neue GCC-Version, die ich verwendet habe, hat den Parameter -qversion nicht unterstützt. Am Ende fand ich, dass der JSON-Port zurückkehrte: numberofport. Nachdem ich meine awk-Zeile korrigiert hatte, wurde sie erfolgreich gekürzt und als variabler $ port übergeben, den ich dann an die Sende-Fernsteuerung übergeben habe!
Dodgexander
Vielen Dank für Ihre Hilfe, ich habe viel gelernt und möchte es hier nicht beenden. Ich möchte das Skript aufräumen, um es benutzerfreundlicher zu machen. Es ist vielleicht mein erstes Drehbuch, das ich größtenteils von einem anderen Ort kopiert habe, aber es ist sehr rudimentär!
Dodgexander
0

Erfolg! Arbeitsskript unten:

Abhängigkeiten: transmission-remote - Sie können das Paket transmission-remote-openssl über optware installieren. sha256sum - optware-Paket 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
quelle