You are not logged in.

#3026 2017-05-26 18:05:23

adam_danischewski
Banned
Registered: 2016-05-06
Posts: 23
Website

Re: Post your handy self made command line utilities

Eschwartz wrote:
adam_danischewski wrote:

If you need to copy things to multiple locations:

alias cpm='_() { src="${1%/}"; shift; printf "\"%s\" " "$@" | xargs -n 1 cp -vR "${src}"; }; _' 

Why not just use a function "cpm()" directly???

Force of habit - you can break it out and run it as a function cpm(). I've been using aliases for a long time and I have utilities built for handling and pulling data from my aliases file that I don't need/want to change at the moment.

$> mkdir -p /tmp/test;cd /tmp/test;cpm(){ src="${1%/}"; shift; printf "\"%s\" " "$@" | xargs -n 1 cp -vR "${src}";}
$>touch file.txt;mkdir -p {a..d}
$>cpm file.txt {a..d} 
‘file.txt’ -> ‘a/file.txt’
‘file.txt’ -> ‘b/file.txt’
‘file.txt’ -> ‘c/file.txt’
‘file.txt’ -> ‘d/file.txt’

Offline

#3027 2017-05-26 18:49:41

eschwartz
Fellow
Registered: 2014-08-08
Posts: 4,097

Re: Post your handy self made command line utilities

Also, no need for all that xargs and printf clutter. And, why are you stripping dirnames from the source file -- is this specifically meant to fail in an unidentified manner when copying things that aren't located in cwd?

cpm() {
    local i
    for i in "${@:2}"; do
        cp -vR "$1" "$i"
    done
}

Last edited by eschwartz (2017-05-26 18:50:22)


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

Offline

#3028 2017-05-26 19:37:15

adam_danischewski
Banned
Registered: 2016-05-06
Posts: 23
Website

Re: Post your handy self made command line utilities

Eschwartz wrote:

Also, no need for all that xargs and printf clutter

cpm() {
    local i
    for i in "${@:2}"; do
        cp -vR "$1" "$i"
    done
}

No need for loops, when you have the elegance of xargs. smile

Offline

#3029 2017-05-26 20:13:34

eschwartz
Fellow
Registered: 2014-08-08
Posts: 4,097

Re: Post your handy self made command line utilities

I'd say handling it in pure bash is more elegant than shelling out for no good reason. Especially when you then have to printf and format argv all over again over stdin, using comparatively arcane escaping (whereas bash knows how to expand and tokenize "$@" natively).

xargs is a useful tool in a scripter's arsenal, not some sort of goal in and of itself. Using xargs does not win you internet points for elegance...

Last edited by eschwartz (2017-05-26 20:15:08)


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

Offline

#3030 2017-05-28 02:11:35

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

Re: Post your handy self made command line utilities

Been having "shutdown sickness" lately*. It seems to be by design. I'd rather not wait until every desktop application in development is updated to play nice with systemd.

Found this neat idea and expanded on it:

#!/bin/bash

#Reboot or shutdown
[[ "${1}" == "reboot" || "${1}" == "-r" ]] && SEQUENCE=(s u b)
[[ "${SEQUENCE}" ]] || SEQUENCE=(s u o)

for i in "${SEQUENCE[@]}"; do sleep 3; printf "${i}" > /proc/sysrq-trigger; done

Is three seconds long enough?

*"Shutdown sickness" is how I have been describing this symptom (extremely delayed shutdown) since I first encountered it, in Windows 95.

::EDIT::
Bonus: Get the total size of all installed software package files (in GiB):

printf "$(echo "$(TOTAL=0; for i in $(pacman -Qi | grep "MiB" | sed 's/[^0-9,.]*//g' | xargs -n1); do TOTAL="$(echo ${i}+${TOTAL} | bc)"; done;  echo "scale=2;${TOTAL}/1024" | bc)+$(TOTAL=0; for i in $(pacman -Qi | grep "KiB" | sed 's/[^0-9,.]*//g' | xargs -n1); do TOTAL="$(echo ${i}+${TOTAL} | bc)"; done;  echo "scale=2;${TOTAL}/1024/1024" | bc)" | bc) GiB\n"

Has this been done before? I hope there's a more efficient way.

>9.35 GiB!

Last edited by quequotion (2017-05-28 10:21:19)

Offline

#3031 2017-05-28 10:50:44

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

Re: Post your handy self made command line utilities

There is definitely a more efficient way - that is a ridiculous number of pipes, subshells, and repeated xargs, bc, grep calls.  There are many incremental simplifications that can be made, but why not just sum the sizes directly:

awk '/%SIZE%/ {getline; size+=$1; } END { print size / (1024 * 1024) " MiB"; }' /var/lib/pacman/local/*/desc

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

Offline

#3032 2017-05-28 11:54:00

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

Re: Post your handy self made command line utilities

Trilby wrote:
awk '/%SIZE%/ {getline; size+=$1; } END { print size / (1024 * 1024) " MiB"; }' /var/lib/pacman/local/*/desc

Marvelously shorter, and more accurate (pacman -Qi's output is approximate). One more "* 1024" for GiB:

awk '/%SIZE%/ {getline; size+=$1; } END { print size / (1024**3) " GiB"; }' /var/lib/pacman/local/*/desc

Last edited by quequotion (2017-05-28 12:18:00)

Offline

#3033 2017-05-28 14:16:25

Ropid
Member
Registered: 2015-03-09
Posts: 1,069

Re: Post your handy self made command line utilities

Following the original idea about going through "pacman -Qi", that could have been done more efficient like this:

pacman -Qi | 
sed -nr '/^Installed Size *: / { s///; s/ //; s/B$//; p }' | 
numfmt --from=auto --format=%.0f | 
awk '{ total += $1 } END{ print total }' | 
numfmt --to=iec-i --format=%.2f --suffix=B

Offline

#3034 2017-05-28 15:16:08

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

Re: Post your handy self made command line utilities

If you're going to parse pacman output and use awk anyways, then sed serves no purpose - neither does numfmt really:

pacman -Qi | awk '/Installed Size/ { sum[$5]+=$4; } END { print sum["MiB"] + sum["KiB"] / 1024; }'

I left off the printing of sum["B"] as it would be divided by 1024^2 and not provide any change in the displayed number.  I've also left out sum["GiB"] as I don't know of any packages with GiB installed sizes, but they may exist - this could be added to the print (sum["GiB"] * 1024 ...)


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

Offline

#3035 2017-05-28 15:50:05

Ropid
Member
Registered: 2015-03-09
Posts: 1,069

Re: Post your handy self made command line utilities

The solution with the sed + numfmt + awk + numfmt actually seems faster here for me. Nearly all of the time disappears into "pacman -Qi" anyways, but I also tried it with pacman's output saved into a file to test just awk etc.:

$ pacman -Qi > pacman.txt

$ time { for x in {1..100}; do <pacman.txt awk '/Installed Size/ { sum[$5]+=$4; } END { print sum["MiB"] + sum["KiB"] / 1024; }'; done; }
...
11597.9
11597.9
11597.9

real	0m0.727s
user	0m0.699s
sys	0m0.051s

$ time { for x in {1..100}; do <pacman.txt sed -nr '/^Installed Size *: / { s///; s/ //; s/B$//; p }' |  numfmt --from=auto --format=%.0f |  awk '{ total += $1 } END{ print total }' |  numfmt --to=iec-i --format=%.2f --suffix=B; done; }
...
11.33GiB
11.33GiB
11.33GiB

real	0m0.628s
user	0m0.964s
sys	0m0.070s

Looking at that result, I guess it's somehow faster here because it's using more than one CPU core?

About the "GiB", I do have a package "ghc" that's 1.1G, but pacman prints it as 1146.92 MiB.

Last edited by Ropid (2017-05-28 15:52:56)

Offline

#3036 2017-05-28 20:08:39

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

Re: Post your handy self made command line utilities

So, you get a performance increase of hardly more than a measuring error for a code line that's twice as long and 10 times harder to understand. Not a great deal.


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

Offline

#3037 2017-05-28 22:02:55

Ropid
Member
Registered: 2015-03-09
Posts: 1,069

Re: Post your handy self made command line utilities

I think it will actually all run the same in reality because your stuff will get run in parallel to "pacman -Qi" doing its thing. What's best depends on the person, I guess. I wouldn't have come up with that hash thingy for awk by myself to deal with the MiB and KiB, but I used numfmt before and have practice with regex.

Offline

#3038 2017-05-29 05:17:03

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

Re: Post your handy self made command line utilities

Ropid wrote:

Following the original idea about going through "pacman -Qi", that could have been done more efficient like this:

pacman -Qi | 
sed -nr '/^Installed Size *: / { s///; s/ //; s/B$//; p }' | 
numfmt --from=auto --format=%.0f | 
awk '{ total += $1 } END{ print total }' | 
numfmt --to=iec-i --format=%.2f --suffix=B

At first I used "pacman -Qi" because It didn't occur to me to access the database directly as Tribily demonstrated; it seemed logical to get this information from pacman. Unfortunately pacman provides numbers in various units {KiB,MiB} and rounds to two decimal places. Getting the size in bytes from the database is more precise and, by not loading the whole database, probably more efficient--but I'm curious if the calculations may actually take longer than using the rounded numbers provided by "pacman -Qi"

Ideally I would have pacman offer the size in bytes, or at least consistent units, and be able to write a more simple script for "pacman -Qi", or add functionality  to pacman to output the total itself, because I like the idea of getting this information from the package manager executable; but I'm not about to fork pacman (again) over it smile

Offline

#3039 2017-05-29 05:40:38

jasonwryan
Anarchist
From: .nz
Registered: 2009-05-09
Posts: 30,424
Website

Re: Post your handy self made command line utilities

This would probably be much better handled by expac.


Arch + dwm   •   Mercurial repos  •   Surfraw

Registered Linux User #482438

Offline

#3040 2017-05-29 07:16:11

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

Re: Post your handy self made command line utilities

jasonwryan wrote:

This would probably be much better handled by expac.

$ expac -Q '%m' -H M | datamash -W sum 1
1972.25

Note: the "exact" value is 1972.298828125, which can be retrieved by removing the -H option and dividing by 1024^2.

Last edited by Alad (2017-05-29 07:21:30)


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

Offline

#3041 2017-05-29 10:19:38

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

Re: Post your handy self made command line utilities

My version from post 3031 is still consistently faster than the expact approach for me (though I fully agree parsing pacman output like the above approaches is silly, that is what expac is for).


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

Offline

#3042 2017-05-29 10:50:30

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

Re: Post your handy self made command line utilities

Yeah, expac is fairly slow on the first run (before things are cached). A concern when using it in scripts - for me at least - but for interactive use the shortness is nice. One less alias to define...

Last edited by Alad (2017-05-29 10:53:05)


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

Offline

#3043 2017-05-31 11:01:24

Ambrevar
Member
Registered: 2011-08-14
Posts: 212
Website

Re: Post your handy self made command line utilities

I would like a shell command to print the date of various locations around the world, similar to Emacs' display-time-world.

I've come up with this POSIX shell script:

#!/bin/sh

set -- \
	UTC UTC \
	Europe/Paris "France Germany" \
	Asia/Calcutta India \
	etc. ...

while [ $# -gt 0 ]; do
	date=$(TZ="$1" date)
	printf "%s\t%s\n" "$date" "$2"
	shift 2
done

Am I re-inventing the wheel? Anything simpler?

Last edited by Ambrevar (2017-05-31 11:07:01)

Offline

#3044 2017-05-31 11:44:46

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

Re: Post your handy self made command line utilities

Not sure if there's an existing wheel being reinvented, but you could avoid the subshells:

...
while [ $# -gt 0 ]; do
   TZ="$1" date "+%a %b %d %R:%S %Z %Y%t$2"
   shift 2
done

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

Offline

#3045 2017-05-31 17:33:43

Ambrevar
Member
Registered: 2011-08-14
Posts: 212
Website

Re: Post your handy self made command line utilities

True, and even simpler:

	TZ="$1" date "+%c%t$2"

I just realized however that date prints in a format different from %c, i.e. it does not respect my locale.

> date
Wed May 31 18:30:57 CET 2017
> date +%c
Wed 31 May 2017 06:31:00 PM CET

Is this the expected behaviour?

Offline

#3046 2017-05-31 18:40:17

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

Re: Post your handy self made command line utilities

I was thinking about suggesting "+%c%t$2" but it is a different format.  Both `date` and `date +%c` should respect locale, and both of your outputs are in the same locale, they are just different formats (different order of information and one on 24-hour one on 12).

Although, I suppose while my format string is equivalent to the default in every case I can find, it is not the identical format string according to the `info` page.  It should be "+%a %b %e %H:%M:%S %Z %Y%t$2" if LC_DATE is not set.


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

Offline

#3047 2017-06-01 15:44:24

Ambrevar
Member
Registered: 2011-08-14
Posts: 212
Website

Re: Post your handy self made command line utilities

Thanks for digging out the details!

Offline

#3048 2017-06-12 00:37:50

leo_gott82
Member
Registered: 2016-08-29
Posts: 20
Website

Re: Post your handy self made command line utilities

Since I prefer to use the mouse as little as possible, I wrote this lil' script (depends on wmctrl and xdotool) to handle windows directly through the keyboard. In this way, you only have to press a few keys in order to iconify, unminimize or close a running window. Hope it'll be useful for some of you. Feel free to modifiy or add whatever you want, for instance, a maximize function (didn't do it myself 'cause I don't like maximized windows).

#!/bin/bash
#Little window manager that allows you to perform basic operations on windows
#It depends on wmctrl and xdotool

###Colors####
red="\033[1;31m"
green="\033[1;32m"
yellow="\033[1;33m"
blue="\033[1;34m"
magenta="\033[1;35m"
cyan="\033[1;36m"
d_cyan="\033[0;36m"
white="\033[1;37m"
d_white="\033[0;37m"
nc="\033[0m"

function help ()
{
   clear
   echo -e "${cyan}              LilWinMan 1.1 (2016)$nc\n"
   echo -e "LilWinMan doesn't take arguments, but works only interactively."
   echo -e "${white}Usage: $nc"
   echo -e "Type the number of the listed window followed by the key identifyng the action you \
want to perform over the selected window."
   echo -e "Action keys are: \n'${yellow}i$nc' - ${white}iconify$nc \n'${yellow}u$nc' - ${white}unminimize$nc or raise a window\n'${yellow}c$nc' - ${white}close$nc \
gracefully \n'${yellow}k$nc' - ${white}kill$nc a window"
   echo -e "E.g.: '${yellow}3 c$nc' will close the third listed window"
   echo -e "The program also allows you to ${white}run a command$nc instead of managing some opened window. \
For instance, if you want to open the IceApe web browser, you simply has to type 'iceape', press enter, and \
IceApe will show up.\nTo show this ${white}help$nc type '${yellow}h$nc' or '${yellow}help$nc'."
   read -n1 -r -p "Press any key to continue..." key && clear
   return
}

function show_windows ()
{
   mapfile -t windows < <(wmctrl -lp | awk '{$2=$3=$4=""; print $0}' | sed 's/  / /g')
   for (( i=0;i<${#windows[@]};i++)); do
      ###print only the win_name
      #Tell LilWinMan not to display its own window
      if ! [[ ${windows[$i]} == *"LilWinMan" ]]; then
         ##get window's state
         state="$(xprop -id $(echo "${windows[$i]}" | awk '{print $1}') | grep "window state" | awk '{print $3}')"
         if [[ $state == "Iconic" ]]; then
            echo -e "${d_white}$((i+1)) - ${d_cyan}$(echo "${windows[$i]}" | awk '{$1=""; print $0}' | sed 's/  / /g')$nc"
         else
            echo -e "${white}$((i+1)) - ${cyan}$(echo "${windows[$i]}" | awk '{$1=""; print $0}' | sed 's/  / /g')$nc"
         fi
      fi
   done
   ##Display possible actions###
   echo -ne "\n${white}Usage:$nc\nwindow_id ${yellow}[i]${nc}conify, ${yellow}[u]${nc}nminimize, ${yellow}[c]${nc}lose, ${yellow}[h]${nc}elp: "
   ##save input in an array: first arg is win number, the second is action###
   read -a input
   case ${input[0]} in
     q|quit|exit) exit 0;;
     h|help) help && show_windows;;
     #if input is not a number...
     *) ! [[ ${input[0]} =~ ^-?[0-9]+$ ]] && eval ${input[@]} 2>/dev/null && exit 0;;
     #eval allows you to take the content of a variable and run it as a command
     #Note: whenever the command run by eval fails (or it doesn't exist), the error is displayed 
     #in the screen, the exit command never happens, and therefore the script goes on to the next
     #condition (line 47), and then to the next (line 49), where it fails and exits. 
     #Note2: the workaround was to repeat (in line 45) the condition that tests whether input is 
     #a number (line 37) after the case sentence.
   esac
}

show_windows
#if not a number...
! [[ ${input[0]} =~ ^-?[0-9]+$ ]] && echo -e "${red}Program doesn't exist!$nc" && sleep 1.4 && exit 0
#if a number, check whether it's not greater than the total amount of windows
[[ "${input[0]}" -gt "${#windows[@]}" ]] && echo -ne "${red}Invalid window!$nc" && sleep 1.3 && exit 0
###check if second argument has been passed
[[ -z ${input[1]} ]] && echo -e "${white}You must specify an action.$nc" && sleep 1.5 && exit 0
###save the win_id
win_id=$(echo "${windows[$((input[0]-1))]}" | awk '{print $1}')
###read the second argument and run the corresponing command##
case ${input[1]} in
   #neither wcmtrl now xdotool by themselves are able to iconify (minimize) a window neither by 
   #name nor by id, so that the workaround is to first unminimize the window to be minimized with
   #wmctrl and then to minimize the active window with xdotool 
   i) wmctrl -ia $win_id && xdotool getactivewindow windowminimize;;
   u) wmctrl -ia $win_id;;
   c) wmctrl -ic $win_id;;
   #k option should be used only when the window doesn't respond and cannot be gracefully closed.
   #Don't list this option in screen, but only in help.
   k) wmctrl -ia $win_id && xdotool getactivewindow windowkill;;
   *) echo -e "${red}Wrong option!$nc" && sleep 1.4 && exit 0
esac
exit 0

It could be a good idea to call this script (as an argument for a terminal) with a keyboard shortcut. In Openbox, it would be something like this:

    <keybind key="C-x">
      <action name="Execute">
        <command>aterm -name "LilWinMan" -title "LilWinMan" -geometry 50x18+430+120 -e /path/to/the/script</command>
      </action>
    </keybind>

Btw, this thread rocks! Thank you all.

Last edited by leo_gott82 (2017-06-12 00:57:51)


Der Mensch weiss nur von  Gott, insofern Gott im Menschen von sich selbst weiss.' (Hegel)

Offline

#3049 2017-08-01 11:54:37

xyproto
Package Maintainer (PM)
From: Oslo
Registered: 2011-01-11
Posts: 43
Website

Re: Post your handy self made command line utilities

Here's a small utility I wrote for detecting which version of GCC (or FPC or OCaml) that was used for compiling an ELF executable.

It also works for stripped executables and it can detect the architecture and little endian/big endian order.

elfinfo.png

Example:

$ elfinfo /usr/bin/ls
/usr/bin/ls: stripped=true, compiler=GCC 6.3.1, byteorder=LittleEndian, machine=Advanced Micro Devices x86-64

Homepage: ELFinfo
Latest release: elfinfo-0.5.tar.xz
AUR package: elfinfo

Offline

#3050 2017-08-08 01:35:53

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

Re: Post your handy self made command line utilities

My alarm clock is annoying. It makes an annoying sound that my unconscious mind just wants to stop, so I tend to hit the snooze after partially waking up, but not enough to actually get up. It has a 9-minute snooze, which apparently is just a terrible thing for my sleep cycle or something.

Turns out my computer makes a better alarm clock. These scripts can definitely use some polish, but I've been waking up earlier, feeling much more rested.

#!/usr/bin/env rc
# ~/local/bin/alarmclock: wake the computer up at the given time,
# defaulting to 5:55 a.m.

if (~ $#1 0) {
	when='tomorrow 5:55'
}
if not {
	when=$1
}

sudo rtcwake -m mem -t `{u date +%s -d $when} && alarm
#!/usr/bin/env rc
# alarm: pick a random song and start playing it quietly, getting
# louder over time

# Pick & play a random album.
# The random selector almost never fails, so even one retry-on-fail
# should mean it always works.
mpc randalbum || mpc randalbum || mpc randalbum

# In case it comes up with a really short one
mpc repeat on

# ALSA's way of denoting volume is *weird*. amixer's 50% = alsamixer's 23
amixer set Master 50%

# FIXME: testing for a file is a stupid way to reclaim control
# of the volume without stopping the music.
while (test ! -f /tmp/stop && mpc status | grep playing) {
	amixer set Master 1+
	sleep 120
}

Offline

Board footer

Powered by FluxBB