You are not logged in.
Automount USB sticks using udev rule (for udev running outside of systemd namespace).
Yes I know this is a bad idea and that I "should" be using udisks. Sue me
ACTION=="add", SUBSYSTEMS=="usb", SUBSYSTEM=="block", ATTR{removable}=="1", RUN{program}+="/home/<username>/scripts/automount.sh $devnode"
#!/bin/bash
set -uo pipefail
_mount() {
local -r _user="$(who | awk '{print $1}')"
local -r _dir="/mnt/$(basename "${1}")"
local -ir _uid="$(id -u "${_user}")"
local -ir _gid="$(id -g "${_user}")"
install -m 755 -g "${_user}" -o "${_user}" -d "${_dir}"
mount -o uid="${_uid}",gid="${_gid}" "${1}" "${_dir}"
}
_enum() {
local -a _partitions=()
mapfile -t _partitions <<< "$(lsblk -o name -lnp "${1}")"
for part in "${_partitions[@]}"
do
if [[ "${part}" != "${1}" ]]
then
_mount "${part}"
fi
done
}
( _enum "${1}" ) &
Last edited by karabaja4 (2021-01-24 02:44:48)
Offline
Based on some recommendations google spit out, here is my bash script using youtube-dl that downloads Audio from Youtube and splits it into one file per video chapter.
#!/bin/bash url="$1" basename=$(youtube-dl --dump-single-json "$url" | jq .title | tr -cd '[:alnum:]') downloads="~/Downloads/_youtube-dl/" mkdir -p "$downloads"/"$basename" cd "$downloads"/"$basename" youtube-dl --write-info-json -x --audio-format mp3 -o "$basename.%(ext)s" "$url" jq '.chapters[] | .start_time,.end_time-.start_time,.title ' < $basename.info.json | xargs -n3 -d'\n' | awk '{print NR" "$s}' > chapters while read -r track start duration title; do title=${title//\"/} ffmpeg -loglevel warning -nostdin -y -ss "$start" -t "$duration" -i "$basename.mp3" -codec:a copy "$track - $title.mp3" done < chapters
It doesn't clean up after itself and probably doesn't handle errors very well.
pacman -S cuetools shntool
shnsplit -f "$1".cue -t %n-%t -o flac "$1".flac
cuetag.sh "$1".cue [0-9]*.flac
It shall work with mp3 too ( I have only used with flac)
Arch is home!
cwm rofi weaver vifm vim lizzy pass terminator
Offline
Suspend my machine when I shutdown my Bluetooth headset. Quick and dirty but whatever...
// build main.go with
// go build -o bsus main.go
package main
import (
"bytes"
"os/exec"
"time"
)
func main() {
var out []byte
var lines int
for {
out, _ = exec.Command("pactl", "list", "cards", "short").Output()
lines = bytes.Count(out, []byte{'\n'})
if lines < 2 {
exec.Command("systemctl", "suspend").Run()
return
}
time.Sleep(time.Second * 5)
}
}
Fix yo shit: journalctl -b -p warning
Github
Offline
record selected window+audio with ffmpeg
#!/bin/bash
slop=$(slop -f "%x %y %w %h %g %i") || exit 1
read -r X Y W H G ID < <(echo $slop)
ffmpeg -f x11grab -framerate 15 -draw_mouse 0 \
-s "$W"x"$H" -i :0.0+$X,$Y \
-f pulse -ar 44100 -ac 2 -i 0 -b 300k /tmp/$(date +%d%m%Y_%H%M%S).mp4
Arch is home!
cwm rofi weaver vifm vim lizzy pass terminator
Offline
Does it really select a window or does it record the selected area?
Offline
Both can be done. Click to select, or draw a rectangle to select area. slop gets the coordinates and that is fed to ffmpeg.
EDIT: Oh,, I got it. It selects area of window when window is clicked, But you shall not move the window during recording. AFAIK ffmpeg supports window grabing in Windows using gdigrab but in linux x11grab only supports area selection.
Last edited by Docbroke (2021-02-04 11:51:26)
Arch is home!
cwm rofi weaver vifm vim lizzy pass terminator
Offline
Be reminded of lunch, directly on the prompt: https://github.com/xyproto/sealion
Last edited by xyproto (2021-02-09 21:11:30)
Offline
Worked on correcting a lot of my earlier fumbling to something, humbly ...improved? ...relatively at least
This just checks all my "vcs" packages for updates using the incredible aurutils tools.. any fixes are very welcome
vcs-sync () {
aurvcssearch=".*-(cvs|svn|git|hg|bzr|darcs)$"
mapfile -t vcspacks < <(awk -v "mask=$aurvcssearch" '$1 ~ mask {print $1}' <(aur repo --list))
declare -a packstack
aurcache='/pkg/aur/aurutils/sync'
if [[ ${#vcspacks[@]} -eq 0 ]]; then
printf "%s\n" "No vcs-packages to check, check your vcs-packages no?" && return 1
else
printf "%s\n" "Checking (${#vcspacks[@]}) vcs-packages for newer commits: ... "
fi
for pack in "${vcspacks[@]}"
do
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
packstack+=( "${pack}" )
printf "%s\n" "$pack has updates adding to stack ..."
fi
fi
done
if [[ ${#packstack[@]} -gt 0 ]]; then
printf "%s\n" "Rebuilding (${#packstack[@]}) vcs-packages: ... "
aur sync --rebuild "${packstack[@]}" && unset vcspacks && unset packstack
else
printf "%s\n" "No vcs-packages to update at this time." && unset vcspacks
fi
}
Last edited by CarbonChauvinist (2021-02-05 02:09:24)
"the wind-blown way, wanna win? don't play"
Offline
Now that I have [gnome-unstable] and [testing] enabled i thought it would be a good idea to start taking daily btrfs snapshots, just in case...
/etc/systemd/system/snapshot.timer:
[Unit]
Description=Daily snapshot
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
/etc/systemd/system/snapshot.service:
[Unit]
Description=Daily snapshot
[Service]
Type=oneshot
ExecStart=/usr/local/bin/snapshot
/usr/local/bin/snapshot:
#!/bin/sh
time=$(date +'%Y-%m-%d@%T')
grub_dir=/boot/grub
config_file="$grub_dir"/arch-snapshots.cfg
snapshot_dir=/snapshots
subvol_dir=/snapshots/arch
uuid=$(findmnt -o uuid -n /)
parameters='rw quiet'
get_snap_info() {
snap_list=$(for snap in "$snapshot_dir"/* ; do printf '%s ' "$(basename -- "$snap")" ; done)
snap_number=$(printf '%s\n' "$snap_list" | awk '{print NF}')
old_snap=$(printf '%s\n' "$snap_list" | awk '{print $1}')
}
if grep -q ' / .*snapshots.*' /proc/self/mounts ; then
printf 'Booted into snapshot, no action taken.\n'
else
printf 'Removing old configuration file...\n'
if [ -e "$config_file" ] ; then
rm "$config_file"
else
printf 'No configuration file found.\n'
fi
printf 'Creating new snapshot...\n'
btrfs subvolume snapshot / "$snapshot_dir"/"$time"
get_snap_info
while [ "$snap_number" -gt 5 ] ; do
printf 'Removing excess snapshot...\n'
btrfs subvolume delete "$snapshot_dir"/"$old_snap"
get_snap_info
done
printf 'Creating new configuration file...\n'
printf '#\n' > "$config_file"
for entry in "$snapshot_dir"/* ; do
for kernel in "$entry"/boot/vmlinuz-* ; do
image=/boot/"${kernel##*/}"
initrd=/boot/initramfs-"${image#*-}".img
set -- "$entry"/boot/*-ucode.img
if [ -e "$1" ] ; then
initrd_line=$(printf 'initrd %s/%s/boot/%s %s/%s%s' "$subvol_dir" "${entry##*/}" "${1##*/}" "$subvol_dir" "${entry##*/}" "$initrd")
else
initrd_line=$(printf 'initrd %s/%s%s' "$subvol_dir" "${entry##*/}" "$initrd")
fi
ed "$config_file" > /dev/null <<!
1i
menuentry '${entry##*/} (${image#*-})' {
search --fs-uuid --set=root $uuid
linux $subvol_dir/${entry##*/}$image root=UUID=$uuid rootflags=subvol=$subvol_dir/${entry##*/} $parameters
$initrd_line
}
.
w
!
done
done
printf 'All done!\n'
fi
$snapshot_dir is the path to the directory that holds the snapshots in the running Arch system and $subvol_dir is the path to the directory that holds the snapshots in the root of the btrfs filesystem; $parameters are the kernel parameters to be applied in the GRUB menu entries that are created for the snapshots. The script deletes any old snapshots once there are more than five, edit the while loop to change this.
Use this stanza in /boot/grub/grub.cfg to add the snapshots:
submenu 'Arch snapshots' {
source $prefix/arch-snapshots.cfg
}
$prefix defaults to the directory containing the grub.cfg file.
I don't use grub-mkconfig so the grub-btrfs package is of no use to me.
EDIT: for the snapshots to be bootable there should be no root partition line in /etc/fstab (custom filesystem options can be applied from the bootloader). Alternatively add a line to modify /etc/fstab in the newly-created snapshot.
Last edited by Head_on_a_Stick (2021-02-22 16:55:20)
Offline
Here's one I use regularly, I call it W (from 'which'); it finds executables in your $PATH given one or two parts of the name.
I don't remember how it works...
#!/bin/bash
# Find files in $PATH matching *$1* [| grep -i $2]
#
if [ $# -lt 1 ]
then
echo Usage: `basename $0` pattern [ pattern2 ]
exit 1
fi
if [ $# -eq 1 ]; then
echo $PATH | sed 's/^/ls -A /' | sed 's/:/ |grep -i '$1'; ls -A /g' | sed 's/$/ |grep -i '$1'/' | bash | sort
exit 0
fi
if [ $# -eq 2 ]; then
echo $PATH | sed 's/^/ls -A /' | sed 's/:/ |grep -i '$1'; ls -A /g' | sed 's/$/ |grep -i '$1'/' | bash | sort | grep -i $2
exit 0
fi
Try
W user
W ^user
W user ad
W ad user
"If you do not change direction, you may end up where you are heading." -- L.T.
Offline
I don't remember how it works...
Poorly, very poorly. That's a rather ridiculous pipeline of seds and greps and even a parsing of ls in there. All that can be done with a single find command:
find $PATH -regex <whatever>
"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" - Richard Stallman
Offline
It does not works…
IFS=: dirs=($PATH)
find ${dirs[@]} -name "*$1*" | grep $2
(bash only, won't even work w/ zsh because of IFS handling)
Offline
IFS=: find $PATH -name "*${1}*" -name "*${2}*" -printf '%P\n'
Last edited by respiranto (2021-02-22 22:19:41)
Offline
Did you try that? In which shell?
Here's weird behavior (which eschwartz can perfectly reasonably explain ;-)
$ bash
$ IFS=: find $PATH -name "*add*" -name "*user*"
find: /usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl’: Datei oder Verzeichnis nicht gefunden
$ IFS=: find $PATH -name "*add*" -name "*user*"
find: /usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl’: Datei oder Verzeichnis nicht gefunden
$ IFS=: dirs=($PATH)
$ IFS=: find $PATH -name "*add*" -name "*user*"
/usr/bin/useradd
Also we probably need "-executable".
Offline
I thought I had it tested...
IFS=:; find $PATH -name "*${1}*" -name "*${2}*" -printf '%P\n'
On weird behaviour:
The line:
IFS=: dirs=($PATH)
sets two variables.
---
Also we probably need "-executable".
find -P $PATH -mindepth 1 -maxdepth 1 -executable -xtype f -name "*${1}*" -name "*${2}*" -printf '%P\n' | sort -u
It would be nice to allow for regexes. Unfortunately, `-(i)regex' matches the whole path and implicitly embeds the pattern in '^' and '$'. I could not come up with something better than the following:
#!/usr/bin/env bash
typeset -a args=()
for p in "$@"
do
p=".*${p}.*"
p="${p#.\*^}"
p="${p%$.\*}"
args+=(-iregex ".*/${p}")
done
IFS=:
find -P $PATH -mindepth 1 -maxdepth 1 -executable -xtype f \
-regextype posix-extended "${args[@]}" -printf '%P\n' \
| sort -u
Alternatively, without explicit loop, unreadable, and still long:
#!/usr/bin/env bash
set -- "${@/#/.\*}"
set -- "${@#.\*^}"
set -- "${@/%/.\*}"
set -- "${@%\$.\*}"
set -- "${@@Q}"
eval "set -- ${@/#/-iregex .\\\*\/}"
IFS=:
find -P $PATH -mindepth 1 -maxdepth 1 -executable -xtype f \
-regextype posix-extended "$@" -printf '%P\n' \
| sort -u
Last edited by respiranto (2021-02-22 23:27:00)
Offline
I'm pretty sure that used to work, but it works fine here just setting IFS - and there is definitely no need for a pipeline and certainly no need for a loop, if you want to use two regex's just use two regexs:
IFS=:; find $PATH -regex <pattern1> -regex <pattern2>
Last edited by Trilby (2021-02-22 23:56:24)
"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" - Richard Stallman
Offline
On weird behaviour:
With more blood and caffeine in my brains it's kinda obvious that IFS is relevant in the context of the shell, not the command.
So you somehow™ have to explicitly set it for that context (and use a subshell…)
Offline
Dumping EC content. Output: https://i.imgur.com/aeJGJd6.png
// Dump laptop's EC content
// Might need modprobe ec_sys
package main
import (
"fmt"
"os"
)
const ec = "/sys/kernel/debug/ec/ec0/io"
const reset = "\033[0m"
const red = "\033[31m"
const green = "\033[32m"
func main() {
fd, err := os.Open(ec)
if err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err)
os.Exit(1)
}
buf := make([]byte, 1)
for i := 0; i < 16; i++ {
fmt.Fprintf(os.Stdout, " %s%02X%s", green, i*16, reset)
for j := 0; j < 16; j++ {
fd.Read(buf)
if int(buf[0]) == 0 {
fmt.Print(" 00")
continue
}
fmt.Fprintf(os.Stdout, " %s%02X%s", red, buf[0], reset)
}
fmt.Println()
}
fmt.Print(" ")
for i := 0; i < 16; i++ {
fmt.Fprintf(os.Stdout, " %s%02X%s", green, i, reset)
}
fmt.Println()
}
Consequent utility for writing to EC registers
// Write to EC register
// Might need 'modprobe ec_sys write_support=1'
// Values must be Hex
// Example: ecwrite e3 ff
package main
import (
"fmt"
"os"
)
const ec = "/sys/kernel/debug/ec/ec0/io"
func main() {
register := os.Args[1]
var r uint8
if _, err := fmt.Sscanf(register, "%x", &r); err != nil {
fmt.Fprintf(os.Stderr, "Invalid register %s\n", register)
os.Exit(1)
}
value := os.Args[2]
var v uint8
if _, err := fmt.Sscanf(value, "%x", &v); err != nil {
fmt.Fprintf(os.Stderr, "Invalid value %s\n", value)
os.Exit(1)
}
fd, err := os.OpenFile(ec, os.O_RDWR, 0600)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
_, err = fd.WriteAt([]byte{byte(v)}, int64(r))
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
Last edited by ugjka (Yesterday 15:51:27)
Fix yo shit: journalctl -b -p warning
Github
Offline