Player FM - Internet Radio Done Right
Checked 5d ago
הוסף לפני five שנים
תוכן מסופק על ידי HPR Volunteer and Hacker Public Radio. כל תוכן הפודקאסטים כולל פרקים, גרפיקה ותיאורי פודקאסטים מועלים ומסופקים ישירות על ידי HPR Volunteer and Hacker Public Radio או שותף פלטפורמת הפודקאסט שלהם. אם אתה מאמין שמישהו משתמש ביצירה שלך המוגנת בזכויות יוצרים ללא רשותך, אתה יכול לעקוב אחר התהליך המתואר כאן https://he.player.fm/legal.
Player FM - אפליקציית פודקאסט
התחל במצב לא מקוון עם האפליקציה Player FM !
התחל במצב לא מקוון עם האפליקציה Player FM !
HPR4373: Rsync with stdin as source
Manage episode 481057698 series 2795599
תוכן מסופק על ידי HPR Volunteer and Hacker Public Radio. כל תוכן הפודקאסטים כולל פרקים, גרפיקה ותיאורי פודקאסטים מועלים ומסופקים ישירות על ידי HPR Volunteer and Hacker Public Radio או שותף פלטפורמת הפודקאסט שלהם. אם אתה מאמין שמישהו משתמש ביצירה שלך המוגנת בזכויות יוצרים ללא רשותך, אתה יכול לעקוב אחר התהליך המתואר כאן https://he.player.fm/legal.
This show has been flagged as Explicit by the host.
In today's show, oxo show us how you can use the output of the find command with -print0 option to rsync files to another location.
find . -type f -mmin -230 -print0 | rsync -aAXv --info=progress2,stats --progress --from0 --files-from - . dst
116 פרקים
Manage episode 481057698 series 2795599
תוכן מסופק על ידי HPR Volunteer and Hacker Public Radio. כל תוכן הפודקאסטים כולל פרקים, גרפיקה ותיאורי פודקאסטים מועלים ומסופקים ישירות על ידי HPR Volunteer and Hacker Public Radio או שותף פלטפורמת הפודקאסט שלהם. אם אתה מאמין שמישהו משתמש ביצירה שלך המוגנת בזכויות יוצרים ללא רשותך, אתה יכול לעקוב אחר התהליך המתואר כאן https://he.player.fm/legal.
This show has been flagged as Explicit by the host.
In today's show, oxo show us how you can use the output of the find command with -print0 option to rsync files to another location.
find . -type f -mmin -230 -print0 | rsync -aAXv --info=progress2,stats --progress --from0 --files-from - . dst
116 פרקים
All episodes
×This show has been flagged as Explicit by the host. hajime This installation script installs an Arch Linux system on an x64 architecture. The installation can be done with or without a network connection (internet). oxo/hajime - Codeberg.org hajime/make-recov at main - oxo/hajime - Codeberg.org isolatest/isolatest at main - oxo/isolatest - Codeberg.org Provide feedback on this episode .…
H
Hacker Public Radio

This show has been flagged as Explicit by the host. font selection Nerd Fonts - Iconic font aggregator, glyphs/icons collection, & fonts patcher Programming Fonts - Test Drive font installation install font package % yay -Sy $font_package update font database % fc-cache --force --verbose verify available fonts % fc-list | grep $font_name change font in application configs e.g.: alacritty emacs sway tofi Provide feedback on this episode .…
H
Hacker Public Radio

This show has been flagged as Explicit by the host. In today's show, oxo show us how you can use the output of the find command with -print0 option to rsync files to another location. find . -type f -mmin -230 -print0 | rsync -aAXv --info=progress2,stats --progress --from0 --files-from - . dst Provide feedback on this episode .…
H
Hacker Public Radio

This show has been flagged as Explicit by the host. Hi listener! My name is oxo. In this first episode for HPR I will introduce myself a little and present my plans for my future episodes on this channel. My goal is to let you as a listener follow along while I am learning new interesting things about Linux. This will be mainly about how I manage to survive the commandline while having fun doing so! :) My main codebase is in the codeberg repository, which you can find here: oxo - Codeberg.org Comments are always welcome! Please contact me via Mastodon: @oxo@qoto.org or email oxo at protonmail.com Provide feedback on this episode .…
This show has been flagged as Clean by the host. Make a diff: $ diff --unified --new-file --recursive original/ my-revision/ > my.patch Send my.patch to somebody so they can use it as input for the patch command: $ patch --strip 0 < my.patch Provide feedback on this episode .
H
Hacker Public Radio

This show has been flagged as Clean by the host. Today I Learnt more Bash tips Sgoti talks about supplying options to bash scripts Tags: Bash tips, TIL, getopts #!/bin/bash # License: GPL v3 # 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 . #Name: showtime.sh #Purpose: Time to make a show. #Version: beta 0.01 #Author: SGOTI (Some Guy On The Internet) #Date: 2023-12-29 #variables: bindir=/usr/bin/ cat=${bindir}cat date=${bindir}date echo=${bindir}echo mkdir=${bindir}mkdir dirshow0=${HOME}/Music/hpr/shows dirshow1=${dirshow0}/$(${date} +%Y) dirqueue=${dirshow1}/queue/$(${date} +%F) dirreserve=${dirshow1}/reserve-queue/$(${date} +%F) #start: function help() { ${cat} << EOH Usage: $0 [-s] [-r] [-q] [-h] name-of-show -s (Regular queue) -r (Reserve queue) -q (quit) -h (help) Examples: $0 -s name-of-show $0 -r name-of-show $0 -q $0 -h EOH } ## Use `getopts` to read user option into script. ## while getopts ":s:r:q:h" option; do case $option in s) show=$OPTARG function mkq () { ${mkdir} -v -p ${dirqueue}/${show}/edit; ${mkdir} -v -p ${dirqueue}/${show}/prod; ${cat} > ${dirqueue}/${show}/edit/${show}.md << _EOD_ # ${show} # ## subtitle ## - Tags: This work is licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/ "CC-BY-SA 4.0 International"). _EOD_ builtin pushd -n ${dirqueue}/${show}/edit; builtin pushd -n ${dirqueue}/${show}/prod; } if [ -d ${dirshow1} ]; then mkq else ${echo} "Good Heavens! It's a new year."; ${mkdir} -v -p ${dirshow1}; mkq fi ;; r) reserve=$OPTARG function mkr () { ${mkdir} -v -p ${dirreserve}/${reserve}/edit; ${mkdir} -v -p ${dirreserve}/${reserve}/prod; ${cat} > ${dirreserve}/${reserve}/edit/${reserve}.md << _EOD_ # ${reserve} # ## subtitle ## - Tags: This work is licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/ "CC-BY-SA 4.0 International"). _EOD_ builtin pushd -n ${dirreserve}/${reserve}/edit; builtin pushd -n ${dirreserve}/${reserve}/prod; } if [ -d ${dirshow1} ]; then mkr else ${echo} "Good Heavens! It's a new year."; ${mkdir} -v -p ${dirshow1}; mkr fi ;; q) ${echo} "Goodbye."; exit ;; h) help exit ;; *) if [ -z "${option}" ]; then help exit 1 fi ${echo} "Good Heavens! Invalid input."; help exit ;; esac done exit; #!/bin/bash # License: GPL v3 # 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 . #Name: sc.sh #Purpose: #Version: beta 0.01 #Author: SGOTI (Some Guy On The Internet) #Date: 2023-12-31 #variables: bindir=/usr/bin/ cat=${bindir}cat date=${bindir}date echo=${bindir}echo ls=${bindir}ls screen=${bindir}screen #start: ${echo} -e "\nStep 0: $(${date} +%F), $(${date} +%T)"; function help() { ${cat} << EOH Usage: $0 [-b] [-s] [-k] [-h] name-of-show -b [y|n] (Create or kill, base sockets.) -s (Create new sockets.) -k (Kill sockets.) -h (help menu) Examples: $0 -b y $0 -b n $0 -s name-of-socket $0 -k name-of-socket $0 -h EOH } ${echo} -e "\nStep 1: $(${date} +%F), $(${date} +%T)"; while getopts ":b:s:k:h:" option; do case "${option}" in b) userinput0=$OPTARG if [ ${userinput0} == "y" ]; then ${screen} -dmS apps; ${screen} -dmS jobby; ${screen} -ls; elif [ ${userinput0} == "n" ]; then # You don't need the entire name to kill the socket. ${screen} -X -S "app" kill ${screen} -X -S "job" kill ${screen} -ls; else ${echo} "Good Heavens!" ${screen} -ls; help exit 1 fi ;; s) userinput0=$OPTARG ${screen} -dmS "${userinput0}"; clear ${screen} -ls; ${echo} -e "\nNew sockets: $(${date} +%F), $(${date} +%T)"; ;; k) userinput0=$OPTARG ${screen} -XS ${userinput0} kill clear ${screen} -ls; ${echo} -e "\nKill sockets: $(${date} +%F), $(${date} +%T)"; ;; h) help ${echo} -e "\nHelp menu: $(${date} +%F), $(${date} +%T)"; exit ;; *) if [ -z "${option}" ]; then help exit 1 fi ${echo} "Good Heavens! Invalid input."; help exit ;; esac done ${echo} -e "\nStep 2: $(${date} +%F), $(${date} +%T)"; exit; Source: In-Depth Series: Today I Learnt Source: In-Depth Series: Bash Scripting This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License . Provide feedback on this episode .…
This show has been flagged as Explicit by the host. Overview Recently Ken Fallon did a show on HPR, number 3962 , in which he used a Bash pipeline of multiple commands feeding their output into a while loop. In the loop he processed the lines produced by the pipeline and used what he found to download audio files belonging to a series with wget . This was a great show and contained some excellent advice, but the use of the format: pipeline | while read variable; do ... reminded me of the "gotcha" I mentioned in my own show 2699 . I thought it might be a good time to revisit this subject. So, what's the problem? The problem can be summarised as a side effect of pipelines. What are pipelines? Pipelines are an amazingly useful feature of Bash (and other shells). The general format is: command1 | command2 ... Here command1 runs in a subshell and produces output (on its standard output ) which is connected via the pipe symbol ( | ) to command2 where it becomes its standard input . Many commands can be linked together in this way to achieve some powerful combined effects. A very simple example of a pipeline might be: $ printf 'World\nHello\n' | sort Hello World The printf command (≡ 'command1' ) writes two lines (separated by newlines) on standard output and this is passed to the sort command's standard input (≡ 'command2' ) which then sorts these lines alphabetically. Commands in the pipeline can be more complex than this, and in the case we are discussing we can include a loop command such as while . For example: $ printf 'World\nHello\n' | sort | while read line; do echo "($line)"; done (Hello) (World) Here, each line output by the sort command is read into the variable line in the while loop and is written out enclosed in parentheses. Note that the loop is written on one line. The semi-colons are used instead of the equivalent newlines. Variables and subshells What if the lines output by the loop need to be numbered? $ i=0; printf 'World\nHello\n' | sort | while read line; do ((i++)); echo "$i) $line"; done 1) Hello 2) World Here the variable 'i' is set to zero before the pipeline. It could have been done on the line before of course. In the while loop the variable is incremented on each iteration and included in the output. You might expect 'i' to be 2 once the loop exits but it is not. It will be zero in fact. The reason is that there are two 'i' variables. One is created when it's set to zero at the start before the pipeline. The other one is created in the loop as a "clone". The expression: ((i++)) both creates the variable (where it is a copy of the one in the parent shell) and increments it. When the subshell in which the loop runs completes, it will delete this version of 'i' and the original one will simply contain the zero that it was originally set to. You can see what happens in this slightly different example: $ i=1; printf 'World\nHello\n' | sort | while read line; do ((i++)); echo "$i) $line"; done 2) Hello 3) World $ echo $i 1 These examples are fine, assuming the contents of variable 'i' incremented in the loop are not needed outside it. The thing to remember is that the same variable name used in a subshell is a different variable; it is initialised with the value of the "parent" variable but any changes are not passed back. How to avoid the loss of changes in the loop To solve this the loop needs to be run in the original shell, not a subshell. The pipeline which is being read needs to be attached to the loop in a different way: $ i=0; while read line; do ((i++)); echo "$i) $line"; done < <(printf 'World\nHello\n' | sort) 1) Hello 2) World $ echo $i 2 What is being used here is process substitution . A list of commands or pipelines are enclosed with parentheses and a 'less than' sign prepended to the list (with no intervening spaces). This is functionally equivalent to a (temporary) file of data. The redirection feature allows for data being read from a file in a loop. The general format of the command is: while read variable do # Use the variable done < file Using process substitution instead of a file will achieve what is required if computations are being done in the loop and the results are wanted after it has finished. Beware of this type of construct The following one-line command sequence looks similar to the version using process substitution, but is just another form of pipeline: $ i=0; while read line; do echo $line; ((i++)); done < /etc/passwd | head -n 5; echo $i root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync 0 This will display the first 5 lines of the file but does it by reading and writing the entire file and only showing the first 5 lines of what is written by the loop. What is more, because the while is in a subshell in a pipeline changes to variable 'i' will be lost. Advice Use the pipe-connected-to-loop layout if you're aware of the pitfalls, but will not be affected by them. Use the read-from-process-substitution format if you want your loop to be complex and to read and write variables in the script. Personally, I always use the second form in scripts, but if I'm writing a temporary one-line thing on the command line I usually use the first form. Tracing pipelines (advanced) I have always wondered about processes in Unix. The process you log in to, normally called a shell runs a command language interpreter that executes commands read from the standard input or from a file. There are several such interpreters available, but we're dealing with bash here. Processes are fairly lightweight entities in Unix/Linux. They can be created and destroyed quickly, with minimal overhead. I used to work with Digital Equipment Corporation's OpenVMS operating system which also uses processes - but these are much more expensive to create and destroy, and therefore slow and less readily used! Bash pipelines, as discussed, use subshells . The description in the Bash man page says: Each command in a multi-command pipeline, where pipes are created, is executed in a subshell, which is a separate process. So a subshell in this context is basically another child process of the main login process (or other parent process), running Bash. Processes (subshells) can be created in other ways. One is to place a collection of commands in parentheses. These can be simple Bash commands, separated by semi-colons, or pipelines. For example: $ (echo "World"; echo "Hello") | sort Hello World Here the strings "World" and "Hello" , each followed by a newline are created in a subshell and written to standard output. These strings are piped to sort and the end result is as shown. Note that this is different from this example: $ echo "World"; echo "Hello" | sort World Hello In this case "World" is written in a separate command, then "Hello" is written to a pipeline. All sort sees is the output from the second echo , which explains the output. Each process has a unique numeric id value (the process id or PID ). These can be seen with tools like ps or htop . Each process holds its own PID in a Bash variable called BASHPID . Knowing all of this I decided to modify Ken's script from show 3962 to show the processes being created - mainly for my interest, to get a better understanding of how Bash works. I am including it here in case it may be of interest to others. #!/bin/bash series_url="https://hackerpublicradio.org/hpr_mp3_rss.php?series=42&full=1&gomax=1" download_dir="./" pidfile="/tmp/hpr3962.sh.out" count=0 echo "Starting PID is $BASHPID" > $pidfile (echo "[1] $BASHPID" >> "$pidfile"; wget -q "${series_url}" -O -) |\ (echo "[2] $BASHPID" >> "$pidfile"; xmlstarlet sel -T -t -m 'rss/channel/item' -v 'concat(enclosure/@url, "→", title)' -n -) |\ (echo "[3] $BASHPID" >> "$pidfile"; sort) |\ while read -r episode; do [ $count -le 1 ] && echo "[4] $BASHPID" >> "$pidfile" ((count++)) url="$( echo "${episode}" | awk -F '→' '{print $1}' )" ext="$( basename "${url}" )" title="$( echo "${episode}" | awk -F '→' '{print $2}' | sed -e 's/[^A-Za-z0-9]/_/g' )" #wget "${url}" -O "${download_dir}/${title}.${ext}" done echo "Final value of \$count = $count" echo "Run 'cat $pidfile' to see the PID numbers" The point of doing this is to get information about the pipeline which feeds data into the while loop . I kept the rest intact but commented out the wget command. For each component of the pipeline I added an echo command and enclosed it and the original command in parentheses, thus making a multi-command process. The echo commands write a fixed number so you can tell which one is being executed, and it also writes the contents of BASHPID . The whole thing writes to a temporary file /tmp/hpr3962.sh.out which can be examined once the script has finished. When the script is run it writes the following: $ ./hpr3962.sh Final value of $count = 0 Run 'cat /tmp/hpr3962.sh.out' to see the PID numbers The file mentioned contains: Starting PID is 80255 [1] 80256 [2] 80257 [3] 80258 [4] 80259 [4] 80259 Note that the PID values are incremental. There is no guarantee that this will be so. It will depend on whatever else the machine is doing. Message number 4 is the same for every loop iteration, so I stopped it being written after two instances. The initial PID is the process running the script, not the login (parent) PID. You can see that each command in the pipeline runs in a separate process ( subshell ), including the loop. Given that a standard pipeline generates a process per command, I was slightly surprised that the PID numbers were consecutive. It seems that Bash optimises things so that only one process is run for each element of the pipe. I expect that it would be possible for more processes to be created by having pipelines within these parenthesised lists, but I haven't tried it! I found this test script quite revealing. I hope you find it useful too. Links Bash pipelines: GNU Bash manual: 3.2.3 Pipelines Bash loops: GNU Bash manual: 3.2.5.1 Looping Constructs Bash process substitution: GNU Bash manual: 3.5.6 Process Substitution HPR shows referenced: hpr2045 :: Some other Bash tips hpr2699 :: Bash Tips - 15 hpr3962 :: It's your data Provide feedback on this episode .…
This show has been flagged as Clean by the host. This is a response show to hpr3959 :: Download any HPR series with english file names "A dir with the series name will be created and all shows will be renamed to ShowTitle.mp3 inside it" This was the first show by gemlog and he used Bash, sed, grep, wget, to scrape the HPR site. This is great but as he points out any change to the site will break the script. A safer way to get the episodes is by scraping the rss feed, and the following is an example of how you might do that #!/bin/bash series_url="https://hackerpublicradio.org/hpr_mp3_rss.php?series=42&full=1&gomax=1" download_dir="./" wget "${series_url}" -O - | xmlstarlet sel -T -t -m 'rss/channel/item' -v 'concat(enclosure/@url, "→", title)' -n - | sort | while read episode do url="$( echo ${episode} | awk -F '→' '{print $1}' )" ext="$( basename "${url}" )" title="$( echo ${episode} | awk -F '→' '{print $2}' | sed -e 's/[^A-Za-z0-9]/_/g' )" wget "${url}" -O "${download_dir}/${title}.${ext}" done Provide feedback on this episode .…
This show has been flagged as Explicit by the host. Hello all. This is gemlog from Terrace, bc, canada just up near the alaska panhandle. Some of you may know me from in COM chat on sdf dot org or as a fedizen on the tilde dot zone instance of mastodon. Now, the other day I finally got around to checking out HPR properly, even though my masto-pal claw-dio-m turned me on to it a couple of years ago. Recently, on a friday night in irc on tilde radio, I noticed there were whole series on hpr and not only single shows and that got me kind of excited. I guess I'm easily excitable. Anyhow, something I could listen to at work or while driving. Still, I managed to forget about it until /just/ before I was leaving the house for work on Monday morning. I rushed to copy over a few shows - nearly at random onto my phone and headed out to work. After I got my morning sorted at work, I told VLC to play-all and enjoyed a couple of shows. I noticed that each show I had chosen had a beg post at the beginning. I figured I could make one on at least something from my messy gemlog/bin dir. However, after a break, I came back and couldn't remember which 4 digit numbered dot mp3 I had finished up on, which mildly irked me. Well, as we all know, irk becomes itch and I put my sad regex skills to the test scraping the hpr website with a custom bash script later when I got home. A very custom bash script. Like all scrapers, if any of the guys at hpr even breathe the wrong way, it will probably break horribly. On the other hand, I've had scrapers that looked just as sad running for many years against a canadian government site. So. Who knows? All the script uses are some built-ins from bash along with sed and wget for the actual getting. My local instance of searX N G was left smoking as scrambled for sed incantations to string together. I'm not a sed guy. Usage is simple, as the script only accepts one argument: ... the four digit series number of the show you want to download. It will create a dir with the series name and download every mp3 it finds, renaming each show to the show title. I was tempted to doll it up with some niceties like options for download dir, a selector for a series with a dialog of some kind... yada yada yada. But... we all know what happens when you stretch a quick hack with a bash script too far for the scripting language: hours of misery wishing you'd started with some other language. So far, I've used the script to download 8 series. DU dash S H tells me they add up to 2 dot 2 gig, so it seems to work well enough. It comes with the same iron clad warranty as everything I write: If it breaks, you get to keep all the pieces. Thanks for listening. #!/bin/bash # gemlog@gemlog.ca 2023-08-26 # License: CC BY-SA 4.0. # not proud of my continuing lack of regex foo frankly... if [ $# -lt 1 ]; then echo 1>&2 "$0: You need to enter the HPR Series Number to download as 4 digits" echo "The full list of HPR Series is at https://hackerpublicradio.org/series/index.html " exit 2 fi snumber=$1 re='^[[:digit:]]{4}$' if [[ $snumber =~ $re ]]; then wget https://hackerpublicradio.org/series/$snumber.html -q -O /tmp/$snumber.html content=$(]*>//g;/]*>//g;/]*>//g;/ Provide feedback on this episode .…
This show has been flagged as Explicit by the host. HPR Shows by Klaatu. Source: hpr3887 :: 10 must-know commands for a new cloud admin. Source: hpr3882 :: Alternatives to the cd command. Hot sauce lady. Source: Franks Red Hot Queen 2011. pwd && ls --group-directories-first --classify --almost-all # some more ls aliases alias la='ls -l --human-readable --group-directories-first --classify --almost-all' alias ll='ls --group-directories-first --classify --almost-all' alias lr='ls -l --human-readable --group-directories-first --classify --recursive' alias lar='ls -l --human-readable --group-directories-first --classify --almost-all --recursive' alias lap='ls -l --human-readable --group-directories-first --classify --almost-all | less' # safety first ;) alias rmi='rm --interactive --verbose' alias mvi='mv --interactive --verbose' alias cpi='cp --interactive --verbose' alias .shred='bleachbit --shred' # cd multi dir alias ..='cd ..;' alias .2='cd ../..;' alias .3='cd ../../..;' alias .4='cd ../../../..;' alias .5='cd ../../../../..;' # Directory controls. function cd () { clear; builtin cd "$@" && ls --group-directories-first --classify --almost-all; history -w; } #function pp () { #builtin pushd +$@ && ls --group-directories-first --classify --almost-all #} function pushup (){ builtin pushd $HOME/.config/vim/sessions/ builtin pushd $HOME/.local/bin/ builtin pushd $HOME/.thunderbird/*.default-release/ builtin pushd $HOME/Documents/non-of-your-business/ builtin pushd $HOME/Downloads/in/ builtin pushd $HOME/Downloads/out/ builtin pushd $HOME/Downloads/playground/ builtin pushd $HOME/Music/hpr/shows/ builtin pushd $HOME/projects/ builtin pushd $HOME/projects/hprbank/bp/ builtin pushd $HOME/symlinks/ builtin pushd $HOME/tmp/ builtin pushd +11 builtin dirs -v } alias pd='pushd' alias dirs='dirs -v' # Update alias .upg='sudo apt update && sudo apt upgrade -y;' # shutdown | reboot alias .sd='sudo shutdown -P now;' alias .rs='sudo reboot;' # Misc alias ccb='cat $HOME/cb | xsel --input --clipboard && echo "Copy. $(date "+%F %T")";' alias pcb='xsel --output --clipboard > $HOME/cb && echo "Copy. $(date "+%F %T")";' alias zz='xsel -c -b && echo "Clipboard Cleared. $(date "+%F %T")";' # File Mods alias 700='chmod --verbose =700' alias 600='chmod --verbose =600' alias 400='chmod --verbose =400' ############################################################################### # Functions ############################################################################### function .s () { ln --symbolic --verbose --target-directory=$HOME/symlinks/ $(pwd)/${1}; } function extract () { if [ -f $1 ] then case $1 in *.tar.bz2) tar -vxjf $1 ;; *.tar.gz) tar -vxzf $1 ;; *.tar) tar -xvf $1 ;; *.bz2) bunzip2 $1 ;; *.rar) unrar -x $1 ;; *.gz) gunzip $1 ;; *.tar) tar -vxf $1 ;; *.tbz2) tar -vxjf $1 ;; *.tgz) tar -vxzf $1 ;; *.zip) unzip $1 ;; *.Z) uncompress $1 ;; *.7z) 7z -x $1 ;; *) echo "Good Heavens, '$1' will NOT extract..." ;; esac else echo "Good Heavens, '$1' is NOT a valid file." fi } function myip () { ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/'; } function .mkd (){ mkdir -v $(date +%F) && pushd $(date +%F); } function .mkt (){ tmpdir=$(mktemp -d /tmp/$(date +%F).XXXXXXXX) && pushd ${tmpdir} } function .d (){ echo $(date +%F)$1 | xsel -i -b; } function .sh () { NEWSCRIPT=${1}.sh cat >> ${NEWSCRIPT} << EOS #!/bin/bash # License: GPL v3 # 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 . #Name: ${NEWSCRIPT} #Purpose: #Version: beta 0.01 #Author: SGOTI (Some Guy On The Internet) #Date: $(date +%F) #variables: #start: exit; EOS if [ -f "${NEWSCRIPT}" ] then chmod 700 ${NEWSCRIPT} else echo "Good Heavens! There isn't a "${NEWSCRIPT}"" fi } function .fmd () { xsel -o -b | fmt -w 76 | sed 's/$/ /g s/ / /g s/ / /g s/ / /g s/$/ /g s/ *$/ /g s/ / /g' | xsel -i -b; } #!/bin/bash # License: GPL v3 # 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 . #Name: bfn.sh #Purpose: Create better file names. #Version: beta 0.01 #Author: SGOTI (Some Guy On The Internet) #Date: 2022-11-08 #variables: oldname=$(echo ${1%.*}) newname=$(echo $oldname | sed 's/ /-/g;s/_/-/g;s/./-/g;s/--*/-/g;/\/d' | tr [:upper:] [:lower:]) ext1=".$(echo ${1##*.})" ext2=".$(echo ${1##*.} | tr [:upper:] [:lower:])" #start: function bcase () { if [ -f $1 ] then echo -e "renaming $oldnamen"; mv -v "$oldname$ext1" "$newname$ext2"; else mv -v "$oldname" "$newname"; fi } bcase exit; #!/bin/bash # License: GPL v3 # 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 . #Name: perm.sh #Purpose: #Version: beta 0.01 #Author: SGOTI (Some Guy On The Internet) #Date: 2023-01-13 #variables: var_dir=${1} #start: function bfp () { find "${var_dir}" -type d -exec chmod -R =700 {} + find "${var_dir}" -type f -exec chmod -R =600 {} + } bfp exit; This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License . Provide feedback on this episode .…
H
Hacker Public Radio

Five or six ways I could think of to roam the files of your Linux computer without cd. pushd and popd dirs https://en.wikipedia.org/wiki/Pushd_and_popd The pushd command, when called with a filepath as an argument, saves the current working directory in memory (via a directory stack) so it can be returned to at any time, places the new filepath at the top of the stack, and changes to the new filepath. The popd command returns to the path at the top of the directory stack. cd - From man bash An argument of - is converted to $OLDPWD before the directory change is attempted. Variables EXPORT mydir="/path/to/file/" cd ${mydir} History and histverify Using !number from the history command will execute the command [user@pc ~]$ history 1 cd tmp 2 cd ~ 3 history [user@pc ~]$ !3 cd tmp [user@pc tmp]$ from the man command shopt [-pqsu] [-o] [optname ...] Toggle the values of settings controlling optional shell behavior. ... -s Enable (set) each optname. -u Disable (unset) each optname. Now using !number from the history command will put the command on the prompt but you need to execute it yourself [user@pc ~]$ shopt -s histverify [user@pc ~]$ !39673 [user@pc ~]$ cd tmp autocd command [ken@kalani ~]$ shopt -s autocd [ken@kalani ~]$ tmp cd -- tmp [ken@kalani tmp]$ ~ cd -- /home/ken working without changing to directory [ken@kalani ~]$ ls tmp…
H
Hacker Public Radio

A named pipe is like a UNIX pipe, except it takes the form of a file. $ mkfifo mypipe $ echo "Hacker Public Radio" > mypipe & $ cat mypipe Hacker Public Radio
H
Hacker Public Radio

Overview Have you ever written a Bash script (or any shell script) where you generate a message like 'Found 42 files' and the day comes when it reports 'Found 1 files'? Have you been irritated by this? I have, and I go to lengths to deal properly with (English) plurals in my Bash scripts. Method 1 The simplest solution would be to use an 'if' statement: if [[ $fcount -eq 1 ]]; then echo "Found 1 file" else echo "Found $fcount files" fi This works, but to have to do it for every message would be a pain! Method 2 The next approach to this problem might be to write a Bash function. pluralise () { local singular="${1}" local plural="${2}" local count="${3}" if [[ $count -eq 1 ]]; then echo "$singular" else echo "$plural" fi } This can be called as follows: $ i=1; echo "Found $i $(pluralise "file" "files" $i)" Found 1 file $ i=42; echo "Found $i $(pluralise "file" "files" $i)" Found 42 files The string being displayed with echo contains a command substitution ('$(command)') which returns 'file' or 'files' depending on the value given. The first two arguments can be more complex than plain strings: $ i=1; echo "There $(pluralise "is 1 light" "are $i lights" $i)" There is 1 light $ i=4; echo "There $(pluralise "is 1 light" "are $i lights" $i)" There are 4 lights The pluralise function is available for download. Method 3 The GNU project has developed a set of utilities called the GNU gettext utilities consisting of tools and documentation for translation. This is a large subject which is not suitable for a short HPR episode such as this one. Among the tools is 'ngettext' which performs the function we have been discussing - choosing among plural forms. It also implements translations if desired (and translation files are provided as part of the software being developed). We will not discuss the translation topic here, but the choice of plurals is something that can be used in Bash scripts. The 'ngettext' tool takes three mandatory parameters: MSGID - the singular form of the text MSGID-PLURAL - the plural form of the text COUNT - the value used to make the singular/plural choice There are other optional parameters and options but they are not relevant here. The tool can be used in exactly the same way as the 'pluralise' example above. $ i=1; echo "There $(ngettext "is 1 light" "are $i lights" $i)" There is 1 light $ i=4; echo "There $(ngettext "is 1 light" "are $i lights" $i)" There are 4 lights Whether you use this or a Bash function is your choice. Conclusion I have been using ngettext in my scripts since I discovered it. If you also need to provide messages in your projects in other languages then this might be a good idea. I admit that my understanding of the GNU gettext project is superficial, so, on reflection it might be better to use a Bash function, since I don’t currently need all of the features GNU gettext provides. Links…
Preamble This is a case where I came upon a thing in Bash I had never considered before and was pleased and surprised that there was a way of doing what I wanted to do! If this is completely obvious to you, apologies, but it wasn’t to me! Overview Many programming languages have the concept of short-circuit evaluation in Boolean expressions. What this means is that in an expression such as: A AND B if A is false then the whole expression must be false, and B doesn’t have to be evaluated. That is because both arguments to AND have to be true for the overall result to be true. If A is true on the other hand, then B has to be evaluated to determine if the overall result is true. Similarly with: A OR B if A is true then the whole expression must be true and B can be skipped without evaluation. This is because only one argument to OR needs to be true to return a true result. If A is false on the other hand, then B has to be evaluated to determine if the overall result is false. Both of these expressions are evaluated from left to right. This is not a given in all languages. Some use special operators such as 'and_then' and 'or_else' which explicitly perform short-circuiting and left-to-right evaluation. Definition In simple terms, short-circuiting is where the evaluation of an expression is stopped as soon as its outcome is determined. The Wikipedia article Short-circuit evaluation defines it as: Short-circuit evaluation, minimal evaluation, or McCarthy evaluation (after John McCarthy) is the semantics of some Boolean operators in some programming languages in which the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression: when the first argument of the AND function evaluates to false, the overall value must be false; and when the first argument of the OR function evaluates to true, the overall value must be true. This article contains a table entitled Boolean operators in various languages which shows details of how various programming and scripting languages cater for this feature. Use case I was writing a Bash script in which I wanted to ask questions about various steps - should they be done or not? Alternatively, I wanted to be able to set an option to run without interaction and assume the answer is 'yes' to all questions. I’d encountered short-circuit evaluation before in Pascal and Perl so I wondered if I could use it in Bash. The expression I was trying to write was: if [[ $YES -eq 1 ]] || yes_no 'Create directory? %s ' 'N'; then # Create directory fi Variable YES is being set through an option '-Y'; it’s normally set to zero but is set to 1 if the option is used. yes_no is a function I wrote, and talked about in HPR episode 2096: “Useful Bash functions - part 2”. The requirement was that if YES was set to 1 I didn’t want the function…
Carl talks about a method to move function definitions to the bottom of a script using sed: #!/bin/sh source <(sed '1,/^exit/ d' $0) __say "hello" exit __say() { echo $1 } Guest Host #1 (scroll to the bottom to ruin the surprise) talks about the shift command using this example: startdate="$1" # Pick up date shift days=0 # Loop through args and create events while [ $1 ] ; do # as many times as you add a timestamp [ $1 != "off" ] && khal new $(date -j -v+"$days"d -f %Y-%m-%d +%Y-%m-%d $startdate) $1 8H Work let days++ shift done Guest Host #2 provides tips and examples on how to use variables safely and politely provide default values. One example of assigning a default value is: foo=${foo:-"blah"} Carl then closes out with the : (colon) shell builtin and provides a variation on the above default value: : ${foo:="blah"}…
ברוכים הבאים אל Player FM!
Player FM סורק את האינטרנט עבור פודקאסטים באיכות גבוהה בשבילכם כדי שתהנו מהם כרגע. זה יישום הפודקאסט הטוב ביותר והוא עובד על אנדרואיד, iPhone ואינטרנט. הירשמו לסנכרון מנויים במכשירים שונים.