You are not logged in.

#3426 2020-11-21 19:51:50

qinohe
Member
From: Netherlands
Registered: 2012-06-20
Posts: 1,265

Re: Post your handy self made command line utilities

Oops, now I see, I need a good night rest I think..
Yeah, you're right I use a menu, my rationale was; why 'remember' if I can let the script do it for me tongue

Offline

#3427 2020-11-28 22:08:08

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

Re: Post your handy self made command line utilities

Systray Bluetooth Profile Switcher

https://github.com/ugjka/bt_profile


Fix yo shit: journalctl -b -p warning
Github

Offline

#3428 2020-11-30 19:23:00

schard
Member
From: Hannover
Registered: 2016-05-06
Posts: 1,148
Website

Re: Post your handy self made command line utilities

Since I'm using multiple kernel flavors but no boot manager with a visible menu, I wrote a hook to display the currently booting kernel version:

$ cat /etc/initcpio/hooks/uname 
#!/usr/bin/ash

run_hook() {
    echo -n "   "  # Align uname output with hook header.
    uname -r
}
$ cat /etc/initcpio/install/uname 
#!/bin/bash

build() {
    add_binary "uname"
    add_runscript
}

help() {
    cat <<HELPEOF
This hook prints the current kernel version during the initramfs phase.
HELPEOF
}

Offline

#3429 2020-12-05 17:45:53

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

Re: Post your handy self made command line utilities

Not a command line script, but a Tampermonkey script for browsers to make https://m.facebook.com/ useable on desktop computer which I prefer over the new desktop design.

https://gist.github.com/ugjka/2c3a94f8a … b4d79723e9

// ==UserScript==
// @name         Facebook Mobile on Desktop
// @namespace    http://tampermonkey.net/
// @version      0.3
// @description  Enhancments for FB mobile on Desktop!
// @author       https://github.com/ugjka/
// @match        https://m.facebook.com/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';
    var body = document.getElementsByTagName("BODY")[0]
    body.style.width = "500px";
    body.style.margin = "auto";

    document.addEventListener("DOMNodeInserted", function () {
        var stories;
        var composer;
        try {
            stories = document.getElementById("story_bucket_viewer_content").childNodes[0];
        }
        catch { }
        if (stories) {
            stories.style.width = "500px";
            stories.style.margin = "auto";
        };
        try {
            composer = document.getElementById("composer-main-view-id")
        }
        catch { }
        if (composer) {
            composer.style.width = "500px";
            composer.style.margin = "auto";
        };
    });
})();

Last edited by ugjka (2020-12-05 18:40:19)


Fix yo shit: journalctl -b -p warning
Github

Offline

#3430 2020-12-09 00:58:13

ephemeralCuriosities
Member
From: Puerto Rico
Registered: 2014-11-23
Posts: 30

Re: Post your handy self made command line utilities

I wanted to keep track of packages missing from both the Arch repos and the AUR after an update (dead packages, basically), so I wrote a script that runs anytime I use pacmatic:

#!/usr/bin/dash -
# Print out packages missing from both repos and AUR.
# shellcheck disable=SC2086

set -e

get_packages(){
    curl -s https://aur.archlinux.org/packages.gz ||
        printf '%s\n' "ERROR: Couldn't obtain packages." >&2
}

make_regex(){
    # Output example: "^item1$|^item2$|^item3$"
    printf '%s' "^$1$"
    shift 1
    while [ -n "$1" ]; do
        printf '%s' "|^$1$"
        shift 1
    done
}

installed_pkgs=$(pacman -Qqm)
[ -n "$installed_pkgs" ] || exit 0

aur_packages=$(get_packages |
    gzip -cd 2> /dev/null |
    sort |
    grep -E "($(make_regex $installed_pkgs))")

[ "$installed_pkgs" = "$aur_packages" ] ||
    if [ -z "$aur_packages" ]; then
        printf '%s\n' "$installed_pkgs"
    else
        printf '%s\n' "$installed_pkgs" |
            grep -E -v "($(make_regex $aur_packages))"
    fi

In other words, I probably missed some package or command that does that for me and I just overcomplicated my life yet again.

Offline

#3431 2020-12-09 01:21:16

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 25,236

Re: Post your handy self made command line utilities

That's a lot of steps ... this should do the same:

#!/bin/sh

pacman -Qqm \
	| sort > /tmp/non-repo.pkgs
curl -s https://aur.archlinux.org/packages.gz \
	| zcat \
	| sort \
	| comm -23 /tmp/non-repo.pkgs -

Or if your shell has process substitution:

#!/bin/bash

curl -s https://aur.archlinux.org/packages.gz \
	| zcat \
	| sort \
	| comm -23 <(pacman -Qqm | sort) -

"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#3432 2020-12-09 02:36:49

ephemeralCuriosities
Member
From: Puerto Rico
Registered: 2014-11-23
Posts: 30

Re: Post your handy self made command line utilities

Trilby wrote:

That's a lot of steps ...

Yeah, I tend to overcomplicate things a lot. Mainly because I don't know as many commands as I should (first I've heard of both zcat and comm, for example).

Thanks for the simpler solution! I'll use the first one 'cause I understand it better (I only know how to write posix shell scripts—bash is a complete mystery to me).

Offline

#3433 2020-12-09 03:28:00

eschwartz
Trusted User/Bug Wrangler
Registered: 2014-08-08
Posts: 4,052

Re: Post your handy self made command line utilities

zcat is usually a shellscript thar runs:

#!/bin/sh

exec gzip -cd "$@"

zless is a bit more useful of a wrapper, since it can transparently gzip -dc for you by defining $LESSOPEN, and zgrep is very useful... though mainly I'd use these convenience wrappers on disk files, not in pipelines.

P.S. If zcat is new to you, you'll probably be interested in the other convenience wrappers, the full list of which is, more or less,

pacman -Qql gzip| grep bin/z

Managing AUR repos The Right Way -- aurpublish (now a standalone tool)

Offline

#3434 2020-12-09 04:00:08

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 25,236

Re: Post your handy self made command line utilities

eschwartz wrote:

zless is a bit more useful of a wrapper ...

Do you mean in general?  I don't believe it'd be of any use in the present context.

eschwartz wrote:

... though mainly I'd use these convenience wrappers on disk files, not in pipelines.

Why is that?  There's no need to save the packages.gz for this.


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#3435 2020-12-09 04:02:35

eschwartz
Trusted User/Bug Wrangler
Registered: 2014-08-08
Posts: 4,052

Re: Post your handy self made command line utilities

You're correct, I meant in the general case not for this specific script.

Disk files might be relevant any time you're inspecting general files *originating* on disk.


Managing AUR repos The Right Way -- aurpublish (now a standalone tool)

Offline

#3436 2020-12-10 07:43:38

GSMiller
Member
Registered: 2020-11-23
Posts: 75

Re: Post your handy self made command line utilities

gzip also contains other utilities that are useful in general, but not specific to this use case:
gzip /usr/bin/gunzip
gzip /usr/bin/gzexe
gzip /usr/bin/gzip
gzip /usr/bin/uncompress
gzip /usr/bin/zcat
gzip /usr/bin/zcmp
gzip /usr/bin/zdiff
gzip /usr/bin/zegrep
gzip /usr/bin/zfgrep
gzip /usr/bin/zforce
gzip /usr/bin/zgrep
gzip /usr/bin/zless
gzip /usr/bin/zmore
gzip /usr/bin/znew


A dog is a man's best friend.

Offline

#3437 2020-12-14 08:02:05

Awebb
Member
Registered: 2010-05-06
Posts: 5,823

Re: Post your handy self made command line utilities

You could use that output lazily and paste it everywhere, of you could just...

pacx ()
{
    for pkg in "$@"
    do
        printf "$pkg: $(pacman -Qql $pkg | grep "bin/." | sed 's/\/usr\/bin\/'// | xargs | fold -s -w $(( $(tput cols) - 2 - ${#pkg} )))\n";
    done
}

I'm not satisfied with the number of pipes and it could look better with some indentation, but it does the job. Getting the thing to wrap on whitespaces only required some research. Maybe I need more awk and more printf in my life. Time for an awk week? :wacko:

EDIT:

What do you guys prefer and why? Above construct or:

for a in b; do
    something
done

Last edited by Awebb (2020-12-14 08:03:18)

Offline

#3438 2020-12-14 13:50:04

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 25,236

Re: Post your handy self made command line utilities

There is no need for everything to be nested in a subshell in the printf format string.  All the commands in the subshell print to stdout anyways.  More importantly: grep + sed = sed (and xargs is a confusing way to just remove newlines, which sed can do too):

for pkg in "$@"; do
   printf $pkg:
   pacman -Qql $pkg \
      | sed -n '/bin/{s/\/usr\/bin\///;H;}${x;s/\n/ /g;p;}' \
      | fold -s -w $(( $(tput cols) - 2 - ${#pkg} ))
done

And this code example should express my view on the second question.

Or to give more love to printf, it can also remove excess newlines:

for pkg in "$@"; do
   printf "$pkg:"
   printf " %s" $(pacman -Qql $pkg | sed -n 's/\/usr\/bin\///p}') \
      | fold -s -w $(( $(tput cols) - 2 - ${#pkg} ))
   printf "\n"
done

Of course none of this addresses the "fold" which has no business inside the loop.  In fact, once it's out of the loop, you can ditch the gymastics dealing with the length of the pkgname:

for pkg in "$@"; do
        printf "$pkg:"
        printf " %s" $(pacman -Qql $pkg | sed -n 's/\/usr\/bin\///p}')
        printf "\n"
done | fold -s -w $(tput cols)

Of course, as soon as you start thinking about taking things out of the loop, you may realize that there's no reason for pacman to be in the loop as pacman can act on many packages at once.  So all we need to do then is get all the information from pacman in one call, then use some other process to format it.  Awk is nice for this:

pacman -Ql $@ | awk '
$2 ~ "/usr/bin/" {
        sub(/\/usr\/bin\//,"",$2);
        pkg[$1]=pkg[$1]" "$2;
}
END {
        for (p in pkg)
                printf "%s:%s\n", p, pkg[p];
}
' | fold -s -w $(tput cols)

And as I love sed, it's worth showing that awk is not needed and this can also be done in sed:

pacman -Ql $@ | sed -n '
/ \/usr\/bin\/$/ {
      s/ .*/:/
      h
   :loop
      n
      s/[^ ]* \/usr\/bin\///
      t append
      b end
   :append
      H
      b loop
   :end
      x
      s/\n/ /g
      p
}
' | fold -s -w $(tput cols)

Or if you're a sadist, a technical oneliner:

pacman -Ql $@ | sed -n '/ \/usr\/bin\/$/{s/ .*/:/;h;:a;n;s/[^ ]* \/usr\/bin\///;tb;bc;:b;H;ba;:c;x;s/\n/ /g;p;}' | fold -s -w $(tput cols)

Last edited by Trilby (2020-12-14 14:54:34)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#3439 2020-12-14 16:33:21

Awebb
Member
Registered: 2010-05-06
Posts: 5,823

Re: Post your handy self made command line utilities

Thanks, Trilby. I guess that answers my EDIT question big_smile

Trilby wrote:

More importantly: grep + sed = sed (and xargs is a confusing way to just remove newlines, which sed can do too):

Oh yeah, I've been abusing xargs as much as the next guy does cat for years.

Trilby wrote:

Of course none of this addresses the "fold" which has no business inside the loop.  In fact, once it's out of the loop, you can ditch the gymastics dealing with the length of the pkgname:

for pkg in "$@"; do
        printf "$pkg:"
        printf " %s" $(pacman -Qql $pkg | sed -n 's/\/usr\/bin\///p}')
        printf "\n"
done | fold -s -w $(tput cols)

That's my favorite solution so far, I guess sed requires more attention. I thought I had tried exactly that fold syntax and it broke horribly.

Offline

#3440 2020-12-16 14:04:27

ephemeralCuriosities
Member
From: Puerto Rico
Registered: 2014-11-23
Posts: 30

Re: Post your handy self made command line utilities

Here's another script I use on my system, this time to send desktop notifications whenever there are packages to update (it's set on a timer for every six hours since boot).  I know I can do the formatting on sed easily, but I wanted to use only shell built-in stuff for funsies.

#!/usr/bin/dash -
# Send notification on Arch/AUR updates
# shellcheck disable=SC2046

notify(){
    loc="$1"
    shift 1
    amt="$#"

    [ $amt -eq 0 ] && return 0
    notify-send \
        -a "acheck-$loc" \
        -u normal \
        -i distributor-logo-archlinux \
        "$(title)" \
        "$(format  "${@}")"
}

title(){
    case $loc in
        repo )
            [ $amt -eq 1 ] &&
                printf '%s package updated' "$amt" ||
                printf '%s packages updated' "$amt"
            ;;
        aur )
            [ $amt -eq 1 ] &&
                printf '%s AUR package updated' "$amt" ||
                printf '%s AUR packages updated' "$amt"
            ;;
    esac
}

format(){
    lim=$((amt < 16 ? amt : 15))
    rem=$((amt - lim))

    while [ $lim -ne 0 ]
    do
        ver="${1#* }"
        printf '<b>%s</b> – %s <b>→</b> %s\n' \
            "${1%% *}" \
            "${ver%% *}" \
            "${1##* }"
        lim=$((lim - 1))
        shift 1
    done
    [ $rem -eq 0 ] || printf '<i>...plus %s more.</i>\n' "$rem"
}

IFS="
"
notify repo $(checkupdates 2> /dev/null)
notify aur $(auracle sync 2> /dev/null)

Last edited by ephemeralCuriosities (2020-12-16 14:14:13)

Offline

#3441 2020-12-16 18:38:16

GSMiller
Member
Registered: 2020-11-23
Posts: 75

Re: Post your handy self made command line utilities

Awebb wrote:

Oh yeah, I've been abusing xargs as much as the next guy does cat for years.

Hello Awebb, you might want to look at this web page:
http://www.novosial.org/shell/useless-cat/
wink


A dog is a man's best friend.

Offline

#3442 2020-12-17 13:22:42

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

Re: Post your handy self made command line utilities


Mods are just community members who have the occasionally necessary option to move threads around and edit posts. -- Trilby
Honest Alad's Package Emporium—Now with added bugs! (Grand reopening: December 1st 2018)

Offline

#3443 2020-12-24 15:31:12

schard
Member
From: Hannover
Registered: 2016-05-06
Posts: 1,148
Website

Re: Post your handy self made command line utilities

Since I did not find an appropriate existing program, I wrote a script to list imports of a python project:

#! /usr/bin/env python3
#  lsimports.py - List python project imports
#  Copyright (C) 2020 Richard Neumann <mail at richard dash neumann period de>
#
#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  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.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <https://www.gnu.org/licenses/>.
"""Lists imports of python modules and packages."""

from argparse import ArgumentParser, Namespace
from ast import Import, ImportFrom, Module, parse
from distutils.sysconfig import get_python_lib
from itertools import chain
from logging import INFO, WARNING, basicConfig, getLogger
from pathlib import Path
from typing import Iterable, Iterator


DESCRIPTION = __doc__
LOG_FORMAT = '[%(levelname)s] %(name)s: %(message)s'
LOGGER = getLogger(Path(__file__).stem)
STDLIB = Path(get_python_lib(standard_lib=True))


def get_imports_from_module(module: Module) -> Iterator[str]:
    """Lists imports from a module AST."""

    for element in module.body:
        if isinstance(element, Import):
            for name in element.names:
                yield name.name
        elif isinstance(element, ImportFrom):
            yield element.module


def get_imports_from_file(path: Path) -> Iterator[str]:
    """Lists imports of the given file."""

    with path.open('r') as file:
        source_code = file.read()

    try:
        module = parse(source_code)
    except SyntaxError:
        LOGGER.error('Cannot parse "%s" due to syntax error.', path)
        return

    yield from get_imports_from_module(module)


def get_imports_from_files(paths: Iterable[Path]) -> Iterator[str]:
    """Returns the imports from multiple files."""

    for path in paths:
        LOGGER.info('Checking: %s', path)
        yield from get_imports_from_file(path)


def get_module_root(module: str) -> str:
    """Returns a set of imported module roots."""

    return module.split('.')[0]


def is_module(path: Path) -> bool:
    """Determines whether the given file is a python module."""

    return path.is_file() and path.suffix == '.py'


def is_package(path: Path) -> bool:
    """Determines whether the given directory is a python package."""

    if not path.is_dir():
        return False

    return '__init__.py' in {path.name for path in path.iterdir()}


def list_library(root: Path) -> Iterator[str]:
    """Yields modules and packages of the given library path."""

    for path in root.iterdir():
        if is_module(path) or is_package(path):
            yield path.stem


def iterfiles(path: Path) -> Iterator[Path]:
    """Recursively yields files in a directory."""

    if path.is_dir():
        for subdir in path.iterdir():
            yield from iterfiles(subdir)
    elif path.is_file():
        yield path


def get_args() -> Namespace:
    """Parses and returns the command line arguments."""

    parser = ArgumentParser(description=DESCRIPTION)
    parser.add_argument('path', nargs='*', type=Path, default=[Path.cwd()],
                        help='the files and folders to scan for imports')
    parser.add_argument('-E', '--exclude-stdlib', action='store_true',
                        help='exclude imports from the standard library')
    parser.add_argument('-e', '--exclude-modules', nargs='+', default=(),
                        metavar='module', help='exclude the specified modules')
    parser.add_argument('-s', '--stdlib', type=Path, default=STDLIB,
                        metavar='path',
                        help='specifies the root of the standard library')
    parser.add_argument('-v', '--verbose', action='store_true',
                        help='print verbose messages')
    return parser.parse_args()


def main():
    """Runs the script."""

    args = get_args()
    basicConfig(format=LOG_FORMAT, level=INFO if args.verbose else WARNING)
    files = filter(is_module, chain(*map(iterfiles, args.path)))
    imports = set(map(get_module_root, get_imports_from_files(files)))
    imports -= set(args.exclude_modules)

    if args.exclude_stdlib:
        imports -= set(list_library(args.stdlib))

    for module in imports:
        print(module)


if __name__ == '__main__':
    main()

Gist: https://gist.github.com/conqp/cb4151186 … 5df431aaf3
Review: https://codereview.stackexchange.com/qu … n-projects

Last edited by schard (2020-12-24 17:20:34)

Offline

#3444 2020-12-24 16:25:22

CarbonChauvinist
Member
Registered: 2012-06-16
Posts: 324

Re: Post your handy self made command line utilities

Stumbled through the following which works for my needs to check vcs packages for available updates using `aur-srcver` and rebuild if available. The initial two lines are copied directly from aurutils code.

~ $ type vcs-sync
vcs-sync is a function
vcs-sync ()
{
    AURVCSSEARCH=".*-(cvs|svn|git|hg|bzr|darcs)$";
    mapfile -t mypacks < <(awk -v "mask=$AURVCSSEARCH" '$1 ~ mask {print $1}' <(aur repo --list));
    declare TRIMMED_PACKS=();
    AURCACHE="/pkg/aur/aurutils/sync";
    if [ "${#mypacks[@]}" = 0 ]; then
        printf "%s\n" "no packs here";
        return 1;
    else
        printf "%s\n" "Checking (${#mypacks[@]}) vcs-packages for newer commits: ... ";
    fi;
    for i in "${!mypacks[@]}";
    do
        PACK="${mypacks[$i]}";
        if [ -d "$AURCACHE/$PACK" ] && pacman -Q "$PACK" > /dev/null 2>&1; then
            FTEST=$( (cd $AURCACHE && aur srcver "$PACK" 2>/dev/null) | awk '{print $2}');
            STEST=$(pacman -Q "$PACK" | awk '{print $2}');
            if [ "$(vercmp "$FTEST" "$STEST")" -gt 0 ]; then
                TRIMMED_PACKS+=("${PACK}");
                printf "%s\n" "$PACK has updates";
            fi;
        fi;
    done;
    if [ "${#TRIMMED_PACKS[@]}" -gt 0 ]; then
        printf "%s\n" "Rebuilding (${#TRIMMED_PACKS[@]}) vcs-packages: ... " "${TRIMMED_PACKS[@]}";
        ( cd $AURCACHE && aur sync --rebuild "$(printf "%s\n" "${TRIMMED_PACKS[@]}")" && unset mypacks );
    else
        printf "%s\n" "No vcs-packages to update at this time.";
    fi
}

Last edited by CarbonChauvinist (2020-12-24 16:34:35)


"the wind-blown way, wanna win? don't play"

Offline

#3445 2020-12-25 10:37:15

ondoho
Member
Registered: 2013-04-30
Posts: 690
Website

Re: Post your handy self made command line utilities

teckk, who I think also has an account here, shared this on LQ.
Here's the Arch version:

#!/usr/bin/python

from turtle import *
from random import randint

def create_rectangle(turtle, color, x, y, width, height):
    turtle.penup()
    turtle.color(color)
    turtle.fillcolor(color)
    turtle.goto(x, y)
    turtle.pendown()
    turtle.begin_fill()

    turtle.forward(width)
    turtle.left(90)
    turtle.forward(height)
    turtle.left(90)
    turtle.forward(width)
    turtle.left(90)
    turtle.forward(height)
    turtle.left(90)
    turtle.end_fill()
    turtle.setheading(0)

def create_circle(turtle, x, y, radius, color):
    oogway.penup()
    oogway.color(color)
    oogway.fillcolor(color)
    oogway.goto(x, y)
    oogway.pendown()
    oogway.begin_fill()
    oogway.circle(radius)
    oogway.end_fill()

BG_COLOR = "#130D80"
oogway = Turtle()
oogway.speed(10)

screen = oogway.getscreen()
screen.bgcolor(BG_COLOR)
screen.title("Merry Christmas ArchLinux")
screen.setup(width=.7, height=.7)

y = -100
create_rectangle(oogway, "brown", -15, y-60, 30, 60)

width = 240
oogway.speed(20)
while width > 10:
    width = width - 10
    height = 10
    x = 0 - width/2
    create_rectangle(oogway, "green", x, y, width, height)
    y = y + height

oogway.speed(5)
oogway.penup()
oogway.color('yellow')
oogway.goto(-20, y+10)
oogway.begin_fill()
oogway.pendown()
for i in range(5):
    oogway.forward(40)
    oogway.right(144)
oogway.end_fill()

tree_height = y + 40

create_circle(oogway, 230, 180, 60, "white")
create_circle(oogway, 220, 180, 60, BG_COLOR)

oogway.speed(20)
number_of_stars = randint(20,30)

for _ in range(0,number_of_stars):
    x_star = randint(-(screen.window_width()//2),screen.window_width()//2)
    y_star = randint(tree_height, screen.window_height()//2)
    size = randint(5,20)
    oogway.penup()
    oogway.color("white")
    oogway.goto(x_star, y_star)
    oogway.begin_fill()
    oogway.pendown()
    for i in range(5):
        oogway.forward(size)
        oogway.right(144)
    oogway.end_fill()

oogway.speed(2)
oogway.penup()
msg = ('Merry Christmas to all Archers!'
        ' And best wishes for a happy and healthier new year.')
        
oogway.goto(0, -200)
oogway.color("white")
oogway.pendown()
oogway.write(msg, move=False, align="center", font=("sans-serif", 15, "bold"))
oogway.hideturtle()

screen.mainloop()

Merry Christmas everyone!


However studied and stilted your rant, it can never hide the base and primitve emotion that inspired it.
There's no objectivity.

Offline

#3446 2020-12-28 05:48:46

karabaja4
Member
From: Croatia
Registered: 2008-09-14
Posts: 913

Re: Post your handy self made command line utilities

Combined cp and progress commands into a single script to create an alias for cp to show progress while copying:

alias cp='/path/to/your/scripts/cp.sh'
#!/bin/bash
set -euo pipefail

_dep() {
    if ! type "${1}" &> /dev/null
    then
        echo "${1} could not be found"
        exit
    fi
}

_dep "progress"
_dep "tput"

cp "$@" &
declare -r pid=${!}

_exit() {
    kill ${pid} > /dev/null 2>&1
    if (( ${?} == 0 ))
    then
        echo -ne "\nKilled ${pid}"
    fi
}

declare ln=0
_print() {
    if [[ "${1}" == "" ]]
    then
        return 0
    fi
    if (( $ln > 0 ))
    then
        tput cuu ${ln}
        tput ed
    fi
    echo -e "${1}" | sed 's/^\s*//' | cut -c "-$(tput cols)"
    ln=2
}

_progress() {
    progress ${1:+"${1}"} -p ${pid} 2>/dev/null
}

trap "_exit" EXIT

_print "$(_progress)"

while true
do
    _print "$(_progress -w)"

    # die if cp finished
    kill -0 "${pid}" &> /dev/null
    if (( ${?} != 0 ))
    then
        break
    fi
done

Last edited by karabaja4 (2020-12-28 06:55:58)

Offline

#3447 2021-01-04 21:25:16

Head_on_a_Stick
Member
From: London
Registered: 2014-02-20
Posts: 5,838
Website

Re: Post your handy self made command line utilities

Entirely trivial and totally unnecessary but I was bored today stuck in the house with a bad back so I wrote this script to show a whiptail dialogue box for selecting a target partition to arch-chroot into:

#!/bin/sh

_list_part ()
{
   # list all partitions except swap & those already mounted
   lsblk -lno name,type,mountpoint | awk '/part/&&!/\//&&!/SWAP/{print $1,$1}'
}

_select_part ()
{
   # shellcheck disable=SC2046 # word spitting is needed for the _list_part function
   choice=$(whiptail --notags --menu "Please select target root partition:" 0 0 0 $(_list_part) 3>&2 2>&1 1>&3)
   if [ -z "$choice" ]; then
      exit 1
   fi
}

_chroot ()
{
   mount /dev/"$choice" /mnt
   arch-chroot /mnt mount -a
   arch-chroot /mnt
   umount -R /mnt
}

_confirm ()
{
   if whiptail --yesno "Target partition is /dev/${choice}, is this correct?" 0 0 0; then
      _chroot
      exit 0
   fi
}

main ()
{
   while true; do
      _select_part
      _confirm
   done
}

main

@Trilby: please be gentle with me big_smile

Offline

#3448 2021-01-04 21:47:39

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 25,236

Re: Post your handy self made command line utilities

Head_on_a_Stick wrote:

@Trilby: please be gentle with me big_smile

I wasn't going to say anything ... but with two posts in a row with it: what's with all the function names starting with underscores?

I've heard one case for such naming with the (claimed) logic that it prevents taking names in the environment that might be used for something else.  This is silly logic from the start, as now multiple people are naming things starting with underscores, so name clashes will be no less likely - it's just ugly names that might clash.  But far more importantly, these are scripts, not shell function libraries; the function names do not persist once the script is done running.


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#3449 2021-01-04 21:51:20

seth
Member
Registered: 2012-09-03
Posts: 20,440

Re: Post your handy self made command line utilities

lsblk -lno name,type,mountpoint | awk '/part/&&!/\//&&!/SWAP/{print $1,$1}'

Dunno about whiptail, but it would probably be nice to know the label and filesystem for the selection?
(nc dialog allows to carry values different from the label for the selection)

Offline

#3450 2021-01-04 22:04:49

Head_on_a_Stick
Member
From: London
Registered: 2014-02-20
Posts: 5,838
Website

Re: Post your handy self made command line utilities

Trilby wrote:

what's with all the function names starting with underscores?

I wanted to use "chroot" as a function name so I prefixed an underscore so it wouldn't clash with the actual command. I don't actually know which would be preferred in such a situation, I suppose I really should check but I'm tired now. Anyway, once I had one function with an underscore the rest had to have them too. Obviously smile

seth wrote:

it would probably be nice to know the label and filesystem for the selection?

Yes, that's a good idea. I was just focused on getting the options working — this is my first time with whiptail.

Offline

Board footer

Powered by FluxBB