Shell Script to Get Weather Data from OpenWeatherMap

Here’s a shell script that gets the ISO 3166-1 alpha-2 country code, then uses it to get precise latitude/longitude from the Geocoding API, and finally gets weather data from OpenWeatherMap.

#!/bin/bash

# Check if required commands are installed
if ! command -v jq &> /dev/null || ! command -v curl &> /dev/null; then
    echo "This script requires 'jq' and 'curl' to be installed."
    exit 1
fi

# Configuration
OPENWEATHER_API_KEY="your_api_key_here"  # Replace with your OpenWeatherMap API key
CITY_NAME="$1"
COUNTRY_NAME="$2"

if [ -z "$CITY_NAME" ]; then
    echo "Usage: $0 <city_name> [country_name]"
    exit 1
fi

# Function to get country code from country name
get_country_code() {
    local country_name="$1"
    # Using RestCountries API to get country code
    curl -s "https://restcountries.com/v3.1/name/${country_name}?fullText=true" | \
    jq -r '.[0].cca2'
}

# Function to get latitude and longitude
get_lat_lon() {
    local city="$1"
    local country_code="$2"
    
    if [ -n "$country_code" ]; then
        # With country code for more precise results
        curl -s "http://api.openweathermap.org/geo/1.0/direct?q=${city},${country_code}&limit=1&appid=${OPENWEATHER_API_KEY}" | \
        jq -r '.[0] | [.lat, .lon] | @tsv'
    else
        # Without country code (may return multiple results)
        curl -s "http://api.openweathermap.org/geo/1.0/direct?q=${city}&limit=1&appid=${OPENWEATHER_API_KEY}" | \
        jq -r '.[0] | [.lat, .lon] | @tsv'
    fi
}

# Function to get weather data
get_weather() {
    local lat="$1"
    local lon="$2"
    
    curl -s "https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${OPENWEATHER_API_KEY}&units=metric" | \
    jq .
}

# Main script execution
if [ -n "$COUNTRY_NAME" ]; then
    echo "Getting country code for $COUNTRY_NAME..."
    COUNTRY_CODE=$(get_country_code "$COUNTRY_NAME")
    
    if [ -z "$COUNTRY_CODE" ] || [ "$COUNTRY_CODE" = "null" ]; then
        echo "Could not find country code for $COUNTRY_NAME. Proceeding without country code..."
    else
        echo "Using country code: $COUNTRY_CODE"
    fi
fi

echo "Getting coordinates for $CITY_NAME ${COUNTRY_CODE:+, $COUNTRY_CODE}..."
COORDS=$(get_lat_lon "$CITY_NAME" "$COUNTRY_CODE")

if [ -z "$COORDS" ] || [ "$COORDS" = "null null" ]; then
    echo "Could not find coordinates for $CITY_NAME"
    exit 1
fi

LAT=$(echo "$COORDS" | awk '{print $1}')
LON=$(echo "$COORDS" | awk '{print $2}')

echo "Coordinates found: Latitude $LAT, Longitude $LON"
echo "Getting weather data..."
get_weather "$LAT" "$LON"

How to Use This Script

  1. Save this script as weather.sh
  2. Make it executable: chmod +x weather.sh
  3. Install dependencies: jq (for JSON parsing) and curl
  4. Run it with:

Notes

  1. You need to replace your_api_key_here with your actual OpenWeatherMap API key
  2. The script uses three APIs:
  3. If you don’t specify a country, it will use the first result from the geocoding API which might not be the one you want
  4. The weather data is returned in metric units (Celsius for temperature)