You are not logged in.
Trilby wrote:what's with all the function names starting with underscores?
I wanted to use "chroot" as a function name so I prefixed an underscore so it wouldn't clash with the actual command. I don't actually know which would be preferred in such a situation, I suppose I really should check but I'm tired now. Anyway, once I had one function with an underscore the rest had to have them too. Obviously
Name it hoas_chroot, or do_chroot? Or, since you don't invoke the actual command, just name it "chroot"?
_select_part () { # shellcheck disable=SC2046 # word spitting is needed for the _list_part function choice=$(whiptail --notags --menu "Please select target root partition:" 0 0 0 $(_list_part) 3>&2 2>&1 1>&3) if [ -z "$choice" ]; then exit 1 fi } _chroot () { mount /dev/"$choice" /mnt arch-chroot /mnt mount -a arch-chroot /mnt umount -R /mnt }
You're using *functions*, but your functions access globals like $choice
main () { while true; do _select_part _confirm done } main
Then you wrap the entire program logic in a "main" function, as if this is C... C needs an internal main() symbol for language reasons, bash does not. This serves no practical purpose. I've heard people argue it serves a code neatness or "prettiness" purpose, but
- in my entirely biased opinion, I *strongly* disagree, fite me
- if you *do* hold by that opinion, then... why are you then using globals???
Managing AUR repos The Right Way -- aurpublish (now a standalone tool)
Offline
I'm sure there's someone on the internet who wants to reuse their bash scripts as a "library", packs stuff in "main" and then checks BASH_SOURCE...
For another opinion on those functions: when reading that script I have to jump around a bunch of times to see what's happening. Compare to someting like this:
#!/bin/sh
_list_part () {
# list all partitions except swap & those already mounted
lsblk -lno name,type,mountpoint | awk '/part/&&!/\//&&!/SWAP/{print $1,$1}'
}
while true; do
# shellcheck disable=SC2046 # word spitting is needed for the _list_part function
choice=$(whiptail --notags --menu "Please select target root partition:" 0 0 0 $(_list_part) 3>&2 2>&1 1>&3)
if [ -z "$choice" ]; then
exit 1
elif whiptail --yesno "Target partition is /dev/${choice}, is this correct?" 0 0 0; then
# chroot to chosen partition
mount /dev/"$choice" /mnt
arch-chroot /mnt mount -a
arch-chroot /mnt
umount -R /mnt
exit 0
fi
done
Which directly conveys what's going on.
Side-note: what's that mount -a doing there?
Combined cp and progress commands into a single script to create an alias for cp to show progress while copying:
Why not just use dd or pv instead of an ad-hoc method?
Last edited by Alad (2021-01-05 01:24:03)
Mods are just community members who have the occasionally necessary option to move threads around and edit posts. -- Trilby
Offline
Which directly conveys what's going on.
THIS, a thousand times this, this is the purpose of code refactoring. Somehow (I blame GNU coding style) refactoring has come to mean just making everything it's own tiny function with mutliple pointless levels of abstraction. Perhaps it's just overapplication of too simple of a heuristic: many novice coders (myself very much included) have (or have had) a habit of putting far too much into a single function. So we need to remind ourselves to spend time refactoring the code the pull out distinct functional units into their own functions. But that doesn't mean that every opportunity to "abstract" something out into it's own distinct function should be taken ad naseum.
Last edited by Trilby (2021-01-05 01:36:28)
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
This underscore thingy probably comes from Python, where it means "private method", although it's just a style convention and doesn't actually do anything.
EDIT: *snip*
Last edited by Awebb (2021-01-05 04:16:43)
Online
For another opinion on those functions: when reading that script I have to jump around a bunch of times to see what's happening. Compare to someting like this:
THIS, a thousand times this, this is the purpose of code refactoring. Somehow (I blame GNU coding style) refactoring has come to mean just making everything it's own tiny function with mutliple pointless levels of abstraction.
I do entirely agree I did say about people who think the complicated functions are prettier / easier to read,
"- in my entirely biased opinion, I *strongly* disagree, fite me"
Managing AUR repos The Right Way -- aurpublish (now a standalone tool)
Offline
Alad wrote:For another opinion on those functions: when reading that script I have to jump around a bunch of times to see what's happening. Compare to someting like this:
Trilby wrote:THIS, a thousand times this, this is the purpose of code refactoring. Somehow (I blame GNU coding style) refactoring has come to mean just making everything it's own tiny function with mutliple pointless levels of abstraction.
I do entirely agree I did say about people who think the complicated functions are prettier / easier to read,
"- in my entirely biased opinion, I *strongly* disagree, fite me"
People will find a way to GOTO, no matter how it's called. Sometimes it feels like people think that anything that doesn't make you jump up and down through the code and open multiple files is "a script" and therefore not proper code.
Online
Gotos made rules simpler. In the goto-based world, my rule would be "all gotos should be conditional". If there isn't some conditional check that could branch the flow of execution in more than one direction, then there is no need for a goto, just put the next code to execute on the next line.
Of course loops superficially seem like an exception, though there still would be a condition to remain in the loop, and there'd be two gotos to maintain the loop (to restart the loop, and to exit the loop).
Last edited by Trilby (2021-01-05 05:04:42)
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
Here's a script I made to fix my Faenza icon theme for Xfce.
Xfce is renaming their icon resources in accordance with the freedesktop.org rDNS icon naming standard, meaning the old names used by Faenza (and most icon themes, I would believe) doesn't match the icon resources any more. The result is that the theme icons are ignored, and the new Xfce default icons are used instead.
This work seems to be ongoing, so I expect to have to update the script from time to time
More info:
Xfce blog for September 2020
Xfce 4.16 release announcement
The script is all very straight forward:
First some manual labour (necessary if you want to this with another theme, or if Xfce renames more icon resources): I got the new resource names by finding files with their common prefix "org.xfce." from /usr/share/icons/hicolor and added the filenames without file extension to the RDNS_NAME array. Then I look up the correct icons for these resources from /usr/share/icons/Faenza and add those to the FAENZA_NAME array, so that RDNS_NAME[n] corresponds to FAENZA_NAME[n].
The script then basically finds all files under /usr/share/icons/Faenza, and compares them to the ones in the FAENZA_NAME array. If it matches it creates a symbolic link from the corresponding directory under ~/.local/share/icons/Faenza and names that link with the icon resource name from the RDNS_NAME array.
That way all the new icon resource names gets a Faenza icon
By the way, this should work (I haven't tried) also for a locally installed theme (i.e. the SOURCE_FOLDER and TARGET_FOLDER are identical).
This means that to undo what this script does, you just have to delete all symbolic links under ~/.local/share/icons/Faenza (or remove the directories altogether)
#!/bin/bash
SOURCE_FOLDER=/usr/share/icons/Faenza
TARGET_FOLDER=~/.local/share/icons/Faenza
linkUp () {
fullPath=$1
fullFilename="${fullPath##*/}"
fileExt="${fullFilename##*.}"
fileName="${fullFilename%.*}"
filePath=`dirname $1`
i=0
for file in ${FAENZA_NAME[*]}; do
if [ $file == $fileName ]; then
if [ ! -d ${filePath/$SOURCE_FOLDER/$TARGET_FOLDER} ]; then
echo -e "mkdir -p ${filePath/$SOURCE_FOLDER/$TARGET_FOLDER}\n"
mkdir -p ${filePath/$SOURCE_FOLDER/$TARGET_FOLDER}
fi
if [ ! -e ${filePath/$SOURCE_FOLDER/$TARGET_FOLDER}/${RDNS_NAME[$i]}.$fileExt ]; then
echo -e "ln -s $fullPath ${filePath/$SOURCE_FOLDER/$TARGET_FOLDER}/${RDNS_NAME[$i]}.$fileExt\n"
ln -s $fullPath ${filePath/$SOURCE_FOLDER/$TARGET_FOLDER}/${RDNS_NAME[$i]}.$fileExt
fi
fi
((i++))
done
}
# Mapping arrays:
# For each file named with a FAENZA_NAME under $SOURCE_FOLDER, a corresponding $TARGET_FOLDER link
# is created, named with the corresponding RDNS_NAME.
# The two arrays RDNS_NAME and FAENZA_NAME maps 1:1
# If you want to use another icon, just edit the arrays :-)
#
# Not mapped (i.e. no links created, so RDNS-icons are kept):
# - org.xfce.about
# - org.xfce.panel.separator
# - org.xfce.panel.applicationsmenu
# - org.xfce.panel.windowmenu
# - org.xfce.terminal-settings
# - org.xfce.tumbler
RDNS_NAME=(org.xfce.appfinder \
org.xfce.Dictionary \
org.xfce.filemanager \
org.xfce.garcon \
org.xfce.mailreader \
org.xfce.mousepad \
org.xfce.notification \
org.xfce.panel.actions \
org.xfce.panel.clock \
org.xfce.panel.directorymenu \
org.xfce.panel.launcher \
org.xfce.panel.pager \
org.xfce.panel \
org.xfce.panel.showdesktop \
org.xfce.panel.statustray \
org.xfce.panel.tasklist \
org.xfce.powermanager \
org.xfce.ScreenSaver \
org.xfce.screenshooter \
org.xfce.session \
org.xfce.settings.accessibility \
org.xfce.settings.appearance \
org.xfce.settings.color \
org.xfce.settings.default-applications \
org.xfce.settings.display \
org.xfce.settings.editor \
org.xfce.settings.keyboard \
org.xfce.settings.manager \
org.xfce.settings.mouse \
org.xfce.taskmanager \
org.xfce.terminalemulator \
org.xfce.terminal \
org.xfce.thunar \
org.xfce.volman \
org.xfce.webbrowser \
org.xfce.workspaces \
org.xfce.xfdesktop \
org.xfce.xfwm4 \
org.xfce.xfwm4-tweaks)
FAENZA_NAME=(xfce4-appfinder \
xfce4-dict.png \
xfce-filemanager \
xfce4-menueditor \
xfce-mail \
mousepad \
xfce4-notifyd \
system-log-out \
xfce4-clock \
folder-open \
application-x-executable \
xfce4-workspaces \
xfce4-panel \
user-desktop \
gnome-status \
stock_task \
gnome-power-manager \
screensaver \
gnome-screenshot \
xfce4-session \
preferences-desktop-accessibility \
preferences-desktop-theme \
preferences-color \
gnome-settings-default-applications \
xfce4-display \
xfce-system \
preferences-desktop-keyboard \
xfce4-settings \
xfce4-mouse \
stock_task \
xfce-terminal \
xfce-terminal \
thunar \
gnome-dev-harddisk-usb \
web-browser \
xfce4-workspaces \
user-desktop \
xfwm4 \
wmtweaks)
echo -e "\nThe following substitutions will be made from rDNS names to Faenza icons:\n"
i=0
for rdns in ${RDNS_NAME[*]}; do
echo "$rdns --> ${FAENZA_NAME[$((i++))]}"
done
echo -e "\nThe substitutions will be made by placing links to Faenza files using rDNS"
echo -e "names in Faenza folders under $TARGET_FOLDER\n"
read -p "Should I continue (y/n)? " -n 1 response
if [ $response != "y" ] && [ $response != "Y" ]; then
echo -e "\nAborting...\n"
exit 1
fi
echo -e "\n"
if [ ! -d $SOURCE_FOLDER ]; then
echo "Source folder doesn't exist, please edit script"
exit 1
fi
echo -e "Working...\n"
find $SOURCE_FOLDER/* -print0 | while IFS= read -r -d '' folder; do linkUp "$folder"; done
echo -e "\nPhew, finished!\n\nAlso consider installing libxfce4ui-nocsd (in AUR) to get rid of the"
echo -e "Gnome-like CSD (Client Side Decorations) window decorations\n"
Last edited by Ferdinand (2021-01-05 08:10:56)
Offline
Thanks to everybody who has taken the time to read my script and offer their opinion, it is very much appreciated and helps greatly.
fite me
Okay lil wizard dood... *rolls up sleeves*
Name it hoas_chroot, or do_chroot?
Yes, I suppose that would do just as well. The underscores were prefixed more or less on a whim and ultimately it's just cosmetic, after all a _rose() by any other name would still smell as sweet
since you don't invoke the actual command
It's invoked in the confirm() function.
Anyway I've just tested and defined functions are run in preference to commands of the same name so the underscrores are indeed superfluous. I'm still keeping them though
You're using *functions*, but your functions access globals like $choice
[...]
Then you wrap the entire program logic in a "main" function, as if this is C... C needs an internal main() symbol for language reasons, bash does not. This serves no practical purpose. I've heard people argue it serves a code neatness or "prettiness" purpose, but- in my entirely biased opinion, I *strongly* disagree, fite me
- if you *do* hold by that opinion, then... why are you then using globals???
I've split the script into separate functions for each distinct process in order to aid debugging and readability. See https://unix.stackexchange.com/question … -functions & http://kfirlavi.herokuapp.com/blog/2012 … ogramming/ for more on this.
And in respect of main() I was following Google's style guide and also bearing in mind this issue. The second point doesn't really apply to this particular script but it informs my general scripting "style", such as it is.
Compare to someting like this
Yes, that's pretty much how the script looked before I refactored it. I just personally prefer separating as much as possible into functions because I agree with the blog post to which I linked above, that's all.
what's that mount -a doing there?
I intend to add the script to the live environment for my CrunchBang clone ISO image to use for rescue and repair of installed systems and that line would ensure that any separate /boot (or other) partitions are mounted inside the chroot environment so that grub.cfg can be regenerated correctly if needed.
Para todos todo, para nosotros nada
Offline
eschwartz wrote:since you don't invoke the actual command
It's invoked in the confirm() function.
I *said*, you don't invoke the actual disk command -- you only invoke the function.
(Note that even if you invoke the disk command too, you can do so via `command chroot` which suppresses alias/function lookups.)
Anyway I've just tested and defined functions are run in preference to commands of the same name so the underscrores are indeed superfluous. I'm still keeping them though
... good grief, did you actually expect explicitly defined functions in your script to be fully impossible to call if they overlapped a PATH executable at any time? How would that work? Every script anywhere could be trivially broken after the fact by putting random binary names in /usr/local/bin:$HOME/bin
eschwartz wrote:You're using *functions*, but your functions access globals like $choice
[...]
Then you wrap the entire program logic in a "main" function, as if this is C... C needs an internal main() symbol for language reasons, bash does not. This serves no practical purpose. I've heard people argue it serves a code neatness or "prettiness" purpose, but- in my entirely biased opinion, I *strongly* disagree, fite me
- if you *do* hold by that opinion, then... why are you then using globals???I've split the script into separate functions for each distinct process in order to aid debugging and readability. See https://unix.stackexchange.com/question … -functions & http://kfirlavi.herokuapp.com/blog/2012 … ogramming/ for more on this.
The first link simply references the second link. The second link was written by an incompetent fool with numerous fatal flaws in even his examples; never mind using that as a style guide, you cannot even use it as a "valid code" guide.
And in respect of main() I was following Google's style guide and also bearing in mind this issue. The second point doesn't really apply to this particular script but it informs my general scripting "style", such as it is.
Google style guides, I've seen them before. When it comes to C, they advise writing C like no one else does; when it comes to python, they advise writing un-pythonic python; when it comes to bash, they advise writing bash in a way that has no basis other than "make it look more like C".
Their style guides are not about making things look better. Their style guides are about making it look the same across every single one of the thousands of languages they use.
The second point is downright incorrect. You must not edit programs in mid-run; you must atomically replace them by deleting them and replacing therm with another inode. e.g. that's how pacman works. Under the hood, so do tools like sed -i.
Managing AUR repos The Right Way -- aurpublish (now a standalone tool)
Offline
... good grief, did you actually expect explicitly defined functions in your script to be fully impossible to call if they overlapped a PATH executable at any time?
Erm, I wasn't sure. I don't script much, computers are just a toy for me so there's no real need. Thanks for enlightening me and thank you for your other opinions, they are very interesting and I shall take them onboard.
EDIT: obligatory xkcd link: https://xkcd.com/844/
Last edited by Head_on_a_Stick (2021-01-05 13:33:32)
Para todos todo, para nosotros nada
Offline
Yes, that's pretty much how the script looked before I refactored it. I just personally prefer separating as much as possible into functions because I agree with the blog post to which I linked above, that's all.
I tend to prefer following my common sense over blog posts and stackoverflow... especially when said resources claim "defensive programming" while ignoring the no.1 principle in Bash: quoting.
Mods are just community members who have the occasionally necessary option to move threads around and edit posts. -- Trilby
Offline
I tend to prefer following my common sense
Ah, no, I don't have any of that. Do you have any scripting tutorials or guides you could recommend? I've always been impressed with your skills ever since the CrunchBang days so I would be interested to hear your opinion. TIA.
Bash
I would prefer to avoid bash wherever possible in favour of POSIX sh because I multi-boot with Alpine Linux and OpenBSD, neither of which include bash in their base systems.
Para todos todo, para nosotros nada
Offline
For using functions vs linear-flow scripts, I prefer functions because I like scoping things. I like my variables declared and used in certain scopes and not being able to access them in a global scope (encapsulation). I also find easier to understand and follow function-like code then linear code. A matter of preference I suppose.
As for function names starting with underscores, I like to somehow visually differentiate between external commands and calls I am making to functions inside my scripts. Again, styling preference.
But I come from very high-level programming background (Node, C#) and write Bash scripts only at a hobby level, so some of the quirks must have transferred over
Last edited by karabaja4 (2021-01-05 20:45:06)
Offline
Alad wrote:I tend to prefer following my common sense
Ah, no, I don't have any of that. Do you have any scripting tutorials or guides you could recommend? I've always been impressed with your skills ever since the CrunchBang days so I would be interested to hear your opinion. TIA.
Alad wrote:Bash
I would prefer to avoid bash wherever possible in favour of POSIX sh because I multi-boot with Alpine Linux and OpenBSD, neither of which include bash in their base systems.
Much of the content here is applicable to POSIX sh too.
Managing AUR repos The Right Way -- aurpublish (now a standalone tool)
Offline
Much of the content here is applicable to POSIX sh too.
Oh thank god, Greg's wiki is "back". That is the best source on the internet for general shell scripting, but some time ago it was taken over by another maintainer who absolutely fucked up the whole website. It was loaded to the brim with all sorts of "modern" javascript flashy nonsense that made it virtually unreadable and annoying as (*&N. I see sanity has been restored.
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
Hmm, I don't recall it ever going away tbh.
You might be thinking of the Bash Guide, not the Bash Wiki? It's still there too: http://mywiki.wooledge.org/BashGuide
But there is a "new version" of the guide being written... by the primary author of the original/current one... at https://guide.bash.academy/
It's still unfinished, and has not been worked on in years AFAICT. It's intended to appeal to people who desperately crave flashy javascripty things, because those people were looking at the original guide and finding it "ugly", thus refusing to read it and not learning anything.
I'm not sure it's ever been intended to remove the original guide even if the new javascripty one gets completed.
Managing AUR repos The Right Way -- aurpublish (now a standalone tool)
Offline
Huh, I guess I did have them mixed up. But for some time I was not able to get to the original / real wiki or bash guide and all search results I could find went to the "new" one.
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
It's intended to appeal to people who desperately crave flashy javascripty things, because those people were looking at the original guide and finding it "ugly", thus refusing to read it and not learning anything.
The Story of Arch and Every. Single. Derivative.
Offline
Heh, you're not wrong.
I suppose lhunath figured the damage caused by incompetent bash scripts is more than the damage caused by running Manjaro.
Managing AUR repos The Right Way -- aurpublish (now a standalone tool)
Offline
Thank you very much Ferdinand. The script works well.
Here's a script I made to fix my Faenza icon theme for Xfce.
Offline
Here's a script I made to fix my Faenza icon theme for Xfce.
Thank you very much, Faenza is such a great classic!
A dog is a man's best friend.
Offline
eschwartz wrote:Much of the content here is applicable to POSIX sh too.
Oh thank god, Greg's wiki is "back". That is the best source on the internet for general shell scripting, but some time ago it was taken over by another maintainer who absolutely fucked up the whole website. It was loaded to the brim with all sorts of "modern" javascript flashy nonsense that made it virtually unreadable and annoying as (*&N. I see sanity has been restored.
For just this reason I have a web server where I host sources that aren't mine. If 'they' decide to 'throw in the towel' I still have their nice sources + most sources are pretty 'static' and don't change that often. I also compile a few RST sites now and then, so for most programs I use I have my own wiki containing(mostly) HTML RST and PDF's, which in the end is a little greener too and not that time consuming;)
Offline
I'm a sad sucker for nice and neat, so I run LightDM with the Webkit2 greeter - and for this I suffer the loss of status notifications during boot.
Also, I'm too lazy to bother with much status checking or log reading when no apparent problem exist.
Which means I just float along in my parallel universe, blissfully ignorant, until something or other suddenly doesn't work, and I am rudely pulled back to reality.
This kind of work for me - but an automatically generated summary presented to me every time I log in could be useful.
Assuming this may hold some degree of general interest, I share my humble start.
Any comments, general ridicule or tips for improvement are heartily welcome
#!/bin/sh
# This would typically go in .xprofile
# Build up a status message in the welcome_file and present it with zenity
welcome_file=~/.welcome
echo -e "\nWelcome to `hostname`: `uname -o` `uname -r` (`uname -m`)\n" > $welcome_file
# Boot info
echo -e "\nLast boot:\n----------" >> $welcome_file
last reboot | head -1 | tr -s " " | cut -d " " -f 5-8 >> $welcome_file
systemd-analyze | sed "s/graphical/Graphical/g" >> $welcome_file
# Boot errors
echo -e "\nErrors:\n-------" >> $welcome_file
journalctl -r -b --no-pager -p err | grep -v "Journal begins" >> $welcome_file
# Failed systemd units
echo -e "\nFailed units:\n-------------" >> $welcome_file
systemctl --failed >> $welcome_file
# Last logins
echo -e "\nLast logins:\n------------" >> $welcome_file
last | grep -v reboot | head -5 | tr -s " " | cut -d " " -f 1,3-7 | tr " " "\t" >> $welcome_file
echo -e "\nNice to see you! \n" >> $welcome_file
cat $welcome_file | zenity --text-info --width=1200 --height=800 --font=mono &
Offline
@Ferdinand,
Your script is not POSIX .. I would replace the echos' with printf.
'systemd-analyze | sed "s/graphical/Graphical/g"' ?? only for that capital g?
Don't use back-ticks use $(..)
last reboot | awk ' FNR == 1 {print $5, $6, $7, $8}'
Start using shellcheck it gives some advice about your scripting, specifically since you host it here;)
Offline