Skip to main content
Notice removed Improve details by Vlastimil Burián
Bounty Ended with Toby Speight's answer chosen by Vlastimil Burián
Notice added Improve details by Vlastimil Burián
Bounty Started worth 100 reputation by Vlastimil Burián
Became Hot Network Question
deleted 4 characters in body; edited tags
Source Link
toolic
  • 15.7k
  • 5
  • 29
  • 216

I would like to ask for a a finalfinal review of my Lightshot print screen Linux handler POSIX shell script.

When I started writing it, it has beenwas a one-liner (shell snippet), but then I decided to grow it, and learn during that time while at it. It's been a wonderful journey, but all has to reach an end. And so this will be my last ever review of this script.

PS: Give yourself time with reviewing it, the. The more notes I get, the better the final release could be. There is no dead-linedeadline or anything alike. Thank you all and good hunting!

In case you need anything from description up to usage of this small script, look at the project on GitHub (direct link), I. I gave it full details there.

I would like to ask for a final review of my Lightshot print screen Linux handler POSIX shell script.

When I started writing it, it has been a one-liner (shell snippet), but then I decided to grow it, and learn during that time while at it. It's been a wonderful journey, but all has to reach an end. And so this will be my last ever review of this script.

PS: Give yourself time with reviewing it, the more notes I get, the better the final release could be. There is no dead-line or anything alike. Thank you all and good hunting!

In case you need anything from description up to usage of this small script, look at the project on GitHub (direct link), I gave it full details there.

I would like to ask for a final review of my Lightshot print screen Linux handler POSIX shell script.

When I started writing it, it was a one-liner (shell snippet), but then I decided to grow it, and learn during that time while at it. It's been a wonderful journey, but all has to reach an end. And so this will be my last ever review of this script.

PS: Give yourself time with reviewing it. The more notes I get, the better the final release could be. There is no deadline or anything alike. Thank you all and good hunting!

In case you need anything from description up to usage of this small script, look at the project on GitHub (direct link). I gave it full details there.

typo fixed && added link to GitHub
Source Link
Vlastimil Burián
  • 2.1k
  • 2
  • 12
  • 32

I would like to ask for a final review of my Lightshot print screen Linux handler POSIX shell script review.

When I started writing it, it has been a one-line shellliner (shell snippet), but then I decided to grow it, and learn during that time while at it. It's been a wonderful journey, but all has to reach an end. And so this will be my last ever review of this script.

In case you need anything from description up to usage of this small script, look at the project on GitHub (direct link), I gave it full details there.

I would like to ask for a final review of my Lightshot print screen Linux handler POSIX shell script review.

When I started writing it, it has been a one-line shell snippet, but then I decided to grow it, and learn during that time while at it. It's been a wonderful journey, but all has to reach an end. And so this will be my last ever review of this script.

I would like to ask for a final review of my Lightshot print screen Linux handler POSIX shell script.

When I started writing it, it has been a one-liner (shell snippet), but then I decided to grow it, and learn during that time while at it. It's been a wonderful journey, but all has to reach an end. And so this will be my last ever review of this script.

In case you need anything from description up to usage of this small script, look at the project on GitHub (direct link), I gave it full details there.

Source Link
Vlastimil Burián
  • 2.1k
  • 2
  • 12
  • 32

Final look at my Lightshot print screen Linux handler POSIX shell script

I would like to ask for a final review of my Lightshot print screen Linux handler POSIX shell script review.

When I started writing it, it has been a one-line shell snippet, but then I decided to grow it, and learn during that time while at it. It's been a wonderful journey, but all has to reach an end. And so this will be my last ever review of this script.

With your help I hope, that is. I attach the whole code as it is now before publishing.

PS: Give yourself time with reviewing it, the more notes I get, the better the final release could be. There is no dead-line or anything alike. Thank you all and good hunting!


#!/bin/sh

#--------------------------------------------------------------------------------
#--                    Lightshot print screen Linux handler                    --
#--                     Git: https://burian.work/lightshot                     --
#--                             Code: POSIX shell                              --
#--                                License: MIT                                --
#--                                Version: 9.1                                --
#--                          Released on: 2025-Oct-01                          --
#--                      E-mail: [email protected]                       --
#--                    Copyright 2018-2025 Vlastimil Burian                    --
#--------------------------------------------------------------------------------

# The hotkey variable is on top for easy set-up; overridable with -k switch.
# Run this script with -h for complete help to this script with an example.
# Just run this script to test out, it will print out if Lightshot was found.
# Set this to the same hotkey which you have set up in your Lightshot options.
# For the left control key and the print screen key put in Control_L+Print.
hotkey=Print

# Treat unset variables as errors when substituting.
# Clarification: this means that accessing any unassigned variable
# produces immediate termination of the script with an error printed.
set -o nounset

# (bool) Function to test a variable for an integer.
is_int()
{
    case "${1#[+-]}" in
        (*[!0123456789]*) return 1 ;;
        ('')              return 1 ;;
        (*)               return 0 ;;
    esac
}

# (bool) Function to test a variable for an unsigned integer.
is_uint()
{
    case "$1" in
        ([+-]*) return 1 ;;
    esac

    is_int "$1"
}

# (bool) Function to test a variable for a "safe" exit code:
# "Safe" exit code must be an unsigned integer from the range of <0;125> which is considered
# the safe range, the remaining range of <126;255> is reserved or otherwise not recommended.
is_safe_exit()
{
    is_uint "$1" && [ "$1" -le 125 ]
}

# (string) Function to detect basic variable types passed to my functions:
# empty, integer, file (with specific info), the rest is considered string.
dump_args()
{
    # we do not write anything for 0 arguments
    [ "$#" -eq 0 ] && return 1
    exec >&2
    i=1
    printf '%s\n' \
        "dump_args()" \
        "$# arguments inspected:"
    while [ "$#" -gt 0 ]; do
        printf "[%d]: '%s' " "$i" "$1"
        if [ -z "$1" ]; then
            printf '%s' "(empty)"
        elif is_int "$1"; then
            printf '%s' "(integer)"
        elif [ -e "$1" ]; then
            printf '%s' "(file: $( file -b "$1" ))"
        else
            printf '%s' "(string)"
        fi
        printf '\n'
        shift
        i=$(( i + 1 ))
    done
}

# (string) Function to print an error message.
error()
{
    printf >&2 '%s\n' \
        "Error heading: $1" \
        "Error message: $2"
}

# (string) Function to print an error message and exit right away.
error_out()
{
    if ! { [ "$#" -eq 2 ] && [ -n "$1" ] && [ -n "$2" ]; } &&
       ! { [ "$#" -eq 3 ] && [ -n "$1" ] && [ -n "$2" ] && [ "$3" -ge 1 ] && is_safe_exit "$3"; } then
        dump_args "$@"
        # shellcheck disable=SC2016
        printf >&2 '%s\n' \
            'error_out() input check' \
            'Wrong number, type or empty arguments have been passed to the function.' \
            'Expected the following strings: $1 = error heading, $2 = error message.' \
            'Optionally, accepting a number: $3 = exit code; if not given 1 is used.' \
            'Acceptable exit code range: anywhere between <1;125>; 1 is the default.'
        exit 1
    fi
    error "$1" "$2"
    exit "${3:-1}"
}

if [ "$( id -u )" -eq 0 ]; then
    error_out 'is_user_root()' 'Running this script with root privileges is not recommended! Expected an ordinary user.'
fi

dependencies()
{
    if [ "$#" -eq 0 ]; then
        error_out 'dependencies() input check' 'No arguments passed to the function! At least one program/package name pair expected.'
    fi
    if [ "$(( $# % 2 ))" -ne 0 ]; then
        dump_args "$@"
        error_out 'dependencies() input check' 'Odd number of arguments has been passed to the function. Program and package names in pairs expected.'
    fi

    dependency_missing=false

    while [ "$#" -gt 0 ]; do
        if ! command -v "$1" >/dev/null 2>&1; then
            dependency_missing=true
            error 'dependencies(): unmet required dependency' "This script requires '$1' program but it is not available on this system! On Ubuntu/Debian OS, just install the '$2' package; other systems may differ."
        fi
        shift 2
    done

    if "$dependency_missing"; then
        exit 1
    fi
}

dependencies \
    pgrep      procps \
    xdotool    xdotool

usage()
{
# Original logic:
#    if ! { [ "$#" -eq 1 ] && is_safe_exit "$1"; } then

    if [ "$#" -ne 1 ] || ! is_safe_exit "$1"; then
        dump_args "$@"
        # shellcheck disable=SC2016
        error_out 'usage() input check' 'Number required: $1 = exit code from the script.'
    fi

    [ "$1" -ne 0 ] && exec >&2

cat <<EOF
Project: Lightshot print screen Linux handler
Version: 9.1 (2025-Oct-01)
GitHub : https://burian.work/lightshot
--------------------------------------------------------------------
Description: This script works with XDOTOOL to trigger Print Screen
key combination in Lightshot application installed on Linux in Wine.
The script, however, won't launch Lightshot for you due to variable
installation locations which make it impossible. You need to run it!
License is MIT. The code can be further enhanced by others provided
that any new copies have my copyright notice included in every case.
--------------------------------------------------------------------
Usage in terminal: ./$( basename "$0" ) [-k HotKey]

    -k HotKey: Optional switch requiring one argument,
        which is the print screen hotkey combination.
        For the left Control key and the Print Screen key
        that would be -k Control_L+Print (as an example).

    -h: Show this help.

Usage in desktop environment:

    You need to find Keyboard shortcuts, and re-map Print to run
    this script, an example from Linux Mint is placed on GitHub.

Author:
    Copyright 2018-2025
    Vlastimil Burian
    [email protected]
EOF

    exit "$1"
}

while getopts ':hk:' option; do

    case "$option" in

        k)
            hotkey=$OPTARG
            shift 2
        ;;

        h)
            usage 0
        ;;

        *)
            dump_args "$@"
            usage 1
        ;;

    esac

done


# This was simulated and IDK how to prevent erroring out without catching it...
# But it does seem to work properly if some expected Key combination is passed.
#./lightshot_print_screen -k -k

# Possible problem under my question here, suggesting including the command below, investigate:
# https://unix.stackexchange.com/a/778450/126755
#shift $(( OPTIND - 1 ))


if [ "$#" -ne 0 ]; then
    dump_args "$@"
    usage 2              # Changed from 1 to 2 for debugging the "problem" above
fi

get_process_id()
{
    if [ "$#" -ne 1 ] || [ -z "$1" ]; then

# Original logic:
#    if ! { [ "$#" -eq 1 ] && [ -n "$1" ]; } then

        dump_args "$@"
        # shellcheck disable=SC2016
        error_out 'get_process_id() input check' 'String required: $1 = a process name to find id to.'
    fi
    # -o, --oldest: least recently started
    pgrep -o "$1"
}

get_window_id()
{

# Original logic:
#    if ! { [ "$#" -eq 2 ] && is_uint "$1" && [ -n "$2" ]; } then

    if [ "$#" -ne 2 ] || ! is_uint "$1" || [ -z "$2" ]; then
        dump_args "$@"
        error_out 'get_window_id() input check' 'Two valid arguments were not passed to the function! Expected a process id (unsigned integer) and a window name (string).'
    fi
    #--all  : Require all conditions to be met.
    #--sync : Wait until a search result is found.
    #--limit: Stop searching after finding N matching windows.
    #--pid  : Match windows that belong to a specific process id.
    #--name : Match against the window name. This is the same string that is displayed in the window titlebar.
    if ! xdotool search --all --sync --limit 1 --pid "$1" --name "$2"; then
        error_out 'get_window_id()' "No window matching process id '$1' and window name '$2' has been found."
    fi
}

# The Lightshot file name is case-sensitive.
lightshot_process_id=$( get_process_id Lightshot.exe )

if ! is_uint "$lightshot_process_id"; then
    # shellcheck disable=SC2016
    error_out 'is_uint $lightshot_process_id' 'Lightshot process is not running. Launch Lightshot app first, please.'
fi

# The Lightshot window name is case-insensitive.
lightshot_window_id=$( get_window_id "$lightshot_process_id" Lightshot )

if ! is_uint "$lightshot_window_id"; then
    # shellcheck disable=SC2016
    error_out 'is_uint $lightshot_window_id' 'Lightshot process was found (is running) but its window was not found for some reason / get_window_id() returned an empty value.'
fi

if xdotool key --window "$lightshot_window_id" "$hotkey"; then
    printf '%s\n' \
        "Success, the hotkey = $hotkey was successfully sent to Lightshot window!" \
        'If the Lightshot overlay did not appear, you likely sent a wrong hotkey.' \
        'In such a case, please adjust the hotkey in Lightshot tray options menu.'
else
    error_out "xdotool key --window $lightshot_window_id $hotkey" 'The above send-hotkey command encountered an unknown error.'
fi