You are not logged in.

#3251 2019-05-19 05:24:33

pellertson
Member
Registered: 2018-03-16
Posts: 5

Re: Post your handy self made command line utilities

I'm a bit of an odd duck and I use Rob Pike's acme as my text editor/general programming environment.  Recently, I wrote an RSS feed for it by converting all the RSS feeds to JSON feeds and using the following to display a summary of my subscriptions:

#!/bin/sh
# RSS/Atom/JSON Feed reader for acme
# This code is in the public domain
for url in $(cat $URLS)
do
	temp=$(mktemp)
	curl -s $url > $temp
	jq -r '.title' $temp
	echo
	jq -r ' .items | .[] | [.title, .url] | join("\t") ' $temp | head -n 5
	echo
	echo =====
	echo
	rm $temp
done | 9p write acme/new/body

writetoacme JSON-Feeds

"writetoacme" is also a script I wrote to help with writing acme screens.

#!/bin/sh
# Shortcut for common writing acme applications
# USAGE: writetoacme $1
# $1: name of window

last=$(9p ls acme | sort -g | tail -n 1)
echo "name $1" | 9p write acme/$last/ctl
echo -n "clean" | 9p write acme/$last/ctl
echo -n "0,0" | 9p write acme/$last/addr
echo -n "dot=addr" | 9p write acme/$last/ctl
echo -n "show" | 9p write acme/$last/ctl

EDIT: before anyone asks, I simply use a web-service called feed2json to do all the converting for me.  I'll probably write my own program to do that later on.  But this works for now.

Last edited by pellertson (2019-05-19 05:31:47)

Offline

#3252 2019-05-19 12:21:07

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,330
Website

Re: Post your handy self made command line utilities

for url in $(cat $URLS)
do
# ...
done

Save the cats!

while read url
do
# ...
done < $URLS

You also may be interested in python's feedparser which would drastically simplify the whole process.

Last edited by Trilby (2019-05-19 12:21:35)


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#3253 2019-05-19 18:37:20

escondida
Package Maintainer (PM)
Registered: 2008-04-03
Posts: 157

Re: Post your handy self made command line utilities

Props for the acme rss script, pellertson! You've inspired me to finish putting together my own version (sans the Web service), something I've been meaning to do for a while.

Offline

#3254 2019-05-20 01:01:14

pellertson
Member
Registered: 2018-03-16
Posts: 5

Re: Post your handy self made command line utilities

Trilby wrote:

You also may be interested in python's feedparser which would drastically simplify the whole process.

That could be useful, but I've found through experience that shell scripts are truly the best way to write to acme screens.  As readable as python is, I cannot go without pipes.  Plus I wanted to learn how to use "jq".  But thanks for the tip on removing cat!

Offline

#3255 2019-05-21 18:36:26

pellertson
Member
Registered: 2018-03-16
Posts: 5

Re: Post your handy self made command line utilities

escondida wrote:

Props for the acme rss script, pellertson! You've inspired me to finish putting together my own version (sans the Web service), something I've been meaning to do for a while.

Thanks!  Can I see your version?

Offline

#3256 2019-06-05 00:39:02

Alad
Wiki Admin/IRC Op
From: Bagelstan
Registered: 2014-05-04
Posts: 2,418
Website

Re: Post your handy self made command line utilities

I was looking to watch websites for changes, but all I found was a paid service. So I decided to host my own solution.

The script is run from cron, and supports three methods of comparison:

1. direct HTML comparison (using curl). This may result in false positives, especially with javascript-heavy sites.
2. text rendering (using w3m). This does not necessarily render all content (again, javascript).
3. full rendering (using cutycapt/qtwebengine). Heavy-handed but reliable approach for most websites. An image overlay is sent as email attachment.

#!/bin/bash
# requires: diff mail file nice imagemagick curl w3m cutycapt xvfb-run
argv0=webwatcher
XDG_CACHE_HOME=${XDG_CACHE_HOME:-$HOME/.cache}

# default arguments
destination=your@face.com
mode=exact

while getopts :d:m: opt; do
    case $opt in
	d) destination=$OPTARG
	   ;;
	m) mode=$OPTARG
	   ;;
	*) echo "usage: ${0##*/} [+-mi} [--] ARGS..."
	   exit 2
    esac
done
shift $(( OPTIND - 1 ))
OPTIND=1

if [[ ! $1 ]]; then
    printf >&2 '%s\n' "$argv0: error: website not specified"
    exit 2
fi

uri=$1
uri_id=$(sha256sum <<< "$1" | cut -d' ' -f1)

case $mode in
    exact)
        tmp_extension=.htm
	# "small changes", may have false positives	
	ww_fetch() { curl -fsS "$1" --output "$2"; }
	;;
    text)
	tmp_extension=.txt
	# text-browser mode, may not render all contents
	ww_fetch() { w3m -dump "$1" > "$2"; }
	;;
    image)
	tmp_extension=.png
	# browser mode, will render full page
	# xvfb-run -a is used to allow multiple processes
	ww_fetch() { nice -n 19 xvfb-run -a --server-args "-screen 0, 1024x768x24" \
			  cutycapt --url="$1" --out="$2"; }
	;;
esac

# xdg base directory
known=$XDG_CACHE_HOME/$argv0/$uri_id$tmp_extension
mkdir -p "$XDG_CACHE_HOME/$argv0"

if [[ -s $known ]]; then
    tmp=$(mktemp --suffix "$tmp_extension")
    ww_fetch "$uri" "$tmp"

    case $mode in
	exact|text)
	    if ! diff -q "$known" "$tmp" >/dev/null; then
		diff -u "$known" "$tmp" | mail -s "$argv0: changes for $1" "$destination"
		mv "$tmp" "$known"
	    else
		rm "$tmp"
	    fi ;;
	image)
	    # when comparing screenshots, metadata has to be taken into account. See:
	    # http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.Anc-text (PNG meta-data)
	    # http://www.imagemagick.org/Usage/compare/ ("IM Image Signatures", imagemagick)
	    image_signatures=()
	    while read -r sig; do
		image_signatures+=("$REPLY")
	    done < <(identify -quiet -format '%#\n' "$tmp" "$known")

	    if [[ ${image_signatures[0]} != "${image_signatures[1]}" ]]; then
		compare "$tmp" "$known" -compose src diff.png
		mail -s "$argv0: changes for $1" "$destination" -A diff.png
		mv "$tmp" "$known"
	    else
		rm "$tmp"
	    fi ;;
    esac
else
    printf >&2 '%s\n' "$argv0: retrieving website for the first time"
    ww_fetch "$uri" "$known"
fi

Last edited by Alad (2019-06-05 00:39:41)


Mods are just community members who have the occasionally necessary option to move threads around and edit posts. -- Trilby

Offline

#3257 2019-06-05 01:41:29

bulletmark
Member
From: Brisbane, Australia
Registered: 2013-10-22
Posts: 675

Re: Post your handy self made command line utilities

Reading Alad's post above and seeing how he uses email for his notification system from his script has prompted me to recommend pushover.net which I have been using for a few years. E.g I have a personal script "notify-phone <message>" which I can call from scripts like the above (PS, I long ago wrote a similar "site-monitor" script myself). Pushover sends notifications direct to your phone, is extremely fast and reliable, and can be configured with different messages and priorities, i.e. with/without sound/pop up etc. You can create groups, so e.g my wife and I are in a "home alarm" group so our phones get instantly notified by my home alarm system (running on a Raspberry Pi using Arch ARM of course). That one is a high priority notification with a distinct sound and popup, which we must instantly deal with.

I normally avoid recommending any paid service but pushover only costs a single one-off "cup of coffee" for lifetime use of the client app. So it is a cheap, easy, and modern but reliable way to add phone notifications to your scripts and programs.

Offline

#3258 2019-06-05 07:00:30

boban_dj
Member
Registered: 2015-03-17
Posts: 150

Re: Post your handy self made command line utilities

@Alad,
CutyCapt is executable name instead cutycapt, found in AUR: https://aur.archlinux.org/packages/cutycapt-qt5-git/
also the website url argument must be full eg: https://example.com

thanks for the script!

Offline

#3259 2019-06-25 04:45:29

Docbroke
Member
From: India
Registered: 2015-06-13
Posts: 1,438

Re: Post your handy self made command line utilities

At the end of my .bash_profile

clear
wm() {
echo ""
echo ""
echo "                                        MY DISPLAY MANAGER"
echo ""
echo ""
echo "Choose your window manager (defaults to i3)?"
echo "s) sway i) i3 k) kodi c) back to console or type command name (e.g., firefox)"
echo ""
echo "You can run this script again with command 'wm'"
echo ""
echo "Make your choice.:"
read wm
case $wm in
    s|sway) sway ;;
    i|i3) sx /usr/bin/i3 ;;
    k|kodi) sx /usr/bin/kodi ;;
    c) ;;
    *) [ $wm ] && sx /usr/bin/$wm || sx /usr/bin/i3 ;;
esac
}
wm

Offline

#3260 2019-06-29 20:27:18

ugjka
Member
From: Latvia
Registered: 2014-04-01
Posts: 1,863
Website

Re: Post your handy self made command line utilities

A little go script to play my favourite radio stations resiliently without buffer latency (uses MPV for playback)

package main

import (
	"flag"
	"fmt"
	"io"
	"log"
	"net"
	"net/http"
	"os"
	"os/exec"
	"time"
)

func main() {
	noskip := flag.Bool("noskip", false, "do not skip buffer")
	flag.Usage = func() {
		fmt.Println("help:")
		fmt.Println("\tavailable stations")
		fmt.Println("\t\t1, 2, 5, swh, heart")
		fmt.Println("\t-noskip")
		fmt.Println("\t\tdisables buffer skiping")
		os.Exit(0)
	}
	flag.Parse()

	stations := map[string]struct {
		stream  string
		buffer  int
		bitrate int
		codec   string
	}{
		//Latvijas Radio 1,2,5
		"1": {"http://lr1mp1.latvijasradio.lv:8010/", 15, 128, "aac"},
		"2": {"http://lr2mp1.latvijasradio.lv:8000/", 15, 128, "aac"},
		"5": {"http://live.pieci.lv/live19-hq.mp3", 3, 128, "mp3"},
		//Radio SWH
		"swh": {"http://87.110.219.34:8000/swhaac", 3, 128, "aac"},
		//Heart London
		"heart": {"http://media-ice.musicradio.com/HeartLondonMP3", 12, 128, "mp3"},
	}

	args := flag.Args()
	// If no args, play LR2
	station := stations["2"]
	if len(args) > 0 {
		if v, ok := stations[args[0]]; ok {
			station = v
		}
	}

	//Custom transport for IceCast protocol
	tr := &http.Transport{
		Dial: func(network, a string) (net.Conn, error) {
			realConn, err := net.Dial(network, a)
			if err != nil {
				return nil, err
			}
			hijack := &IcyConnWrapper{
				deadline: time.Second * 5,
				Conn:     realConn,
			}
			if *noskip {
				hijack.deadline = time.Second * 15
			}
			return hijack, nil
		},
	}
	client := &http.Client{
		Transport: tr,
		Timeout:   time.Hour * 6,
	}
	http.DefaultClient = client

	for {
		stream, err := http.Get(station.stream)
		if err != nil {
			log.Println("GET:", err)
			time.Sleep(time.Second * 5)
			continue
		}
		pipe, err := getPipe(station.codec)
		if err != nil {
			log.Println("GETPIPE:", err)
			time.Sleep(time.Second * 5)
			continue
		}
		//Skip the buffer for more realtime playback
		if !*noskip {
			err := skipBytes(stream.Body, station.bitrate/8*1024*station.buffer)
			if err != nil {
				log.Println("SKIP BYTES:", err)
				stream.Body.Close()
				pipe.Close()
				time.Sleep(time.Second * 5)
				continue
			}
		}
		//Fetch only half a second at a time
		buf := make([]byte, station.bitrate/8*1024/2)
		_, err = io.CopyBuffer(pipe, stream.Body, buf)
		if err != nil {
			log.Println("COPY BUFFER:", err)
			stream.Body.Close()
			pipe.Close()
			time.Sleep(time.Second * 5)
		}
	}
}

//IcyConnWrapper makes IceCast to work with net/http package
type IcyConnWrapper struct {
	net.Conn
	haveReadAny bool
	deadline    time.Duration
}

func (i *IcyConnWrapper) Read(b []byte) (int, error) {
	i.Conn.SetReadDeadline(time.Now().Add(i.deadline))
	if i.haveReadAny {
		return i.Conn.Read(b)
	}
	i.haveReadAny = true
	//bounds checking ommitted. There are a few ways this can go wrong.
	//always check array sizes and returned n.
	n, err := i.Conn.Read(b[:3])
	if err != nil {
		return n, err
	}
	if string(b[:3]) == "ICY" {
		//write Correct http response into buffer
		copy(b, []byte("HTTP/1.1"))
		return 8, nil
	}
	return n, nil
}

func skipBytes(i io.Reader, target int) error {
	buf := make([]byte, 128)
	total := 0
	for {
		n, err := i.Read(buf)
		if err != nil {
			return err
		}
		total += n
		if total > target {
			return nil
		}
	}
}

func getPipe(codec string) (pipe io.WriteCloser, err error) {
	cmd := exec.Command("mpv", "-", "--profile=low-latency", "--quiet",
		"--cache=no", "--demuxer-lavf-buffersize=512",
		"--demuxer-lavf-format="+codec, "--demuxer=+lavf")

	pipe, err = cmd.StdinPipe()
	if err != nil {
		return
	}

	statusOut, err := cmd.StdoutPipe()
	if err != nil {
		return
	}
	statusErr, err := cmd.StderrPipe()
	if err != nil {
		return
	}

	go func(src io.ReadCloser) {
		io.Copy(os.Stdout, src)
	}(statusOut)

	go func(src io.ReadCloser) {
		io.Copy(os.Stderr, src)
	}(statusErr)

	err = cmd.Start()
	if err != nil {
		return
	}
	go func(c *exec.Cmd) {
		c.Wait()
		log.Println("REALEASING MPV")
	}(cmd)
	return
}

Last edited by ugjka (2019-07-05 22:30:47)


https://ugjka.net
paru > yay | vesktop > discord
pacman -S spotify-launcher
mount /dev/disk/by-...

Offline

#3261 2019-06-29 21:22:19

N_BaH
Member
Registered: 2015-12-30
Posts: 84

Re: Post your handy self made command line utilities

no shebang ?
is the kernel able to read your mind ?
wink

Offline

#3262 2019-06-29 21:28:45

ugjka
Member
From: Latvia
Registered: 2014-04-01
Posts: 1,863
Website

Re: Post your handy self made command line utilities

N_BaH wrote:

no shebang ?
is the kernel able to read your mind ?
wink

Go compiles to a statically linked binary executable

Last edited by ugjka (2019-06-29 21:29:18)


https://ugjka.net
paru > yay | vesktop > discord
pacman -S spotify-launcher
mount /dev/disk/by-...

Offline

#3263 2019-06-30 05:24:33

N_BaH
Member
Registered: 2015-12-30
Posts: 84

Re: Post your handy self made command line utilities

ah, go !
you should have given a link (where) to go.

Offline

#3264 2019-06-30 10:57:14

quequotion
Member
From: Oita, Japan
Registered: 2013-07-29
Posts: 814
Website

Re: Post your handy self made command line utilities

I emulated the rotate cube "screensaver" functionality compiz (0.9.x) lost many cycles ago, with xdotool and xprintidle:

#!/bin/bash

#Control this Xorg display
DISPLAY=:0.0

#Disable any input device other than XTEST and pointer
#pointer=12
#for i in $(xinput list --id-only); do \
#  [[ "$i" -gt "5" ]] && [[ "$i" -ne "$pointer" ]] && \
#    enabled="$(xinput list-props $i | grep "Device Enabled")" && \
#    [[ "${enabled: -1}" -eq "1" ]] && \
#      xinput disable "$i" && \
#      disabled+=("$i"); \
#done

#Pixels to move mouse (rotates cube)
step=1

#Start rotation left or right at random
direction=$RANDOM; let "direction >>= 14"
[[ "$direction" -eq 1 ]] && direction=90 || direction=270

#Compiz rotate plugin's "initiate" button
xdotool mousedown 9 &

#Rotate Cube
while [ $(xprintidle) -gt 0 ]; do
  xdotool mousemove_relative --polar "$direction" "$step" &
  #Approximately 60fps
  sleep 0.0165
done

#Compiz rotate plugin's "initiate" button
xdotool mouseup 9 &

#Enable any disabled input devices
#for i in "${disabled[@]}"; do \
#      xinput enable "$i" & \
#done

UPDATE: Added xinput to disable devices while screensaver is active; one pointer needs to be excepted (your usual mouse) to break out of the screensaver. Not sure of a way to correlate the pointer device one uses most to a specific xinput number, so commented out (find this number by name or trial and error with xinput {list,disable n,enable n}).

Last edited by quequotion (2020-01-12 14:40:47)

Offline

#3265 2019-06-30 15:17:34

ugjka
Member
From: Latvia
Registered: 2014-04-01
Posts: 1,863
Website

Re: Post your handy self made command line utilities

N_BaH wrote:

ah, go !
you should have given a link (where) to go.

There is a way to execute it as a script though: https://blog.cloudflare.com/using-go-as … -in-linux/


https://ugjka.net
paru > yay | vesktop > discord
pacman -S spotify-launcher
mount /dev/disk/by-...

Offline

#3266 2019-07-09 18:04:40

kokoko3k
Member
Registered: 2008-11-14
Posts: 2,421

Re: Post your handy self made command line utilities

Vpn via ssh with routed traffic, it could be done a lot better, and seems to require superuser rights on the local and remote side ; of course key authentication is needed, but it is still definitely nice:

TUNIP_L=192.168.244.2 #local vpn ip
TUNIP_R=192.168.244.1 #remote vpn ip
DEF_GW=192.168.15.1  #default local gateway
SSHD=<remote ip> #remote ssh server
SSHDP=22 #remote ssh server port

sh -c "sleep 5 ; \
        route add -net 0.0.0.0 netmask 0.0.0.0 gw $TUNIP_R ; \
        route add $SSHD gw $DEF_GW ; \
        echo routed" &

ssh \
  -o PermitLocalCommand=yes \
  -o LocalCommand="sudo ifconfig tun5 $TUNIP_L pointopoint $TUNIP_R netmask 255.255.255.0" \
  -o ServerAliveInterval=60 \
  -w 5:5 root@$SSHD -p $SSHDP  \
  "sudo ifconfig tun5 $TUNIP_R pointopoint $TUNIP_R netmask 255.255.255.0;   echo tun ready"

route del -net 0.0.0.0 netmask 0.0.0.0 gw $TUNIP_R ; route del $SSHD gw $DEF_GW
echo unrouted

on the ssh server (it could be done even in the previous command):

iptables -t nat -A POSTROUTING -s 192.0.0.0/24 -o etha0a9 -j MASQUERADE

Do i really need openvpn?

Last edited by kokoko3k (2019-07-09 18:07:01)


Help me to improve ssh-rdp !
Retroarch User? Try my koko-aio shader !

Offline

#3267 2019-07-10 11:06:05

Awebb
Member
Registered: 2010-05-06
Posts: 6,610

Re: Post your handy self made command line utilities

N_BaH wrote:

ah, go !
you should have given a link (where) to go.

He said it's a go script. Dunno what else you'd need to know.

Offline

#3268 2019-08-07 04:53:51

waitnsea
Member
From: France
Registered: 2013-02-10
Posts: 59

Re: Post your handy self made command line utilities

Added help function on zshbuiltins in ~/.zsh_functions:

## zshbuiltins help by paragraph
helpz()
{
    [[ -z $* ]] && echo "give argument among these :  "  &&
    ls /usr/share/zsh/*/help/  || less /usr/share/zsh/*/help/$* 
}

without argument gives list and with one shows help, more readable than man zshbuiltins

Last edited by waitnsea (2019-08-09 04:52:30)

Offline

#3269 2019-08-10 09:36:19

sadboi389
Member
Registered: 2018-03-31
Posts: 33

Re: Post your handy self made command line utilities

??? ⏹??? ?????? ?⏹? ???? ???? ????: ?????? ?⏹?? ??????? ?⏹ ????⏹? ??⏹???!

("The only script you will ever need: Change your letters to random emojis!") - I'm not sure if this forum will display the emojis though.. Here's a screenshot:

Screenshot-from-2019-08-10-11-31-04.png

#!/bin/bash
declare -a keycodes=("24" "25" "26" "27" "28" "29" "30" "31" "32" "33" "34" "38" "39" "40" "41" "42" "43" "44" "45" "46" "47" "48" "52" "53" "54" "55" "56" "57" "58")
declare -a emojis=("3299" "1F004" "1F0CF" "1F170" "1F171" "1F17E" "1F17F" "1F18E" "1F191" "1F192" "1F193" "1F194" "1F195" "1F196" "1F197" "1F198" "1F199" "1F19A" "1F1E6" "1F1E7" "1F1E8" "1F1E9" "1F1EA" "1F1EB" "1F1EC" "1F1ED" "1F1EE" "1F1EF" "1F1F0" "1F1F1" "1F1F2" "1F1F3" "1F1F4" "1F1F5" "1F1F6" "1F1F7" "1F1F8" "1F1F9" "1F1FA" "1F1FB" "1F1FC" "1F1FD" "1F1FE" "1F1FF" "1F201" "1F202" "1F21A" "1F22F" "1F232" "1F233" "1F234" "1F235" "1F236" "1F237" "1F238" "1F239" "1F23A" "1F250" "1F251" "1F300" "1F301" "1F302" "1F303" "1F304" "1F305" "1F306" "1F307" "1F308" "1F309" "1F30A" "1F30B" "1F30C" "1F30D" "1F30E" "1F30F" "1F310" "1F311" "1F312" "1F313" "1F314" "1F315" "1F316" "1F317" "1F318" "1F319" "1F31A" "1F31B" "1F31C" "1F31D" "1F31E" "1F31F" "1F320" "1F321" "1F324" "1F325" "1F326" "1F327" "1F328" "1F329" "1F32A" "1F32B" "1F32C" "1F32D" "1F32E" "1F32F" "1F330" "1F331" "1F332" "1F333" "1F334" "1F335" "1F336" "1F337" "1F338" "1F339" "1F33A" "1F33B" "1F33C" "1F33D" "1F33E" "1F33F" "1F340" "1F341" "1F342" "1F343" "1F344" "1F345" "1F346" "1F347" "1F348" "1F349" "1F34A" "1F34B" "1F34C" "1F34D" "1F34E" "1F34F" "1F350" "1F351" "1F352" "1F353" "1F354" "1F355" "1F356" "1F357" "1F358" "1F359" "1F35A" "1F35B" "1F35C" "1F35D" "1F35E" "1F35F" "1F360" "1F361" "1F362" "1F363" "1F364" "1F365" "1F366" "1F367" "1F368" "1F369" "1F36A" "1F36B" "1F36C" "1F36D" "1F36E" "1F36F" "1F370" "1F371" "1F372" "1F373" "1F374" "1F375" "1F376" "1F377" "1F378" "1F379" "1F37A" "1F37B" "1F37C" "1F37D" "1F37E" "1F37F" "1F380" "1F381" "1F382" "1F383" "1F384" "1F385" "1F386" "1F387" "1F388" "1F389" "1F38A" "1F38B" "1F38C" "1F38D" "1F38E" "1F38F" "1F390" "1F391" "1F392" "1F393" "1F396" "1F397" "1F399" "1F39A" "1F39B" "1F39E" "1F39F" "1F3A0" "1F3A1" "1F3A2" "1F3A3" "1F3A4" "1F3A5" "1F3A6" "1F3A7" "1F3A8" "1F3A9" "1F3AA" "1F3AB" "1F3AC" "1F3AD" "1F3AE" "1F3AF" "1F3B0" "1F3B1" "1F3B2" "1F3B3" "1F3B4" "1F3B5" "1F3B6" "1F3B7" "1F3B8" "1F3B9" "1F3BA" "1F3BB" "1F3BC" "1F3BD" "1F3BE" "1F3BF" "1F3C0" "1F3C1" "1F3C2" "1F3C3" "1F3C4" "1F3C5" "1F3C6" "1F3C7" "1F3C8" "1F3C9" "1F3CA" "1F3CB" "1F3CC" "1F3CD" "1F3CE" "1F3CF" "1F3D0" "1F3D1" "1F3D2" "1F3D3" "1F3D4" "1F3D5" "1F3D6" "1F3D7" "1F3D8" "1F3D9" "1F3DA" "1F3DB" "1F3DC" "1F3DD" "1F3DE" "1F3DF" "1F3E0" "1F3E1" "1F3E2" "1F3E3" "1F3E4" "1F3E5" "1F3E6" "1F3E7" "1F3E8" "1F3E9" "1F3EA" "1F3EB" "1F3EC" "1F3ED" "1F3EE" "1F3EF" "1F3F0" "1F3F3" "1F3F4" "1F3F5" "1F3F7" "1F3F8" "1F3F9" "1F3FA" "1F400" "1F401" "1F402" "1F403" "1F404" "1F405" "1F406" "1F407" "1F408" "1F409" "1F40A" "1F40B" "1F40C" "1F40D" "1F40E" "1F40F" "1F410" "1F411" "1F412" "1F413" "1F414" "1F415" "1F416" "1F417" "1F418" "1F419" "1F41A" "1F41B" "1F41C" "1F41D" "1F41E" "1F41F" "1F420" "1F421" "1F422" "1F423" "1F424" "1F425" "1F426" "1F427" "1F428" "1F429" "1F42A" "1F42B" "1F42C" "1F42D" "1F42E" "1F42F" "1F430" "1F431" "1F432" "1F433" "1F434" "1F435" "1F436" "1F437" "1F438" "1F439" "1F43A" "1F43B" "1F43C" "1F43D" "1F43E" "1F43F" "1F440" "1F441" "1F442" "1F443" "1F444" "1F445" "1F446" "1F447" "1F448" "1F449" "1F44A" "1F44B" "1F44C" "1F44D" "1F44E" "1F44F" "1F450" "1F451" "1F452" "1F453" "1F454" "1F455" "1F456" "1F457" "1F458" "1F459" "1F45A" "1F45B" "1F45C" "1F45D" "1F45E" "1F45F" "1F460" "1F461" "1F462" "1F463" "1F464" "1F465" "1F466" "1F467" "1F468" "1F469" "1F46A" "1F46B" "1F46C" "1F46D" "1F46E" "1F46F" "1F470" "1F471" "1F472" "1F473" "1F474" "1F475" "1F476" "1F477" "1F478" "1F479" "1F47A" "1F47B" "1F47C" "1F47D" "1F47E" "1F47F" "1F480" "1F481" "1F482" "1F483" "1F484" "1F485" "1F486" "1F487" "1F488" "1F489" "1F48A" "1F48B" "1F48C" "1F48D" "1F48E" "1F48F" "1F490" "1F491" "1F492" "1F493" "1F494" "1F495" "1F496" "1F497" "1F498" "1F499" "1F49A" "1F49B" "1F49C" "1F49D" "1F49E" "1F49F" "1F4A0" "1F4A1" "1F4A2" "1F4A3" "1F4A4" "1F4A5" "1F4A6" "1F4A7" "1F4A8" "1F4A9" "1F4AA" "1F4AB" "1F4AC" "1F4AD" "1F4AE" "1F4AF" "1F4B0" "1F4B1" "1F4B2" "1F4B3" "1F4B4" "1F4B5" "1F4B6" "1F4B7" "1F4B8" "1F4B9" "1F4BA" "1F4BB" "1F4BC" "1F4BD" "1F4BE" "1F4BF" "1F4C0" "1F4C1" "1F4C2" "1F4C3" "1F4C4" "1F4C5" "1F4C6" "1F4C7" "1F4C8" "1F4C9" "1F4CA" "1F4CB" "1F4CC" "1F4CD" "1F4CE" "1F4CF" "1F4D0" "1F4D1" "1F4D2" "1F4D3" "1F4D4" "1F4D5" "1F4D6" "1F4D7" "1F4D8" "1F4D9" "1F4DA" "1F4DB" "1F4DC" "1F4DD" "1F4DE" "1F4DF" "1F4E0" "1F4E1" "1F4E2" "1F4E3" "1F4E4" "1F4E5" "1F4E6" "1F4E7" "1F4E8" "1F4E9" "1F4EA" "1F4EB" "1F4EC" "1F4ED" "1F4EE" "1F4EF" "1F4F0" "1F4F1" "1F4F2" "1F4F3" "1F4F4" "1F4F5" "1F4F6" "1F4F7" "1F4F8" "1F4F9" "1F4FA" "1F4FB" "1F4FC" "1F4FD" "1F4FF" "1F500" "1F501" "1F502" "1F503" "1F504" "1F505" "1F506" "1F507" "1F508" "1F509" "1F50A" "1F50B" "1F50C" "1F50D" "1F50E" "1F50F" "1F510" "1F511" "1F512" "1F513" "1F514" "1F515" "1F516" "1F517" "1F518" "1F519" "1F51A" "1F51B" "1F51C" "1F51D" "1F51E" "1F51F" "1F520" "1F521" "1F522" "1F523" "1F524" "1F525" "1F526" "1F527" "1F528" "1F529" "1F52A" "1F52B" "1F52C" "1F52D" "1F52E" "1F52F" "1F530" "1F531" "1F532" "1F533" "1F534" "1F535" "1F536" "1F537" "1F538" "1F539" "1F53A" "1F53B" "1F53C" "1F53D" "1F549" "1F54A" "1F54B" "1F54C" "1F54D" "1F54E" "1F550" "1F551" "1F552" "1F553" "1F554" "1F555" "1F556" "1F557" "1F558" "1F559" "1F55A" "1F55B" "1F55C" "1F55D" "1F55E" "1F55F" "1F560" "1F561" "1F562" "1F563" "1F564" "1F565" "1F566" "1F567" "1F56F" "1F570" "1F573" "1F574" "1F575" "1F576" "1F577" "1F578" "1F579" "1F57A" "1F587" "1F58A" "1F58B" "1F58C" "1F58D" "1F590" "1F595" "1F596" "1F5A4" "1F5A5" "1F5A8" "1F5B1" "1F5B2" "1F5BC" "1F5C2" "1F5C3" "1F5C4" "1F5D1" "1F5D2" "1F5D3" "1F5DC" "1F5DD" "1F5DE" "1F5E1" "1F5E3" "1F5E8" "1F5EF" "1F5F3" "1F5FA" "1F5FB" "1F5FC" "1F5FD" "1F5FE" "1F5FF" "1F600" "1F601" "1F602" "1F603" "1F604" "1F605" "1F606" "1F607" "1F608" "1F609" "1F60A" "1F60B" "1F60C" "1F60D" "1F60E" "1F60F" "1F610" "1F611" "1F612" "1F613" "1F614" "1F615" "1F616" "1F617" "1F618" "1F619" "1F61A" "1F61B" "1F61C" "1F61D" "1F61E" "1F61F" "1F620" "1F621" "1F622" "1F623" "1F624" "1F625" "1F626" "1F627" "1F628" "1F629" "1F62A" "1F62B" "1F62C" "1F62D" "1F62E" "1F62F" "1F630" "1F631" "1F632" "1F633" "1F634" "1F635" "1F636" "1F637" "1F638" "1F639" "1F63A" "1F63B" "1F63C" "1F63D" "1F63E" "1F63F" "1F640" "1F641" "1F642" "1F643" "1F644" "1F645" "1F646" "1F647" "1F648" "1F649" "1F64A" "1F64B" "1F64C" "1F64D" "1F64E" "1F64F" "1F680" "1F681" "1F682" "1F683" "1F684" "1F685" "1F686" "1F687" "1F688" "1F689" "1F68A" "1F68B" "1F68C" "1F68D" "1F68E" "1F68F" "1F690" "1F691" "1F692" "1F693" "1F694" "1F695" "1F696" "1F697" "1F698" "1F699" "1F69A" "1F69B" "1F69C" "1F69D" "1F69E" "1F69F" "1F6A0" "1F6A1" "1F6A2" "1F6A3" "1F6A4" "1F6A5" "1F6A6" "1F6A7" "1F6A8" "1F6A9" "1F6AA" "1F6AB" "1F6AC" "1F6AD" "1F6AE" "1F6AF" "1F6B0" "1F6B1" "1F6B2" "1F6B3" "1F6B4" "1F6B5" "1F6B6" "1F6B7" "1F6B8" "1F6B9" "1F6BA" "1F6BB" "1F6BC" "1F6BD" "1F6BE" "1F6BF" "1F6C0" "1F6C1" "1F6C2" "1F6C3" "1F6C4" "1F6C5" "1F6CB" "1F6CC" "1F6CD" "1F6CE" "1F6CF" "1F6D0" "1F6D1" "1F6D2" "1F6E0" "1F6E1" "1F6E2" "1F6E3" "1F6E4" "1F6E5" "1F6E9" "1F6EB" "1F6EC" "1F6F0" "1F6F3" "1F6F4" "1F6F5" "1F6F6" "1F6F7" "1F6F8" "1F910" "1F911" "1F912" "1F913" "1F914" "1F915" "1F916" "1F917" "1F918" "1F919" "1F91A" "1F91B" "1F91C" "1F91D" "1F91E" "1F91F" "1F920" "1F921" "1F922" "1F923" "1F924" "1F925" "1F926" "1F927" "1F928" "1F929" "1F92A" "1F92B" "1F92C" "1F92D" "1F92E" "1F92F" "1F930" "1F931" "1F932" "1F933" "1F934" "1F935" "1F936" "1F937" "1F938" "1F939" "1F93A" "1F93C" "1F93D" "1F93E" "1F940" "1F941" "1F942" "1F943" "1F944" "1F945" "1F947" "1F948" "1F949" "1F94A" "1F94B" "1F94C" "1F950" "1F951" "1F952" "1F953" "1F954" "1F955" "1F956" "1F957" "1F958" "1F959" "1F95A" "1F95B" "1F95C" "1F95D" "1F95E" "1F95F" "1F960" "1F961" "1F962" "1F963" "1F964" "1F965" "1F966" "1F967" "1F968" "1F969" "1F96A" "1F96B" "1F980" "1F981" "1F982" "1F983" "1F984" "1F985" "1F986" "1F987" "1F988" "1F989" "1F98A" "1F98B" "1F98C" "1F98D" "1F98E" "1F98F" "1F990" "1F991" "1F992" "1F993" "1F994" "1F995" "1F996" "1F997" "1F9C0" "1F9D0" "1F9D1" "1F9D2" "1F9D3" "1F9D4" "1F9D5" "1F9D6" "1F9D7" "1F9D8" "1F9D9" "1F9DA" "1F9DB" "1F9DC" "1F9DD" "1F9DE" "1F9DF" "1F9E0" "1F9E1" "1F9E2" "1F9E3" "1F9E4" "1F9E5" "1F9E6" "203C" "2049" "2122" "2139" "2194" "2195" "2196" "2197" "2198" "2199" "21A9" "21AA" "231A" "231B" "2328" "23CF" "23E9" "23EA" "23EB" "23EC" "23ED" "23EE" "23EF" "23F0" "23F1" "23F2" "23F3" "23F8" "23F9" "23FA" "24C2" "25AA" "25AB" "25B6" "25C0" "25FB" "25FC" "25FD" "25FE" "2600" "2601" "2602" "2603" "2604" "260E" "2611" "2614" "2615" "2618" "261D" "2620" "2622" "2623" "2626" "262A" "262E" "262F" "2638" "2639" "263A" "2640" "2642" "2648" "2649" "264A" "264B" "264C" "264D" "264E" "264F" "2650" "2651" "2652" "2653" "2660" "2663" "2665" "2666" "2668" "267B" "267F" "2692" "2693" "2694" "2695" "2696" "2697" "2699" "269B" "269C" "26A0" "26A1" "26AA" "26AB" "26B0" "26B1" "26BD" "26BE" "26C4" "26C5" "26C8" "26CE" "26CF" "26D1" "26D3" "26D4" "26E9" "26EA" "26F0" "26F1" "26F2" "26F3" "26F4" "26F5" "26F7" "26F8" "26F9" "26FA" "26FD" "2702" "2705" "2708" "2709" "270A" "270B" "270C" "270D" "270F" "2712" "2714" "2716" "271D" "2721" "2728" "2733" "2734" "2744" "2747" "274C" "274E" "2753" "2754" "2755" "2757" "2763" "2764" "2795" "2796" "2797" "27A1" "27B0" "27BF" "2934" "2935" "2B05" "2B06" "2B07" "2B1B" "2B1C" "2B50" "2B55" "3030" "303D" "3297")
len=${#emojis[@]}

for i in "${keycodes[@]}"; do
	n=$(($RANDOM % len))
	g=$(($RANDOM % len))
	xmodmap -e "keycode  ${i} = U${emojis[$n]} U${emojis[$g]}"
done

Self explanatory I think. You might want to backup your keymap (xmodmap -pke > xmm.txt) to restore (xmodmap xmm.txt) it later. All changes are temporary (-e).


#!/bin/bash
xclip -selection clipboard -target image/png -i "/path/to/image.png"

Copies an image as such into the clipboard. Useful to set as shortcut if you frequently use an image on social media (e.g. Discord).


#!/bin/bash
if [[ $1 == "" ]]; then
	echo "Please supply a file to play."
	exit 1
fi

frp=$(realpath "$1")

if [[ $2 == "f" ]]; then
	fwidth="100%"
	fheight="100%"
	bpb=""
else
	fwidth=$(mediainfo --output=JSON "${frp}" | jq . | grep "Width" | cut -d '"' -f 4)
	fheight=$(mediainfo --output=JSON "${frp}" | jq . | grep "Height" | cut -d '"' -f 4)
	bpb="<br></br>"
fi

echo "<style>html{ background-color: #232323; }</style><center>${bpb}<embed src='${frp}' type='application/x-shockwave-flash' width='${fwidth}' height='${fheight}' quality='high'></center>" > /tmp/cflashplayer.html
firefox --new-tab /tmp/cflashplayer.html

For all of those getting mad over firefox not playing your .swf files and instead just wanting to download them. A crude yet nice .SWF player (uses firefox). Supply "f" as second argument for fullscreen. Requires jq and mediainfo.

Offline

#3270 2019-09-29 21:55:07

t3kk3n
Member
Registered: 2014-04-18
Posts: 24

Re: Post your handy self made command line utilities

Someone may have use for the following small script I wrote, for use with a yubikey/crypto device:

#!/bin/bash

function genhelp () {
    echo -e "$0 <lock/unlock/relock>"
    exit 1
}

if [ $# -eq 0 ]; then genhelp; fi

if [[ "$1" == "lock" ]]; then
    rm -rf /tmp/netacct-*
elif [[ "$1" == "unlock" ]]; then
    rm -rf /tmp/netacct-*
    tmpd=$(mktemp -p /tmp -d netacct-XXXXXXXX)
    gpgtar -C "$tmpd" --decrypt /home/usr/files/ncred 1>/dev/null 2>/dev/null
    echo "$tmpd"
elif [[ "$1" == "relock" ]]; then
    tdir=$(find '/tmp/' -maxdepth 1 -type d -name 'netacct-*' -print -quit)
    if [[ -z "$tdir" ]]; then
        echo "Credentials not found, exiting"
        exit 1
    fi
    gpgtar -C "$tdir" --encrypt --output /home/usr/files/ncred --recipient XXXXXXX z1
else
    genhelp
fi

I have all of my passwords stored in individual files, for each online website I have a username/password with. I utilize this script to simply decrypt the files in one swoop, re-encrypt the password files back into the original gpg'd tar archive, and to remove the temporary directory in /tmp. Currently, my yubikey stick is set up with a main unlock passcode, so when this script is executed, it will prompt for the code. After the first time, it will be stored in the keyring. I also have a udev script set up to remote the decrypted files when the yubikey stick is removed, as follows: (stored in /etc/udev/rules.d/XX-name.rules)

ACTION=="remove", ENV{ID_MODEL}=="Yubikey_4_OTP+U2F+CCID", ENV{ID_VENDOR_ID}=="1050", ENV{ID_MODEL_ID}=="0407", RUN+="/usr/local/bin/netaccts lock"

Cheers to anyone who uses this, or makes this better.

Offline

#3271 2019-09-29 22:29:00

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,330
Website

Re: Post your handy self made command line utilities

A case statement could clean that up:

#!/bin/bash

case $1 in
   unlock)
      rm -rf /tmp/netacct-*
      tmpd=$(mktemp -p /tmp -d netacct-XXXXXXXX)
      gpgtar -C "$tmpd" --decrypt /home/usr/files/ncred 1>/dev/null 2>&1
      echo "$tmpd"
      ;;
   relock)
      tdir=$(find '/tmp/' -maxdepth 1 -type d -name 'netacct-*' -print -quit)
      if [[ -z "$tdir" ]]; then
         echo "Credentials not found, exiting"
         exit 1
      fi
      gpgtar -C "$tdir" --encrypt --output /home/usr/files/ncred --recipient XXXXXXX z1
      ;&
   lock)
      rm -rf /tmp/netacct-*
      ;;
   *)
      echo -e "$0 <lock/unlock/relock>"
      exit 1
esac

Note I changed the logic slightly so that relock also removes /tmp/netacct-*.  Given that you are "relocking" it should end up in a locked state.  If you don't want this, then just add back a ';;' terminator for the relock case which currently falls through to the lock case.

EDIT: apparently fallthrough only works in BASH and has a funky terminating symbol ';&'.  I could have sworn I used case-statement fallthrough in shells before just by omitting the ';;', perhaps I'm remembering incorrectly.

Last edited by Trilby (2019-09-30 00:25:49)


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#3272 2019-09-30 16:09:08

t3kk3n
Member
Registered: 2014-04-18
Posts: 24

Re: Post your handy self made command line utilities

Trilby, thanks for that. And yeah, I know, I should probably use case statements more. Thanks more for informing me about the fall back feature, didn't know about that! I heavily/extensively use zsh, would it be any different?

Offline

#3273 2019-09-30 17:49:24

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,330
Website

Re: Post your handy self made command line utilities

I don't know zsh at all - when I first wrote the above code I thought fallthrough was in all shells, but was wrong (it's a C thing I guess and recently added to BASH).

Without the fallthrough, though, you'd only duplicate the one rm line.

Using a case with a default case is what really simplifies it so you don't need to check multiple times on whether the help output should be displayed.

Last edited by Trilby (2019-09-30 17:50:09)


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#3274 2019-10-06 05:00:22

quequotion
Member
From: Oita, Japan
Registered: 2013-07-29
Posts: 814
Website

Re: Post your handy self made command line utilities

Yet another tts script, based on this.

tts:

#!/bin/bash

textin="/tmp/.tts-in" && [[ ! -p "${textin}" ]] && mkfifo -m 600 "${textin}"
wavout="/tmp/.tts-out" && [[ ! -p "${wavout}" ]] && mkfifo -m 600 "${wavout}"
htsvoice="/usr/share/hts/voices/english/cmu_us_arctic_slt.htsvoice" && \
  [[ ! -f "${htsvoice}" ]] && echo "HTS voice not available" && exit 1

while IFS= read -r line; do
  echo "${line}" > "${textin}" &
  flite_hts_engine -m "${htsvoice}" \
                   -s 48000 -r 1.3 -fm 0 \
                   "${textin}" -o "${wavout}" &
  paplay -d Center-Mono "${wavout}"
done <<< "${@}"

This was easier for me than patching flite_hts_engine to use stdio.

paplay is better at guessing the audio format than aplay, and allows to send the output to any pulseaudio sink. "Center-Mono" is a remapped (virtual) sink on a digital 5.1 output, using only the center channel.

/etc/pulse/default.pa (excerpt):

#Center mono
load-module module-remap-sink sink_name=Center-Mono sink_properties="device.description='Center Mono (5.1 AC3 on ALC892 Digital)' media.name='Center-Mono'" master=alsa_output.pci-0000_00_1b.0.iec958-ac3-surround-51 channels=1 master_channel_map=center channel_map=mono

Edit: Subsequently, rewrote dmesg-speak!

Last edited by quequotion (2019-10-06 09:38:10)

Offline

#3275 2019-11-10 02:48:46

avi9526
Member
Registered: 2015-05-15
Posts: 117

Re: Post your handy self made command line utilities

On my notebook KDE changing screen brightness too hard, wanted smooth change like in windows, so made script

arguments: [number of steps] [single step amount]
bind it to brightness keys as
~/backlight 10 2
~/backlight -10 2

#!/usr/bin/bash

Amount=${1}
Inc=${2:-1}

function getbacklight {
    qdbus org.kde.Solid.PowerManagement /org/kde/Solid/PowerManagement/Actions/BrightnessControl org.kde.Solid.PowerManagement.Actions.BrightnessControl.brightness
}

function setbacklight {
    qdbus org.kde.Solid.PowerManagement /org/kde/Solid/PowerManagement/Actions/BrightnessControl org.kde.Solid.PowerManagement.Actions.BrightnessControl.setBrightness "$1"
}

if ((${Amount} < 0));
then
    Inc=$((-$Inc))
    Amount=$((-$Amount))
fi

for (( i = 0; i <= ${Amount}; i++ )) ; do
    setbacklight $(($(getbacklight) + $Inc))
done

Last edited by avi9526 (2019-11-10 02:50:00)

Offline

Board footer

Powered by FluxBB