You are not logged in.
I coded a CLI tool in C. With it you can manage all systemd units very comfortable with a TUI. You can select units with up / down, hit Enter to display all status information and use the F -keys to start, stop, restart, enable, disable, mask, unmask and reload the unit. After every operation, the daemon reloads and updates the display. The compiled executable is only some kilobytes, but the source code is 1561 lines long. I don't know if I can paste the source code here.
But if you like, you can get the source and also a compiled binary on my GitHub page.
My username:Lennart1978 the tool is called "servicemaster".
Today I updated to version 1.1 and it works very well.
All you need: systemd-libs and ncurses (Most likely this is already installed)
It's always great when someone else has use for it. It was a lot of work for me, I'm just a hobby programmer, not a professional.
Ich weiß, dass ich nichts weiß !
Offline
I coded a CLI tool in C. With it you can manage all systemd units very comfortable with a TUI. You can select units with up / down, hit Enter to display all status information and use the F -keys to start, stop, restart, enable, disable, mask, unmask and reload the unit. After every operation, the daemon reloads and updates the display. The compiled executable is only some kilobytes, but the source code is 1561 lines long. I don't know if I can paste the source code here.
But if you like, you can get the source and also a compiled binary on my GitHub page.My username:Lennart1978 the tool is called "servicemaster".
Today I updated to version 1.1 and it works very well.
All you need: systemd-libs and ncurses (Most likely this is already installed)It's always great when someone else has use for it. It was a lot of work for me, I'm just a hobby programmer, not a professional.
Offline
ServiceMaster release version 1.3:
- DBus event loop: Reacts immediately to external changes to units
- Fixed some small bugs
Ich weiß, dass ich nichts weiß !
Offline
This is a comically long one-liner I keep in my .profile for PDF merging.
pdfmerge() { if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then echo "Usage: pdfmerge MERGED PDF1 PDF2"; echo "Merge PDF1 and PDF2 into MERGED"; return 0; else if [ "$#" != 3 ]; then echo "pdfmerge: bad usage"; echo "Try 'pdfmerge --help' for more information"; return 1; fi; gs -qo -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -o $@; fi }
Some of my classes require PDF submissions with both computer-generated output and scans of handwritten solutions, so I use this to quickly merge the two. It doesn't have perfect error checking, but it's just enough for me to remember how to use it when I do use it once every one or two weeks or so.
I suspect it may be wise to un-one-liner it at some point.
Astrophysicist and programmer. I like simple things.
Offline
Here you go:
# original
pdfmerge() {
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
echo "Usage: pdfmerge MERGED PDF1 PDF2"
echo "Merge PDF1 and PDF2 into MERGED"
return 0
else
if [ "$#" != 3 ]; then
echo "pdfmerge: bad usage"
echo "Try 'pdfmerge --help' for more information"
return 1
fi
gs -qo -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -o $@
fi
}
# simplified
pdfmerge() {
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
echo "Usage: pdfmerge MERGED PDF1 PDF2"
echo "Merge PDF1 and PDF2 into MERGED"
return 0
fi
if [ "$#" != 3 ]; then
echo "pdfmerge: bad usage"
echo "Try 'pdfmerge --help' for more information"
return 1
fi
gs -qo -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -o $@
}
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
You're right! With the returns there I don't need the extra else. Thanks! More proof comically long one-liners are a bad idea.
Astrophysicist and programmer. I like simple things.
Offline
Lazy:
pdfmerge() {
[ "$#" = 3 ] && echo gs -qo -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -o "$@" && return 0
echo "Usage: pdfmerge MERGED PDF1 PDF2"; return 1
}
(though nb. the quoted "$@")
Online
I don't think quoting it would work as desired since it would treat the three items as a single argument to -o though, right? That might work anyhow but I haven't tested and I don't know if that would necessarily work.
Astrophysicist and programmer. I like simple things.
Offline
it would treat the three items as a single argument to -o
Source this:
foo(){
echo $#
}
bar(){
foo "$@"
}
then run
bar 1 2 3
bar "1 2" 3
Then test
Source this:
foo(){
echo $#
}
bar(){
foo $@
}
bar 1 2 3
bar "1 2" 3
Notice a difference?
Online
Yeah, as expected when it's quoted it treats the quoted object as one, but when it's unquoted it treats it as two space separated objects.
I guess my brain isn't seeing why that is desirable behavior here.
Astrophysicist and programmer. I like simple things.
Offline
"1 2" are one parameter, not two.
You want 'bar 1 2 3' to print "3" and 'bar "1 2" 3' to print '2'
Do you get that when not quoting $@ ?
The relevant condition is if the filenames you're passing contain spaces.
Online
Ah, that's why I didn't think of it, I tend not to use spaces in filenames. Thanks. O7
Astrophysicist and programmer. I like simple things.
Offline
Using QEMU/KVM a lot recently to test ISO images so I wrote these two functions for my shell RC file:
function vinst {
if [ $# != 2 ] ; then
echo 'Usage vinst $iso $disk'
else
qemu-system-x86_64 \
-enable-kvm \
-m 4G \
-device virtio-vga-gl \
-display sdl,gl=on \
-machine q35 \
-device intel-iommu \
-cpu host \
-audiodev alsa,id=snd0 \
-device ich9-intel-hda \
-device hda-output,audiodev=snd0 \
-drive if=virtio,format=raw,cache=none,file="$2" \
-nic user,model=virtio-net-pci \
-cdrom "$1" \
-boot d
fi
}
function vrun {
qemu-system-x86_64 \
-enable-kvm \
-m 4G \
-device virtio-vga-gl \
-display sdl,gl=on \
-machine q35 \
-device intel-iommu \
-cpu host \
-audiodev alsa,id=snd0 \
-device ich9-intel-hda \
-device hda-output,audiodev=snd0 \
-drive if=virtio,format=raw,cache=none,file="$1" \
-nic user,model=virtio-net-pci
}
`vinst` is for testing live ISO images and installing, it accepts the ISO image name and the target disk image as arguments, `vrun` is for running the installed system and accepts the disk image name.
Last edited by Head_on_a_Stick (2024-09-25 10:10:40)
Para todos todo, para nosotros nada
Offline
Just as a few posts before, that'd be cleaner without the else block (I also replaced the string comparison with numeric comparison:
vinst() {
if [ $# -ne 2 ]; then
echo 'Usage vinst <iso> <disk>'
return 1
fi
qemu-system-x86_64 \
# ...
}
Last edited by Trilby (2024-09-25 13:21:30)
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
^ Thanks!
EDIT: these boards have an excellent linting service
Last edited by Head_on_a_Stick (2024-09-25 13:05:10)
Para todos todo, para nosotros nada
Offline
My pdf management script
#!/bin/bash
## read below file for details of qpdf usage
# /usr/share/doc/qpdf/qpdf-manual.pdf
#
#
# TRY PDFTRICKS for gui
echo -n "
choose option
m) merge pdf files
e) extract pages from pdf
p) image to pdf
l) libreoffice document to pdf
v) djvu to pdf
d) remove password (decrypt)
b) get and edit metadata ( including bookmarks )
r) rotate pages
s) optimize for size
x) exit
#? "
# d) delete pages from pdf (untested)
read ops
case $ops in
m) echo "which files to merge?"
read -a IN
echo -n "provide name for output file:"
read OUT
# pdfunite ${IN[@]} $OUT.pdf
pdftk ${IN[@]} cat output $OUT.pdf
;;
p) echo "which image files to convert? e.g., *.jpg"
read -a IN
echo -n "provide name for output file:"
read OUT
# convert "${IN[@]}" $OUT.pdf
img2pdf --output $OUT.pdf ${IN[@]}
;;
l) echo "which document files to convert? e.g., *.odt"
read -a IN
# echo -n "provide name for output file:"
# read OUT
libreoffice --headless --convert-to pdf "${IN[@]}"
;;
v) echo "which djvu file to convert?"
read -a IN
OUT="`basename $IN .djvu`"
OUT="$OUT".pdf
ddjvu -format=pdf -quality=85 -verbose $IN $OUT ;;
s)
echo "which pdf file to modify?"
read -a IN
echo -n "provide name for output file:"
read OUT
# ebook=150dpi, screen=72dpi, printer=300dpi, default=largesize
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dNOPAUSE -dQUIET -dBATCH -sOutputFile="$OUT" "$IN"
;;
e) echo -n "name the pdf file to extract images from:"
read IN
echo -n "first page to extract:"
read FIRST
echo -n "last page to extract:"
read LAST
echo -n "provide name for output file:"
read OUT
# pdfseparate -f $FIRST -l $LAST $IN $OUT%d
pdftk $IN cat $FIRST-$LAST output $OUT.pdf
# pdfunite $(echo $OUT*) $OUT.pdf
;;
r) echo -n "name the pdf file to rotate pages:"
read IN
echo -n "angle of rotation, +90 -90" # left,right,north,south etc with pdftk
read ANGLE
echo -n "first page to rotate:"
read FIRST
echo -n "last page to rotate:"
read LAST
echo -n "provide name for output file:"
read OUT
qpdf --rotate=$ANGLE:$FIRST-$LAST $IN $OUT.pdf
# pdftk $IN rotate $FIRST-$LAST$ANGLE output $OUT.pdf
;;
d) echo -n "Which pdf file to decrypt (without .pdf) ?"
read FILE
echo -n "Original password ?"
read PASS
qpdf --password="$PASS" --decrypt $FILE.pdf $FILE.decrypted.pdf
# pdftk $FILE.pdf input_pw "$PASS" output $FILE.decrypted.pdf
;;
b) echo -n "Which pdf file (without .pdf) ?"
read FILE
pdftk $FILE.pdf dump_data output $FILE.txt
echo "metadata dumped to $FILE.txt"
echo "kindly edit the metadata and enter y to proceed"
read reply
[[ $reply = y ]] && pdftk $FILE.pdf update_info $FILE.txt output $FILE.bookmarked.pdf
;;
# d) echo " example command to remove page 21
# pdftk $FILE.pdf cat 1-20 22-end $FILE_edited.pdf" ;;
x) exit
;;
esac
Arch is home!
https://github.com/Docbroke
Offline
When I moved from Ubuntu to Arch the pc no longer "saves" in any form any screen inversion nor brightness, display calibration. Once I adjust anything, the setting was lost and gone. So I had to write the script that reapply the settings every time any adjustment is made
One screen fits one pc "adjustall" that auto runs every time I login. Overall it kept the last screen settings except brightness, which is hardcoded in the auto run.
It receives the brightness value via command line with some input checking. Max brightness is 1 and min brightness is 0 if there is no error check. Anything brighter or dimmer xrandr will accept the value but you risk nor being able to see anything on the screen at all
#!/bin/bash
# Program to adjust screen brightness and display color
# Reads file isinvert to re-invert the screen if the screen was color inverted beforehand
# rgb 255, 242, 250 0.92117 0.949019 0.98039812
brightValue=$(echo "scale=0;(${1}*1000)/1" | bc)
#echo $brightValue
if [ $brightValue -lt 240 ]; then # bright value is lower than 0.24
echo 'a screen too dim is bad for your eyes'
exit 1
fi
if [ $brightValue -gt 1100 ]; then # bright value is higher than 1.1
echo 'Excessive Brightness Detected'
exit 1
fi
xrandr --output eDP-1 --brightness "${1}" &> /dev/null
xcalib -red 1 1.0 97.0 -green 1 1.0 94.0 -blue 1 1.0 98.0 -a &> /dev/null
# if the screen was is inverted reapply the modification
isinvert=$(cat /home/js/isinvert)
if [ $isinvert = 'true' ]; then
xcalib -i -a &> /dev/null
else
echo $isinvert &> /dev/null
fi
#--gamma '0.9686275:0.9411765:0.9803529168'
Invert screen and save the settings to a text file
#!/bin/bash
isinvert=$(cat /home/js/isinvert)
if [ $isinvert = 'true' ]; then
echo $isinvert
echo 'false' > ~/isinvert
else
echo 'true' > ~/isinvert
fi
# invert all colors of the screen
xcalib -i -a &> /dev/null
isinvert - The file storing the invert option, either being true or false
true
Last edited by lvsl (2024-12-06 22:42:10)
Offline
This is a slightly more convenient way to tabulate the permissions of every file in a directory (at least if you like octal permissions):
/usr/local/bin/listperm:
#!/bin/bash
if [ $# -eq 3 ]; then
find "$1" -type "$2" -perm "$3" 2> /dev/null
elif [ $# -eq 2 ]; then
find "$1" -type "$2" -exec stat -c %a {} + 2> /dev/null | sort | uniq -c
else
echo "Wrong number of arguments."
fi
Running "listperm . f" will get you a tabulated list of the permissions of every regular file in the current directory. If you find a single file with odd permissions like 711 and want to know what it is, then "listperm . f 711" will get you that.
And here is a silly, very hacky pacman hook for forcing Discord to fully update itself (I use a more complicated version of this that accounts for betterdiscord injection as well as moving the .pki dotfile elsewhere).
/usr/local/bin/discordupdate.sh:
#!/bin/bash
isdiscordrunning="`ps ax | awk '$5 ~ /\/opt\/discord\/Discord/' | wc -l`"
isdisplayrunning="`ps ax | awk '$5 ~ /\/usr\/lib\/Xorg/' | wc -l`"
if [ "$isdisplayrunning" != "0" ] ; then
sudo -u USERNAME killall Discord;
sudo -u USERNAME discord --help &> /dev/null;
if [ "$isdiscordrunning" != "0" ] ; then
sudo -u USERNAME sh -c 'echo "" >> /tmp/discordstatus'
fi
fi
Note that you need a filesystem watcher (inotifywait/entr/etc.) to monitor the /tmp/discordstatus file and start discord if it changes. Obviously replace the Xorg path with a Wayland one if you use that. It works because if you pass discord a commandline option it doesn't understand (like --help), it fully updates and then immediately crashes.
Offline
@mesaprotector
find . -printf "%4m : %f\n"
find . -printf "%4m | column\n"
sort -u
pgrep Xorg && killall Discord && echo "" >> /tmp/discordstatus && sudo -u USERNAME discord --help &
@lvsl
if (( brightValue < 240 )) …
zsh btw. does floating point arithmetic no problem (I had to check that bash actually doesn't before simplyfing this too much
#!/bin/bash
# invert all colors of the screen or exit with error
xcalib -i -a &> /dev/null || exit 1
# no cat abuse, https://porkmail.org/era/unix/award#cat
read isinvert < ~/.isinvert
#flip
$isinvert && isinvert=false || isinvert=true
# and write
echo $isinvert > ~/.isinvert
Online
@seth
Firstly thank you. I really wasn't expecting somebody who could comment on my programming skills for ways that I can improve. When I learned programming I didn't have the capacity to view other people's code. So I pretty much just search for books from the net and figure out how things work on my own.
The "cat" abuse:
The reply took longer than expected. But the website you've provided were good read, even though I don't totally agree with that view. What I have read there was if I am correct, the added layer for cat to receive stdin and then just throw stdin as stdout, and therefore wasting an extra process doing something that is entirely useless. I don't quite get there is the reason why it is a very major concern (if you dont mind can you explain more on that?). But the alternative syntax you've provided suggested some quite good use of the redirect arrow, which I was previously not familiar with. And that is all great.
zsh:
I haven't got zsh on my computer but later I will go try it. Last time when I checked on my Arch it wasn't installed. But same as bc, I think that one doesn't come with the Arch core package for the same reason. Just like how vi, vim, which, file, rsync and many others doesn't come bundled neither.
The logical operators:
Although I haven't see it to be used to flip value in bash. I have seen similar use in some other programming language I have learned such as
value = value == true? false : true;
value == "a" && return 0;
The flip one though it seems to assign and return values at the same time. You saved me many lines of code. But it took me some guesses to figure out what it might be doing.
Really. Thank you very much. I really appreciate your help.
Offline
I don't quite get there is the reason why it is a very major concern
It's not. It's "bad" style.
You can also run into trouble if "cat" isn't /usr/bin/cat but some alias or symlink to bat etc et pp. so we just sidestep this by never using cat for things it's not meant to.
That being said:
◉ type pastebin
pastebin is an alias for curl -F 'file=@-' 0x0.st | tee >(xsel -i 2>/dev/null) >(qrencode -t ANSIUTF8 2>/dev/null)
and although curl can perfectly post files that are not stdin, I use only that one alias and cat files into it.
But that's for convenience - I'd not use that in a script.
Online
While we are trying to not skin more cats you can save a binary state in the filesystem by just checking whether a file exists.
if mkdir $HOME/.isinverted > /dev/null
then
echo "Inverted"
else
echo "Not inverted"
fi
mkdir is used to atomically create a file to protect against race conditions.
Offline
@seth:
Your explanation makes sense. I didn't consider alias or symlinks or other factors. There's a saying that it means - if you have one thing you are only troubled by that one thing. But having two means twice the trouble.
While we are trying to not skin more cats you can save a binary state in the filesystem by just checking whether a file exists.
if mkdir $HOME/.isinverted > /dev/null then echo "Inverted" else echo "Not inverted" fi
mkdir is used to atomically create a file to protect against race conditions.
I think you got the wrong idea as only me will ever modify the file and the other script will only ever read it. There is nothing at all that need to be "locked". The concept of something needs to be "locked" came from the idea when someone or a program/package-manager like pacman is working with a file or a system, there will only be that one person/program working on it and nobody else. And when the person is done, the lock dissapears. Anyone else can go read the file to their hearts content, doesn't matter if the lock exist or not.
And I'm the only person here. The only file here that will modify isinvert is a file that inverts the screen color. Nothing else. Re-read the scripts, or try drawing a diagram about the relationships between the three files there. There's no race condition here and every thing in the script, other than it being ran only *once* when I login, is triggered by me and nothing else.
Once you drew the diagram I am sure things will clear up for you, and it will help you in your computer journey and you can be better and get more focus on your task, and only that task, without getting sidetracked from time to time. By the way, unlike other people in the forum, I am one of the most untalented type of people who got no idea how to program, how to use linux with a command line properly, and got only enough expertise to start windows, installing drivers by hand by searching websites, and is hopeless in any programming language. So I knew how it feels like getting sidetracked by things that are not important. My mind jumped from place to place, having all sorts of ideas coming everywhere, related or unrelated, like a bomb filling with so call "ideas". That hindrance was something I had to get over. Eventually I need to learn where my own priorities are, and what is more important. Even if it means I need to give up something that I used to think to as being important.
Programming is a tough job. And so is the computer.
Edit: About race condition, the website you gave me made sense because it took advantage of the command mkdir, that can only make a directory when a directory does not exist, and otherwise, throw an error that the command failed. But for checking whether the file exist or not, there is no such safeguard. So when two programs run at the same time, both of their checks will succeed, which defeats the purpose of "locking" altogether.
Last edited by lvsl (2024-12-08 17:59:27)
Offline
This script gets the synopsis from a command several different ways, first starting with trying the man-page, then trying a few other sources, finally just trying to get it from -h/--help. I use this *mostly* with HEASoft tools (which is why fhelp is in there) but it's good sometimes for reminding myself how stuff like comm and csplit work without pulling up the man page just to read off the synopsis.
The current version relies on a tool I have called wstrip which is basically a command-line wrapper for python's .split() method. There's definitely a Better Way to Do That but this was just something I wrote when I should've been doing more productive things.
Also gets stuck if e.g. the command doesn't take -h and expects to read from STDIN.
#!/usr/bin/sh
if [ "$1" = "-h" ] || [ "$1" = "--help" ]
then
echo "Usage: usage COMMAND"
echo "Display synopsis for COMMAND"
echo "Options:"
echo " -h, --help Display this help"
echo " -v, --version Display version information"
exit 1
elif [ "$1" = "-v" ] || [ "$1" = "--version" ]
then
echo "usage v2.1.0"
exit 1
elif [ "$1" = "" ]
then
echo "usage: Missing operand"
echo "Try 'usage --help' for more information"
exit 1
elif [ "$#" != 1 ]
then
echo "usage: $2: Extra operand"
echo "Try 'usage --help' for more information"
exit 1
fi
if [ "$1" = "$(apropos $1 2>/dev/null | grep -E '\((1|6)\)' | cut -f1 -d' ' | grep "^$1$")" ]
then
man "$1" 2>/dev/null | col -bx | awk -v S="^SYNOPSIS" '$0 ~ S {cap="true"; print} $0 !~ S && /^[A-Z ]+$/ {cap="false"} $0 !~ S && !/^[A-Z ]+$/ {if(cap == "true")print}' | tail -n+2 | wstrip -e
exit 0
fi
if fhelp -l -m=cat $1 &>/dev/null
then
fhelp -m=cat $1 | col -bx | awk -v S="^USAGE" '$0 ~ S {cap="true"; print} $0 !~ S && /^[A-Z ]+$/ {cap="false"} $0 !~ S && !/^[A-Z ]+$/ {if(cap == "true")print}' | tail -n+2 | wstrip -e
exit 0
fi
if ! which $1 &>/dev/null
then
echo "usage: $1: No such command"
exit 1
fi
for HELP in "-h" "--help" "--usage" "-?"
do
if USAGE=$($1 $HELP 2>/dev/null | grep -iE '^usage' | cut -f2- -d':' | tr '\n' ';' )
then
if [ -n "$USAGE" ]
then
echo -e "$USAGE" | tr ';' '\n' | wstrip -e
exit 0
fi
fi
done
echo "usage: $1: No usage given"
exit 1
Astrophysicist and programmer. I like simple things.
Offline
Look up case statements in bash.
Offline