77# - Add Starlink speed test
88# - Upload test result to Cloudflare R2 buckets via Worker proxy
99
10+ VERSION=" 20260204"
11+
1012help () {
1113 echo -e " Usage:\n sudo bash $0 [--install | <interface>]"
1214 echo -e " \nArguments:"
@@ -22,9 +24,12 @@ help () {
2224 echo " sudo bash starlink.sh eth0"
2325 echo -e " \nNote:\n Rich image rendering in terminal requires a modern terminal emulator. (e.g., iTerm2, Ghostty, WezTerm, Kitty, etc.)"
2426 echo -e " \nContact: clarkzjw@uvic.ca"
27+ echo -e " Version: $VERSION "
2528 exit 1
2629}
2730
31+ STARLINK_GRPC_ENDPOINT=" 192.168.100.1:9200"
32+
2833# ######################################################
2934# Detect terminal emulator type and its image protocol support
3035# Some of the code in this section is generated by AI coding tools
@@ -119,6 +124,13 @@ get_uuid () {
119124 echo " $uuid "
120125}
121126
127+ get_datetime () {
128+ datetime=$( date -u " +%Y%m%d-%H%M%S" )
129+ echo " $datetime "
130+ }
131+
132+ DATA_DIR=" "
133+
122134INIT_FLAG=False
123135IFACE=" "
124136if [ " $1 " == " --install" ]; then
@@ -160,7 +172,7 @@ install () {
160172 apt-get update
161173
162174 echo " Installing essential packages..."
163- apt-get install -y curl gnupg2 ca-certificates lsb-release traceroute mtr iputils-ping screen jq bind9-dnsutils wget python3
175+ apt-get install -y curl gnupg2 ca-certificates lsb-release traceroute mtr iputils-ping screen jq bind9-dnsutils wget python3 jq
164176
165177 echo " Install additional tools..."
166178 apt-get install -y chafa gnuplot gawk
@@ -198,10 +210,10 @@ test_subnet () {
198210
199211 if [ $? -eq 0 ]; then
200212 echo " Match $cidr "
201- grep " $cidr " feed.csv || echo " No matching subnet $cidr in feed.csv"
202- grep " $cidr " pops.csv || echo " No matching subnet $cidr in pops.csv"
213+ grep " $cidr " feed.csv || echo -e " \nNo matching subnet $cidr in feed.csv"
214+ grep " $cidr " pops.csv || echo -e " \nNo matching subnet $cidr in pops.csv"
203215 else
204- echo " No Match"
216+ echo -e " \nNo Match"
205217 fi
206218}
207219
@@ -214,38 +226,42 @@ geoip () {
214226 cat feed.csv | awk -F' ,' ' {print $1}' > subnet.txt
215227
216228 echo -e " \n###### GeoIP Lookup via ipinfo.io"
217- curl -4 ipinfo.io --interface " $IFACE "
229+ curl -4 ipinfo.io --interface " $IFACE " > " $DATA_DIR /geoip.txt "
218230 v4_ip=$( curl -4 -s ipinfo.io/ip --interface " $IFACE " )
219231
220232 if [ " $IPV6_AVAILABLE " -eq 0 ]; then
221- curl -6 v6.ipinfo.io --interface " $IFACE "
233+ curl -6 v6.ipinfo.io --interface " $IFACE " >> " $DATA_DIR /geoip.txt "
222234 v6_ip=$( curl -6 -s v6.ipinfo.io/ip --interface " $IFACE " )
223235 fi
224236
225237 echo -e " \n\n###### Checking GeoIP and PoP information"
226- test_subnet " $v4_ip " " subnet.txt"
238+ test_subnet " $v4_ip " " subnet.txt" >> " $DATA_DIR /geoip.txt "
227239 if [ " $IPV6_AVAILABLE " -eq 0 ]; then
228- test_subnet " $v6_ip " " subnet.txt"
240+ test_subnet " $v6_ip " " subnet.txt" >> " $DATA_DIR /geoip.txt "
229241 fi
230242
243+ cat " $DATA_DIR /geoip.txt"
231244 rm -f subnet.txt
232245}
233246
234247cf_ray () {
235248 echo -e " \n###### Cloudflare Ray ID"
236- curl -sI https://www.cloudflare.com/cdn-cgi/trace | grep cf-ray
249+ curl -sI https://www.cloudflare.com/cdn-cgi/trace | grep cf-ray > " $DATA_DIR /cf-ray.txt"
250+ cat " $DATA_DIR /cf-ray.txt"
237251}
238252
239253dns () {
240254 # TODO: support -b option to bind to specific interface
241255 echo -e " \n###### Checking DNS resolver locations"
242256 OPTIONS=" CHAOS TXT id.server +nsid"
243257 echo -e " -- Cloudflare DNS"
244- dig @1.1.1.1 $OPTIONS
258+ dig @1.1.1.1 $OPTIONS > " $DATA_DIR /dig.txt "
245259 echo -e " -- Google DNS"
246- dig @8.8.8.8 $OPTIONS
260+ dig @8.8.8.8 $OPTIONS >> " $DATA_DIR /dig.txt "
247261 echo -e " -- Quad9 DNS"
248- dig @9.9.9.9 $OPTIONS
262+ dig @9.9.9.9 $OPTIONS >> " $DATA_DIR /dig.txt"
263+
264+ cat " $DATA_DIR /dig.txt"
249265}
250266
251267trace () {
@@ -255,18 +271,22 @@ trace () {
255271 if [ -n " $IFACE " ]; then
256272 OPTIONS=" $OPTIONS -I $IFACE "
257273 fi
258- mtr 1.1.1.1 $OPTIONS
274+ mtr 1.1.1.1 $OPTIONS > " $DATA_DIR /mtr.txt "
259275 if [ " $IPV6_AVAILABLE " -eq 0 ]; then
260- mtr 2606:4700:4700::1111 $OPTIONS
276+ mtr 2606:4700:4700::1111 $OPTIONS >> " $DATA_DIR /mtr.txt "
261277 fi
278+
279+ cat " $DATA_DIR /mtr.txt"
262280}
263281
264282grpc_status () {
265283 echo -e " \n###### Starlink GRPC Status"
266- grpcurl -plaintext -d {\" get_status\" :{}} 192.168.100.1:9200 SpaceX.API.Device.Device/Handle
284+ grpcurl -plaintext -d {\" get_status\" :{}} $STARLINK_GRPC_ENDPOINT SpaceX.API.Device.Device/Handle > " $DATA_DIR /grpc_status.json"
285+ cat " $DATA_DIR /grpc_status.json" | jq ' .'
267286
268287 echo -e " \n###### Starlink GRPC Location"
269- grpcurl -plaintext -d {\" get_location\" :{}} 192.168.100.1:9200 SpaceX.API.Device.Device/Handle
288+ grpcurl -plaintext -d {\" get_location\" :{}} $STARLINK_GRPC_ENDPOINT SpaceX.API.Device.Device/Handle > " $DATA_DIR /grpc_location.json"
289+ cat " $DATA_DIR /grpc_location.json" | jq ' .'
270290}
271291
272292show_networking () {
@@ -308,6 +328,12 @@ ping_gw () {
308328 fi
309329}
310330
331+ setup_directory () {
332+ datetime=$( get_datetime)
333+ DATA_DIR=" data/$datetime "
334+ mkdir -p " $DATA_DIR "
335+ }
336+
311337run_once () {
312338 if [ -z " $IFACE " ]; then
313339 echo -e " Error: No interface name specified. \n Please provide the interface name that is connected to Starlink."
@@ -317,6 +343,8 @@ run_once() {
317343
318344 IPV6_AVAILABLE=$( test_ipv6; echo $? )
319345
346+ setup_directory
347+
320348 show_networking
321349 grpc_status
322350 geoip
@@ -333,5 +361,3 @@ if [ "$INIT_FLAG" == "True" ]; then
333361fi
334362
335363run_once
336- # uuid=$(get_uuid)
337- # echo $uuid
0 commit comments