Skip to content

Instantly share code, notes, and snippets.

@kawaz
Created Oct 26, 2016
Embed
What would you like to do?
maxOS の VPN をCLIで一覧したり接続・切断したりするスクリプト
#!/usr/bin/env bash
set -e
usage() {
local name
name=$(basename "$0")
echo "Usage: $name command [options]"
echo " $name list"
echo " $name connect ID"
echo " $name disconnect ID"
}
vpn_list() {
scutil --nc list |
perl -pe's/.*?\((\w+)\) +([\w-]+) +(\w+) +--> (\w+) +"(.*)"? +\[.*?\]$/$1\t$2\t$3\t$4\t$5/i' |
while read -r Status Id Type SubType UserDefinedName; do
[[ $Type == PPP ]] || continue
UserDefinedName="$(scutil <<< "show Setup:/Network/Service/$Id" | grep '^ UserDefinedName : ')"
UserDefinedName=${UserDefinedName#* : }
jq \
--arg Status "$Status" \
--arg Id "$Id" \
--arg Type "$Type" \
--arg SubType "$SubType" \
--arg UserDefinedName "$UserDefinedName" \
'{ Id:$Id, Type:$Type, SubType:$SubType, Status:$Status, UserDefinedName:$UserDefinedName }' <<< true
done
}
vpn_connect() {
local Id=$1
vpn_opwait connect "$Id" Connected
}
vpn_disconnect() {
local Id=$1
vpn_opwait disconnect "$Id" Disconnected
}
vpn_opwait() {
local operation=$1 Id=$2 Status=$3 UserDefinedName
UserDefinedName=$(vpn_get "$Id" "UserDefinedName")
osascript -l JavaScript -e 'run=args=>{(se=>se[args[0]](se.networkPreferences.services[args[1]]))(Application("System Events"))}' "$operation" "$UserDefinedName"
vpn_wait "$Id" "$Status"
}
vpn_get() {
if [[ -z $2 ]]; then
vpn_list | jq --arg Id "$1" -s '.[]|select(.Id==$Id)'
else
vpn_get "$1" | jq --arg Key "$2" '.[$Key]' -r
fi
}
vpn_wait() {
local Id=$1 Status=$2 count=1
while cur=$(vpn_get "$Id" Status); [[ $cur == *ing ]]; do
echo "$cur $((count++))"
sleep 1
done
[[ -n "$cur" ]]
echo "$cur"
[[ $cur == "$Status" ]]
}
case $1 in
list|connect|disconnect)
"vpn_$1" "${@:2}"
;;
*)
usage
;;
esac
@kawaz
Copy link
Author

kawaz commented Oct 26, 2016

scutil --nc {start,stop} で接続と切断が出来ることになってるが scutil --nc start での接続はパスワードとかも全部引数に指定しないといけなくてOS側に設定されてるやつ使えや!ってなるので scutil --nc start は使わない。代わりに Application("System Events") を呼ぶワンライナーのosascriptを使ってる。

本質的には関係ないけどデータの扱いと見た目整形の簡単のために jq を使ってるので brew install jq などが必要。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment