alias lsvideo='sudo $(type -P lspci) -vvvv -d "$($(type -P lspci) -nn|sed -n "/VGA/p"|$(type -P grep) -oP "(?<=\[)[[:alnum:]]{4}:[[:alnum:]]{4}(?=\])")"'
Tuesday, October 29, 2019
lsvideo - List Video Card/Driver Info
Saturday, October 26, 2019
exclude - Excludes Match & Optionally N-before / N-After - in Awk
alias exclude='_(){ local match="${1}";local lnb="${2}";local lnf="${3}"; (($#<1))||[[ "${1}" =~ ^- ]]&&echo "Usage: exclude <match> [<lines back [0-9],def=0> <lines forward [0-9],def=0>]"&&return 1;awk -vmtch="${match}" -vlnb=${lnb} -vlnf=${lnf} "BEGIN{i=0;skip=0}{if(skip==0 && \$0 ~ mtch){for(j=0;j<lnb&&i>0;j++)delete arr[--i];skip=lnf;}else{if(skip==0)arr[i++]=\$0;else skip--;}}END{for(i=0;i<length(arr);i++)print arr[i];}";};_'
Friday, October 25, 2019
g2nasm - GAS ASM to NASM
Why didn't anyone else think to do this over the last 20+ years? I have no idea, but here it is. It's a Work In Progress, it's far from done but it's a decent start.
Get the latest on GitHub.
#!/bin/bash
######################################################################
######################################################################
## Author: Adam Michael Danischewski
## GitHub: https://github.com/AdamDanischewski/g2nasm
## Created Date: 2019-10-24
## Name: g2nasm.bsh
## Version: v0.01
## Last Modified: 2019-10-24
## Issues: If you find any issues emai1 me at <my first name> (dot)
## <my last name> (at) gmail (dot) com.
##
## Requirements: nasm, xxd, gnu awk, gnu sed
##
## This script takes gas asm generated by gcc and converts it to nasm.
## Eg. $> gcc -S -o code.gasm code.c
##
## You can then convert the code.gasm to nasm with this script:
## Eg. $> g2nasm.bsh code.gasm > code.nasm
##
## Then you can compile and run your nasm on Linux:
## Eg. $> nasm -f elf64 -o code.o code.nasm
## $> gcc -no-pie -o run_code code.o
## $> ./run_code
##
## As of this initial release it works for only a subset of gas asm - over
## time this will hopefully work on all of gas asm (except prbly macros).
##
## For now this should work on simple programs.
## Caveat: *** much is still missing/unmapped ***
## Get the lastest on GitHub: https://github.com/AdamDanischewski/g2nasm
## Pull requests invited.
##
## Tested on:
## #include <stdio.h>
##
## /* function to show bytes in memory, from location start to start+n*/
## void show_mem_rep(char *start, int n)
## {
## int i;
## for (i = 0; i < n; i++)
## printf(" %.2x", start[i]);
## printf("\n");
## }
##
## /*Main function to call above function for 0x01234567*/
## int main()
## {
## int i = 0x01234567;
## show_mem_rep((char *)&i, sizeof(i));
## getchar();
## return 0;
## }
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
##
## Released under Creative Commons License: CC BY-SA 4.0
## https://creativecommons.org/licenses/by-sa/4.0/
######################################################################
######################################################################
_=${BASH_ARGC} ### Cause BASH_ARGV to be populated, for options_handler.
declare FILE="${1}"
declare -a OPTIONS="" ## Used by: options_handler ()
declare WORKING_COPY=""
declare -a GLOBALS
declare GLOBAL_OFFSET_TABLE_FLAG=0
declare -r GLOBAL_OFFSET_TABLE="extern _GLOBAL_OFFSET_TABLE_"
declare -a RO_BLOCKS
declare RO_ALIGN=""
function usage() {
cat << EOF
Usage: ${0##*/} [-h] <file>
<file>: Gas asm file.
gcc -S -o code.gasm code.c ## file=code.gasm
OPTIONS:
-h|--help Usage
EOF
}
function main_clean() {
WORKING_COPY=$(sed -E "/.string/!{s/, /,/g;s/%//g;s/\\$//g;s/je/jz/};/[ \t]*.(file|text|type|cfi_|size|ident|section|intel_syntax)/d;s/(^[ \t]*)(sub|lea|add|cmp|xor)([ql])([ \t]*)([^,]*)(,)([ \t]*)(.*$)/\1\2\4\8, \5/;s/\b(pop|push|sub|lea)([lq])\b/\1/;/^.LF..:/d" "${FILE}")
GLOBALS[0]="$(sed -En 's/(^[ \t]*.globl)([ \t]*)([^ \t]*)(.*$)/global \3/p' <<< "${WORKING_COPY}")"
WORKING_COPY=$(sed '/^[ \t]*.globl/d' <<< "${WORKING_COPY}")
WORKING_COPY=$(sed -E '/\b[a-z]{3}q\b/s/(-[0-9]+)(\()([a-z]{3})(\))/qword [\3\1H]/' <<< "${WORKING_COPY}")
WORKING_COPY=$(sed -E '/\b[a-z]{3}l\b/s/(-[0-9]+)(\()([a-z]{3})(\))/dword [\3\1H]/' <<< "${WORKING_COPY}")
## Every offset left except lea: -12(rbp)--> dword [rbp-0CH]
WORKING_COPY=$(sed -E '/\blea\b/!s/(-[0-9]+)(\()([a-z]{3})(\))/dword [\3\1H]/' <<< "${WORKING_COPY}")
## lea mapping: -12(rbp)-->[rbp-0CH]
WORKING_COPY=$(sed -E '/\blea\b/s/(-[0-9]+)(\()([a-z]{3})(\))/[\3\1H]/' <<< "${WORKING_COPY}")
}
function load_externals() {
local call=""
local plt=""
local -i i=0
while IFS= read -r call; do
let i+=1
call=$(awk '{print $2}' <<< "${call}")
call="${call%@PLT}"
if ((! GLOBAL_OFFSET_TABLE_FLAG)); then
plt="${call##*@}"
[[ -n "${plt}" ]] && GLOBAL_OFFSET_TABLE_FLAG=1
fi
GLOBALS[${i}]="extern ${call}"
done < <(grep -P '^[ \t]*call' "${FILE}")
WORKING_COPY="$(sed 's/@PLT//g' <<< "${WORKING_COPY}")"
}
function num2hex() { printf "%02X\n" "${1}";}
function print_globals() {
local -i i=0
for((i=0;i<${#GLOBALS[@]};i++)){
printf "%11s\n" "${GLOBALS[${i}]}"
((i==0))&&echo
}
((GLOBAL_OFFSET_TABLE_FLAG)) && printf "${GLOBAL_OFFSET_TABLE}\n"
echo
}
function add_map() {
local -i line=0
local val=""
local hexval=""
## -8(rbp)-->[qd]word [rbp-8H]
}
function offset_to_hex() {
local -i line=0
local val=""
local hexval=""
while IFS= read -r line; do
val="$(sed -nE "${line}s/(^[^0-9]+)([0-9]+H)(.*$)/\2/p" <<< "${WORKING_COPY}")"
hexval=$(num2hex ${val%H})
WORKING_COPY=$(sed "${line} s/${val}/${hexval}H/" <<< "${WORKING_COPY}")
done < <(sed -nE '/^.*([dq]word|lea)[^0-9]*[0-9]+H.*$/=' <<< "${WORKING_COPY}")
}
function mov_map() {
local -i line=0
local val=""
local hexval=""
## -8(rbp)-->qword [rbp-8H]
WORKING_COPY=$(sed -E 's/(^[ \t]*)(mov)(sbl|zbl|slq|l|q)([ \t]*)([^,]*)(,)([ \t]*)(.*$)/\1\2\3\4\8, \5/' <<< "${WORKING_COPY}")
WORKING_COPY=$(sed -E '/mov[dlq]/s//mov/;s/movzbl/movzx/g;s/movsbl/movsx/g;s/movslq/movsxd/g' <<< "${WORKING_COPY}")
}
function rax_map() {
WORKING_COPY=$(sed 's/(rax)/byte [rax]/g' <<< "${WORKING_COPY}")
}
function leaq_map() {
## .LC0(rip)-->[rel ?_001]
## --------------------------------------------------------------------------->> ## Make sure it's padded to three zeroes.
WORKING_COPY="$(sed -E '/.LC[0-9]/s/(\.LC)([0-9]+)(\()([a-z]{3})(\))/[rel ?_\2]/;s/(\[rel \?_)([0-9])]/\100\2]/;s/(\[rel \?_)([0-9][0-9])]/\10\2]/' <<< "${WORKING_COPY}")"
## Increment the label number.
WORKING_COPY="$(awk '{if($0 ~ /\[rel \?_[0-9]{3}/){match($0,/([0-9]{3})/,arr);var=arr[1]+1;var=sprintf("%03d",var);gsub(/[0-9]{3}/,var, $0); print $0;}else print;}' <<< "${WORKING_COPY}")"
}
## String Arg 1 - String to convert
function convert_string_to_hex() {
xxd -ps -c1 <(echo -en "${1}\x0"|sed 's/"//g')|tr '\n' ' '|sed -r 's/.{24}/\U&\n/g;s/^[ \t]*//'|sed -r '${s/^.*$/& 00 00 00 00 00 00 00 00 00/;s/^(.{24})(.*$)/\1/;};s/ / /g;s/^.*$/\U&/'|
sed -r 's/^./db &/;s/[0-9A-F]{2}[ \t]*$/&H/;s/[0-9A-F]{2}/&H,/g;'| sed -r 's/,[ \t]*$//;s/^.*$/ &/;s/0AH[ \t]*$/00H/;s/[,H \t]*$/H/'
}
## Load Read Only Blocks
function get_ro_blocks() {
local block_start_addr=""
local block_end_addr=""
local block=""
local string=""
local ro_align=""
local -i ro_block_index=${#RO_BLOCKS[@]}
## get all read only block start addr's
while IFS= read -r block_start_addr; do
## Note: start at index 1 since that's what nasm starts it's ro block labels at
let ro_block_index+=1
## save all read only blocks
block="$(sed -En "${block_start_addr},/^[^ \t]/{/^[^ \t]/b;p}" <<< "${WORKING_COPY}")"
block_end_addr="$(($(sed -En "$((${block_start_addr}+1)),\${/^[\.a-z]/{=;q}}" <<< "${WORKING_COPY}")-1))"
WORKING_COPY="$(sed -E "${block_start_addr},${block_end_addr}s/^.*$/DELETE_THIS/" <<< "${WORKING_COPY}")"
ro_align=$(sed -rn 's/^([ \t]*.align )([0-9]+)(.*$)/align=\2/p' <<< "${block}")
[[ -n "${ro_align}" ]] && RO_ALIGN="${ro_align}" && block="$(sed -r "s/.align[ \t]*[0-9]+//"<<<"${block}")"
string=$(sed -rn 's/^([ \t]*\.string)([ \t]*)("[^"]*")(.*$)/\3/p' <<< "${block}")
if [[ -n "${string}" ]]; then
string="$(convert_string_to_hex "${string}" | tr '\n' '\001')"
block="$(sed -r "s/^[ \t]*\.string.*\$/${string}/;/^[ \t]*.(text|type|globl)/d" <<< "${block}"|tr '\001' '\n')"
fi
RO_BLOCKS[${ro_block_index}]="${block}"
done < <(sed -En '/^\.LC[0-9]+:.*$/=' <<< "${WORKING_COPY}")
WORKING_COPY="$(sed '/^DELETE_THIS/d' <<< "${WORKING_COPY}")"
}
function print_ro_blocks() {
local -i i=1
printf "SECTION .rodata %s\n\n" "${RO_ALIGN}"
for((i=1;i<=${#RO_BLOCKS[@]};i++)){
printf "?_%03.f:\n" ${i}
printf "%s\n" "${RO_BLOCKS[$i]}"
}
}
function fs_map() {
## fs:40-->qword [fs:abs 28H]
WORKING_COPY="$(sed -E '/\bfs:[0-9]+\b/s/\bfs:([0-9]+)\b/qword [fs:abs \1H]/' <<< "${WORKING_COPY}")"
}
function init() {
main_clean
load_externals
get_ro_blocks
mov_map
leaq_map
rax_map
fs_map
offset_to_hex ## Call this last.
}
function print_section_text() {
printf "SECTION .text\n\n"
}
function print_section_data() {
printf "SECTION .data\n\n"
}
function print_section_bss() {
printf "SECTION .bss\n\n"
}
function main() {
init
print_globals
print_section_text
printf "%s\n\n" "${WORKING_COPY}"
print_section_data
print_section_bss
print_ro_blocks
}
function options_handler() {
local -i i=0
local CURVAL=""
local NEXTVAL=""
((${#BASH_ARGV[@]}==0)) && usage && exit 0
for((i=$((${#BASH_ARGV[@]}-1));i>=0;i--)); do
CURVAL=${BASH_ARGV[${i}]}
NEXTVAL=${BASH_ARGV[$((${i}-1))]}
case "${CURVAL}" in
-h|-?|--help)
usage
exit 0
;;
*)
FILE="${CURVAL}"
[[ ! -e "${FILE}" ]] && printf "*** ERROR - File (\"${FILE}\") not found. \n" && exit 1
;;
esac
done
}
options_handler
main
exit 0
gd / df Wrapper - Optionally Prints Device/Mount/Size for any File/Dir
Simple df -h wrapper that will show the /dev/ or /mnt/ point of any file/dir. It is scriptable and trims trailing @'s for those who like to visualize their links. Get the latest on GitHub.
alias gd='_(){ local -i popts=0;[[ "${1}" =~ ^-[sS] ]]&&popts=1&&shift;[[ "${1}" =~ ^-[aA] ]]&&popts=2&&shift;[[ "${1}" =~ ^-[mM] ]]&&popts=3&&shift;local ref="${1%@}";if(($#<1))||[[ "${ref}" =~ ^- || ! -e "${ref}" ]];then echo "Usage: gd [[-s, print size] | [-a, print all] | [-m, print mount point]] <reference file/dir>, arg1=${1},arg2=${2}";[[ ! "${ref}" =~ ^- && ! -e "${ref}" && (($#>0))]]&&echo "*** gd::Error - File (\"${ref}\") not found.";return 1;fi;df -h "$(readlink -f "${ref}")"|awk -vpopts=${popts} "NR==1{header=\$0};NR>1{if(popts==1)print \$1,\$2;else if(popts==2){printf(\"%s\n%-16s%-6s%-5s%-6s%-5s%-20s\n\",header,\$1,\$2,\$3,\$4,\$5,\$6);}else if(popts==3)print \$6;else print \$1;}";};_'
Tuesday, October 22, 2019
pnasm64 - Migrate C Code to NASM
Nasm is decently structured assembly - if you ever are interested in harnessing the true power of a new chipset you'll probably need to write assembly at some point.
To run this you'll need nasm, gcc from the repos - and objconv from: https://www.agner.org/optimize/
And this will only work out-of-the-box on simple C programs, to add libraries you'll need to hack it up and make it your own. Get the latest on GitHub.
alias pnasm64='_(){ local sel="";local file="${1}"; (($#<1))||[[ "${1}" =~ ^- || ! -e "${file}" ]]&&echo "Usage: pnasm64 <your.c> [-t (compile and link)]"&&return 1;rm -f "${file%.c}.o" "${file%.c}.asm";echo "Decompiling into object code.";gcc -fno-asynchronous-unwind-tables -s -c "${file}" -o "${file%.c}.o";echo "Converting to nasm.";objconv -fnasm "${file%.c}.o"; sed -i -e "s/align=1//g" -e "s/[a-z]*execute//g" -e "s/: *function//g" -e "/default *rel/d" "${file%.c}.asm";[[ -n "${2}" && "${2}" =~ "-t" ]]&&echo "Compiling with nasm..."&&nasm -felf64 -o "${file%.c}2.o" "${file%.c}.asm"&&echo "Linking with gcc..."&&gcc -fno-pie -no-pie -o "${file%.c}" "${file%.c}2.o";};_'
And this will only work out-of-the-box on simple C programs, to add libraries you'll need to hack it up and make it your own. Get the latest on GitHub.
Sunday, October 20, 2019
Tuesday, October 15, 2019
writes - Print HD Writes
The following alias prints HD writes for a hard drive in TB.
Get the lastest on GitHub
alias writes='_(){ (($#<1))||[[ "${1}" =~ ^- ]]&&echo "Usage: writes <drive eg. /dev/sdb>"&&return 1;local drive="${1}";[[ ! -e "${drive}" ]]&&echo "Device (${drive}) not found."&&return 1;smrt=$(sudo smartctl -a "${drive}");grep -iEq "unsupported"<<<"${smrt}"&&echo "Error: Not a smart tools capable SSD."&&return 1;sector_sz=$(awk "/^Sector Size:/{gsub(/[^0-9]/,\"\",\$3);print \$3}" <<< "${smrt}");lbas=$(awk "/Total_LBAs_Written/{print \$10}" <<< "${smrt}");if [[ -n "${lbas}" ]];then writes=$(echo "scale=10;(${lbas}*${sector_sz})/1099511627776"|bc);else giga=$(awk "/Lifetime_Writes_GiB/{print \$10}" <<< "${smrt}");if [[ -n "${giga}" ]];then writes=$(echo "scale=10;(${giga}*1.073741824)/1000"|bc);else tlc32=$(awk "/TLC_Writes_32MiB/{print \$10}" <<< "${smrt}");[[ -z ${tlc32} ]]&&echo "Error - Could not find write data for drive ($drive)."&&return 1;writes=$(echo "scale=10;((${tlc32}*32*1.073741824)/1000)/1000"|bc);fi;fi;printf "Total writes for drive %s: %.2f TB\n" ${drive} ${writes};};_'
Tuesday, October 8, 2019
Terminal Color Analyzer - Prints True RGB Values for Terminal Colors
#!/bin/bash
######################################################################
######################################################################
## Author: Adam Michael Danischewski
## GitHub: https://github.com/AdamDanischewski/scriptsandoneliners
## Created Date: 2019-10-08
## Name: pscolors.bsh
## Version: v0.01
## Last Modified: 2019-10-08
## Issues: If you find any issues emai1 me at <my first name> (dot)
## <my last name> (at) gmail (dot) com.
##
## Requirements:xdotool/xdotool, xwininfo/x11-utils, tput/ncurses-bin,
## scrot/scrot, convert/imagemagick
## On Ubuntu:
## sudo apt-get install xdotool x11-utils scrot ncurses-bin imagemagick
##
## Prints the full xterm-256 ansi color mapping to RGB (decimal) and HEX
## in ANSI color (\x1b[38;5;<ansi>m) and Truecolor (\x1b[38;2;<R>;<G>;
## <B>m) and prints the rgb values of the colors that the terminal
## prints to the screen.
##
## How? First it prints all 256 ANSI colors for your terminal into a
## grid then it uses scrot to take a screenshot. It then steps over the
## image using imageMagick to pull the pixel color value for each cell.
##
## Why? Because there are alot of potential manipulators of color prior
## to colors landing on the actual screen. E.g. compton, shading, etc.
##
## With this tool you can get the end result rgb colors after all
## graphics processing is done when you are looking at your terminal.
##
## Without this tool, you would only know what you configured and what
## is advertised. This tool gives you the color actuals -- of course you
## can't really SEE the actual colors though I attempt to display them
## in TRUECOLOR. You can grab the RGB values and display them elsewhere
## (e.g. color tool in a web browser) to really see the nuances between
## what is advertised and what is experienced in your terminal.
##
## Note: If you have translucent windows, the background may affect the
## results - you should probably kill conky and run this on a blank
## workspace in a maximized terminal for best results.
##
## Look-up values gleened from:
## https://upload.wikimedia.org/wikipedia/commons/1/15/Xterm_256color_chart.svg
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
##
## Released under Creative Commons License: CC BY-SA 4.0
## https://creativecommons.org/licenses/by-sa/4.0/
######################################################################
######################################################################
## Global variables
declare SCREENSHOT_LOC=/tmp/__pscolorscrnshot_$RANDOM__.png
declare -i COLOR_SWATCH_IMG_COLS=60 ## Use a 60 term col wide image.
declare SHOW_COLOR_DELAY=.25
declare XWININFO="" ## Get the current window info via xwininfo.
declare X_COORD="" ## Absolute upper-left X
declare Y_COORD="" ## Absolute upper-left Y
declare REL_X="" ## Relative upper-left X
declare REL_Y="" ## Relative upper-left Y
function show_colors() {
local -i ANSI=0
tput clear
## Print the mysterious ANSI colors.
for ANSI in {0..256} ; do
echo -en "\\033[38;5;${ANSI}m█\\033[0m"
(($((${ANSI}+1))%${COLOR_SWATCH_IMG_COLS}==0)) && echo
done
echo
}
## Parse RGB hex tuples.
## <Arg 1> - Hex: Input hex value [[:xdigit]]{6}
## <Arg 2> - String: Tuple [r|g|b]
function get_rgbtuple() {
local hexrgb="${1}"
local tuple_flag="${2}"
local tuple_fmt="${3:-x}"
local tuple=""
case "${tuple_flag}" in
r|R)
tuple=${hexrgb:0:2}
;;
g|G)
tuple=${hexrgb:2:2}
;;
b|B)
tuple=${hexrgb:4:2}
;;
esac
echo $((0x${tuple}))
}
function get_rgb() {
local -i ansi=${1:-1}
local -a rgb=("000000" "800000" "008000" "808000" "000080" \
"800080" "008080" "c0c0c0" "808080" "ff0000" "00ff00" "ffff00" \
"0000ff" "ff00ff" "00ffff" "ffffff" "000000" "00005f" "000087" \
"0000af" "0000d7" "0000ff" "005f00" "005f5f" "005f87" "005faf" \
"005fd7" "005fff" "008700" "00875f" "008787" "0087af" "0087d7" \
"0087ff" "00af00" "00af5f" "00af87" "00afaf" "00afd7" "00afff" \
"00d700" "00d75f" "00d787" "00d7af" "00d7d7" "00d7ff" "00ff00" \
"00ff5f" "00ff87" "00ffaf" "00ffd7" "00ffff" "5f0000" "5f005f" \
"5f0087" "5f00af" "5f00d7" "5f00ff" "5f5f00" "5f5f5f" "5f5f87" \
"5f5faf" "5f5fd7" "5f5fff" "5f8700" "5f875f" "5f8787" "5f87af" \
"5f87d7" "5f87ff" "5faf00" "5faf5f" "5faf87" "5fafaf" "5fafd7" \
"5fafff" "5fd700" "5fd75f" "5fd787" "5fd7af" "5fd7d7" "5fd7ff" \
"5fff00" "5fff5f" "5fff87" "5fffaf" "5fffd7" "5fffff" "870000" \
"87005f" "870087" "8700af" "8700d7" "8700ff" "875f00" "875f5f" \
"875f87" "875faf" "875fd7" "875fff" "878700" "87875f" "878787" \
"8787af" "8787d7" "8787ff" "87af00" "87af5f" "87af87" "87afaf" \
"87afd7" "87afff" "87d700" "87d75f" "87d787" "87d7af" "87d7d7" \
"87d7ff" "87ff00" "87ff5f" "87ff87" "87ffaf" "87ffd7" "87ffff" \
"af0000" "af005f" "af0087" "af00af" "af00d7" "af00ff" "af5f00" \
"af5f5f" "af5f87" "af5faf" "af5fd7" "af5fff" "af8700" "af875f" \
"af8787" "af87af" "af87d7" "af87ff" "afaf00" "afaf5f" "afaf87" \
"afafaf" "afafd7" "afafff" "afd700" "afd75f" "afd787" "afd7af" \
"afd7d7" "afd7ff" "afff00" "afff5f" "afff87" "afffaf" "afffd7" \
"afffff" "d70000" "d7005f" "d70087" "d700af" "d700d7" "d700ff" \
"d75f00" "d75f5f" "d75f87" "d75faf" "d75fd7" "d75fff" "d78700" \
"d7875f" "d78787" "d787af" "d787d7" "d787ff" "dfaf00" "dfaf5f" \
"dfaf87" "dfafaf" "dfafdf" "dfafff" "dfdf00" "dfdf5f" "dfdf87" \
"dfdfaf" "dfdfdf" "dfdfff" "dfff00" "dfff5f" "dfff87" "dfffaf" \
"dfffdf" "dfffff" "ff0000" "ff005f" "ff0087" "ff00af" "ff00df" \
"ff00ff" "ff5f00" "ff5f5f" "ff5f87" "ff5faf" "ff5fdf" "ff5fff" \
"ff8700" "ff875f" "ff8787" "ff87af" "ff87df" "ff87ff" "ffaf00" \
"ffaf5f" "ffaf87" "ffafaf" "ffafdf" "ffafff" "ffdf00" "ffdf5f" \
"ffdf87" "ffdfaf" "ffdfdf" "ffdfff" "ffff00" "ffff5f" "ffff87" \
"ffffaf" "ffffdf" "ffffff" "080808" "121212" "1c1c1c" "262626" \
"303030" "3a3a3a" "444444" "4e4e4e" "585858" "626262" "6c6c6c" \
"767676" "808080" "8a8a8a" "949494" "9e9e9e" "a8a8a8" "b2b2b2" \
"bcbcbc" "c6c6c6" "d0d0d0" "dadada" "e4e4e4" "eeeeee")
if ((ansi<=256)); then
printf "%s\n" "${rgb[${ansi}]}"
return 0
else
return 1
fi
}
function print_coords(){
local -i i=0
for((i=0;i<256;i++)){
echo "IMG_TRU_XCOORD: ${IMG_TRU_XCOORD}, IMG_TRU_YCOORD: ${IMG_TRU_YCOORD}, IMG_XCOORD: ${IMG_XCOORD}, IMG_YCOORD: ${IMG_YCOORD}"
get_next_x_coord
}
}
function get_next_x_coord(){
IMG_TRU_XCOORD=$(echo "scale=10;${IMG_TRU_XCOORD}+${CHAR_WIDTH}"|bc)
if awk "BEGIN{exit !(${IMG_TRU_XCOORD}>(${COLOR_SWATCH_IMG_COLS}*${CHAR_WIDTH}))}"; then
IMG_TRU_XCOORD=$(echo "scale=10;${CHAR_WIDTH}*.5"|bc)
get_next_y_coord
fi
IMG_XCOORD=$(awk -vtx=${IMG_TRU_XCOORD} 'BEGIN{printf("%1.f\n",tx)}')
}
function get_next_y_coord(){
IMG_TRU_YCOORD=$(echo "scale=10;${IMG_TRU_YCOORD}+${CHAR_HEIGHT}"|bc)
IMG_YCOORD=$(awk -vty=${IMG_TRU_YCOORD} 'BEGIN{printf("%1.f\n",ty)}')
}
function print_rgb(){
local -i ANSI=0
local -i r=0
local -i g=0
local -i b=0
local p_r=""
local p_g=""
local p_b=""
local p_ANSI=""
local ACTUAL_RGB=""
local xrgb_R=""
local xrgb_G=""
local xrgb_B=""
local xprgb_R=""
local xprgb_G=""
local xprgb_B=""
local xhex=""
tput reset
for((ANSI=0;ANSI<256;ANSI++)){
xhex=$(get_rgb "${ANSI}")
xrgb_R=$(get_rgbtuple "${xhex}" "r")
xrgb_G=$(get_rgbtuple "${xhex}" "g")
xrgb_B=$(get_rgbtuple "${xhex}" "b")
xprgb_R=$(printf "%3s" "${xrgb_R}")
xprgb_G=$(printf "%3s" "${xrgb_G}")
xprgb_B=$(printf "%3s" "${xrgb_B}")
read -r -d=' ' r g b < <(convert "${SCREENSHOT_LOC}" -format "%[fx:int(255*p{${IMG_XCOORD},${IMG_YCOORD}}.r)] %[fx:int(255*p{${IMG_XCOORD},${IMG_YCOORD}}.g)] %[fx:int(255*p{${IMG_XCOORD},${IMG_YCOORD}}.b)]" info:-)
p_r=$(printf "%3s" "${r}")
p_g=$(printf "%3s" "${g}")
p_b=$(printf "%3s" "${b}")
p_ANSI=$(printf "%3s" "${ANSI}")
printf "\\033[38;5;${ANSI}m████ ANSI ${p_ANSI}\\033[0m|\\033[38;5;${ANSI}m%s%s\\033[0m|\x1b[38;2;${xrgb_R};${xrgb_G};${xrgb_B}mxterm-256color - RGB/TRUECOLOR - RGB:%s,%s,%s\\033[0m%s \\033[38;2;${r};${g};${b}mActual terminal RGB: %s ████\\033[0m\n" "HEX:0x" "${xhex}" "${xprgb_R}" "${xprgb_G}" "${xprgb_B}" " |" "srgb(${p_r},${p_g},${p_b})"
get_next_x_coord
}
}
function init() {
## Get xwindow info
XWININFO=$(xwininfo -id $(xdotool getactivewindow))
## Parse xwininfo data:
X_COORD=$(sed -nE 's/(^.*Absolute upper-left X:)( *)([0-9]+)/\3/p' <<< "${XWININFO}")
Y_COORD=$(sed -nE 's/(^.*Absolute upper-left Y:)( *)([0-9]+)/\3/p' <<< "${XWININFO}")
REL_X=$(sed -nE 's/(^.*Relative upper-left X:)( *)([0-9]+)/\3/p' <<< "${XWININFO}")
REL_Y=$(sed -nE 's/(^.*Relative upper-left Y:)( *)([0-9]+)/\3/p' <<< "${XWININFO}")
SCRN_WIDTH=$(sed -nE 's/(^.*Width:)( *)([0-9]+)/\3/p' <<< "${XWININFO}")
SCRN_HEIGHT=$(sed -nE 's/(^.*Height:)( *)([0-9]+)/\3/p' <<< "${XWININFO}")
## Get terminal sizing
SCRN_ROWS=$(tput lines)
SCRN_COLS=$(tput cols)
CHAR_WIDTH=$(echo "scale=10;${SCRN_WIDTH}/${SCRN_COLS}"|bc)
CHAR_HEIGHT=$(echo "scale=10;${SCRN_HEIGHT}/${SCRN_ROWS}"|bc)
## IMG_TRU_XCOORD starts at half the terminal char width. Thereafter
## we will move by a full character width rounded to the nearest
## pixel. IMG_TRU_XCOORD will keep the accurate unrounded values and
## the IMG_XCOORD is the rounded value needed for imageMagick.
IMG_TRU_XCOORD=$(echo "scale=10; ${CHAR_WIDTH}*.5"|bc)
IMG_XCOORD=$(awk -vtx=${IMG_TRU_XCOORD} 'BEGIN{printf("%1.f\n",tx)}')
## IMG_TRU_YCOORD starts at half the terminal char height. Thereafter
## we will move down by a full char height after COLOR_SWATCH_IMG_COLS
## columns have been calculated.
IMG_TRU_YCOORD=$(echo "scale=10; ${CHAR_HEIGHT}*.5"|bc)
IMG_YCOORD=$(awk -vty=${IMG_TRU_YCOORD} 'BEGIN{printf("%1.f\n",ty)}')
## Screenshot coords
## Add the relative offset to absolute coord to get the true coords.
let X_COORD+=${REL_X} ## Screenshot X Coord
let Y_COORD+=${REL_Y} ## Screenshot Y Coord
## Screenshot size
IMG_WIDTH=$(awk -viw=$(echo "scale=10;${COLOR_SWATCH_IMG_COLS}*${CHAR_WIDTH}"|bc) 'BEGIN{printf("%1.f\n",iw)}')
IMG_HEIGHT=$(awk -vih=$(echo "scale=10;5*${CHAR_HEIGHT}"|bc) 'BEGIN{printf("%1.f\n",ih)}')
}
function main(){
init
tput smcup ## Save screen.
rm -f "${SCREENSHOT_LOC}"
show_colors
sleep ${SHOW_COLOR_DELAY}
## Take screenshot w/location and image dimensions.
scrot "${SCREENSHOT_LOC}" -a${X_COORD},${Y_COORD},${IMG_WIDTH},${IMG_HEIGHT}
tput rmcup ## Restore screen.
print_rgb
rm -f "${SCREENSHOT_LOC}"
}
main
exit 0
Subscribe to:
Posts (Atom)