我收到错误:
awk:错误的正则表达式'{|:|}':前面的正则表达式无效 {"arguments":{},"result":"success"} {"port":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 发出端口号请求,然后将接收到的端口转发到传输守护进程。
答案1
如果你问的是“我如何从该输入数据中获取端口号?",数据如下:
{"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
我无法帮助你进行传输接口。
答案2
成功了!工作脚本如下:
依赖项: transmission-remote - 您可以通过 optware 安装 transmission-remote-openssl 包。 sha256sum - optware 包 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