Trying to write a script which uses Charles Karney's GeodSolve to solve a straight-forward geodesic problem. GeodSolve takes the input: lat1 lon1 azi1 dist1, and outputs: lat2 lon2 azi2.

I have a file ("azi_dist_file") containing azimuths and distances in the first and second column respectively. In the below simple script the user is asked to provide the initial position, lat1 and lon1, while azi1 and dist1 are fetched from azi_dist_file. The programme GeodSolve will then solve the direct geodesic problem and return the endpoint position, lat2 lon2 (and azi2 which is irrelevant here); I'd like this second position to be used as the initial position in a further invocation of GeodSolve, but fetching azi2 and dist2 from the 2nd row of azi_dist_file; repeated until the last row in that file is reached. Finally, I'd like all the lat,lon,azi,dist values written to a new file.

So far I have managed to write the following.

echo "Enter starting latitude: "
read lat1
echo "Enter starting longitude: "
read lon1
alpha1=`awk 'NR==1{print;exit}' azi_dist_file|cut -f1 -d$'\t'`
dist1=`awk 'NR==1{print;exit}' azi_dist_file|cut -f2 -d$'\t'`
echo "$lat1 $lon1 $alpha1 $dist1" >> lat_lon_azi_dist_file
echo $lat1 $lon1 $alpha1 $dist1 | GeodSolve
lat2=`echo $lat1 $lon1 $alpha1 $dist1 | GeodSolve | cut -f1 -d' '`
lon2=`echo $lat1 $lon1 $alpha1 $dist1 | GeodSolve | cut -f2 -d' '`
echo "$lat2 $lon2"
  • 1
    Please edit your question and show us an example of your input file. Also, clarify what your script can do so far (much easier than having us figure it out from your code) and what it doesn't. Finally, as a general rule, I'd avoid expecting input from the user. It is much easier to pass the starting values as parameters to your script (script.sh lat1 lat2). The values will then be available to the script as $1 and $2 respectively.
    – terdon
    Sep 13, 2016 at 15:44

1 Answer 1


It sounds like you want something like:

#!/bin/bash -
# lat/lon passed as arguments to the script instead of being input to the
# user:
lat=${1?} lon=${2?}

while read alpha dist ignore; do
  printf '%s\n' "$lat $lon $alpha $dist" >&3
  read lat lon ignore < <(
    printf '%s\n' "$lat $lon $alpha $dist" | GeodSolve 3>&-)
  printf '%s\n' "$lat $lon"
done < azi_dist_file 3> lat_lon_azi_dist_file

The read vars < <(cmd) is to work around the fact that in bash (contrary to zsh or AT&T ksh) in cmd | read vars, the read command is run in a subshell. Alternatively, with recent versions of bash, you can use shopt -s lastpipe to have bash behave like zsh or ksh in this instance.

POSIXly, you can also use:

unset -v IFS; set -f; set -- $(cmd); lat=$1 lon=$2

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .