Menu driven scripts

About writing shell scripts and making the most of your shell
Forum rules
Topics in this forum are automatically closed 6 months after creation.
User avatar
Termy
Level 12
Level 12
Posts: 4248
Joined: Mon Sep 04, 2017 8:49 pm
Location: UK
Contact:

Re: Menu driven scripts

Post by Termy »

I suppose in this case it's not necessary, because the filehandle would be closed when PERL exits, but if it fails, it would fail quietly, which is part of why it's important to handle it accordingly. The or die("$!") business is commonplace in PERL when dealing with things which especially operate on files, which accounts for at least 52 functions:

Code: Select all

accept()	chown()		dbmopen()	getsockopt()	mkdir()		open()		recv()		semget()	shmget()	sysopen()	truncate()
bind()		close()		exec()		ioctl()		msgctl()	opendir()	rename()	semop()		shmread()	sysread()	unlink()
binmode()	closedir()	fcntl()		kill()		msgget()	pipe()		rmdir()		send()		shutdown()	sysseek()
chdir()		connect()	flock()		link()		msgrcv()	read()		seek()		setsockopt()	socketpair()	system()
chmod()		dbmclose()	fork()		listen()	msgsnd()	readlink()	semctl()	shmctl()	symlink()	syswrite()
If you don't want to handle those kind of exceptions, then you could try the autodie pragma, which certainly cleans up the code, but IMO it's better to learn to do this manually to have a better understanding of the language; I didn't do this for a long time, then paid the price several times. Just because something will 'probably' work, doesn't mean it's wise to simply cross your fingers and hope things work out.

My mindset with programming is similar to how I handle money: I don't save for what I expect, I save for what I don't.

Quite right, you didn't need the declare builtin to assign an array, unless it's an associative array.

Regarding the while read loop, that's a good observation, but you weren't piping, as far as I could see. Redirecting into a while read loop isn't piping, thankfully. You can forgo the processes substitution (<(...)) for command substitution ($(...) or `...`) with a herestring (<<<), like:

Code: Select all

while read -a Line; do
	if [[ ${Line[0]} == Mem: ]]; then
		UsedRAM=${Line[2]}
		break
	fi
done <<< "$(free -h)"
printf '%s\n' "$UsedRAM"
That should have effectively answered your next question. ;) You can also use the readarray or mapfile builtin (synonymous), which dumps the contents of the file into an array (default: $MAPFILE), where each line is an element in the array. Although, this can be tweaked with flags and stuff, such as to remove the included newline character (think of it like in PERL, without chomp()). Note that this immediately stores the contents of the file into that array, which may be inefficient or otherwise undesired, depending on the task.

Ah, I really do appreciate the honesty that you just want it to look cool, but here's the thing: it doesn't. When I first started programming, I genuinely thought that lots of busy looking complex and obnoxious code was SUPER COOL, but then I actually learned what complex code was and how ridiculous my old code looked. Never again. So, please don't worry about looking cool. IMO, what's cool is efficient, clean, and robust code.

Yeah, the HTML comments, as you demonstrated.

Your percentage thing is cracking me up. :lol:
I'm also Terminalforlife on GitHub.
user6c57b8
Level 2
Level 2
Posts: 52
Joined: Mon Aug 05, 2019 1:07 pm

Re: Menu driven scripts

Post by user6c57b8 »

Termy wrote: Thu May 26, 2022 3:34 pm I suppose in this case it's not necessary, because the filehandle would be closed when PERL exits, but if it fails, it would fail quietly, which is part of why it's important to handle it accordingly.
Even if the script was being written for NASA, and if the script messed up 500 people would die, I still wouldn't put the die("$!") in for the close(). Not my problem.
Termy wrote: The or die("$!") ... when dealing with things which especially operate on files, which accounts for at least 52 functions: ...
So or die("$!") common-place functions are 90% file-handling. It's 17%surprising the system function can use or die("$!"). That's 17%cool.
Termy wrote: If you don't want to handle those kind of exceptions, then you could try the autodie pragma, ...
That feels 96%rare to use. But 96%interesting.
Termy wrote: ...you didn't need the declare builtin to assign an array, unless it's an associative array.
Associative arrays are as useful as CSV files and JSON files.
Termy wrote: You can forgo the processes substitution (<(...)) for command substitution ($(...) or `...`) with a herestring (<<<), like:

Code: Select all

while read -a Line; do
	if [[ ${Line[0]} == Mem: ]]; then
		UsedRAM=${Line[2]}
		break
	fi
done <<< "$(free -h)"
printf '%s\n' "$UsedRAM"
Impressive you didn't even need to use awk to tokenize the free output.
And what the heck why didn't I know about the

Code: Select all

while read Line; do echo "$Line"; done <<< "$(echo put latin here)"
syntax omg I'm 900%mad. There are too many styles of while loops to memorize I'm 93%sure.
Termy wrote: You can also use the readarray or mapfile builtin (synonymous), which dumps the contents of the file into an array (default: $MAPFILE), where each line is an element in the array. Although, this can be tweaked with flags and stuff, such as to remove the included newline character (think of it like in PERL, without chomp()). Note that this immediately stores the contents of the file into that array, which may be inefficient or otherwise undesired, depending on the task.
what a wonderful bash built-in. And you made it 200%easier to skim the `help mapfile`, thank you!
It's 90%-like php's slurping file_get_contents().
I love it.
Although like you said in a previous post: If you don't want the input file to be slurped into a line-by-line array you can just go file_contents=`<a_regular_text_file.txt` to get the file's contents into a whole string. Which I think I said earlier is 17%sweet.
Termy wrote: Ah, I really do appreciate the honesty that you just want it to look cool, but here's the thing: it doesn't.
The sad part is that you're 900%right.
Termy wrote: Yeah, the HTML comments, as you demonstrated.
oof. Putting non-HTML comments in an HTML-like "data-file" (?) would 13%hurt.
LittleScriptMan
Level 3
Level 3
Posts: 158
Joined: Thu Jan 13, 2022 8:42 am

Re: Menu driven scripts

Post by LittleScriptMan »

Ray94520 wrote: Mon May 23, 2022 9:24 pm In certain areas I do use tput it has been quite handy in some cases
Hello,
Like AndyMH and even after reading Xenopeek's remark on command substitution still thinking I can manage a 0,0010452 s delay for a tput command execution :lol: (just joking but perfectly understanding the warning about command substitution is more general than that), I'm still using it this way :
- at the end of my .bashrc there is a call for a file containing some color settings (but it can also just be pasted at the end of the .bashrc file) :

Code: Select all

# TEXT ATTRIBUTES
TStd=$(tput sgr0)
TBold=$(tput bold)
TDim=$(tput dim)
TUnd=$(tput smul)
TBlink=$(tput blink)
TRev=$(tput rev)

# FOREGROUND ATTRIBUTES
TBlackf=$(tput setaf 0)
TRedf=$(tput setaf 1)
TGreenf=$(tput setaf 2)
TYellowf=$(tput setaf 3)
TBluef=$(tput setaf 4)
TMagentaf=$(tput setaf 5)
TCyanf=$(tput setaf 6)
TWhitef=$(tput setaf 7)

# BACKGROUND ATTRIBUTES
TBlackb=$(tput setab 0)
TRedb=$(tput setab 1)
TGreenb=$(tput setab 2)
TYellowb=$(tput setab 3)
TBlueb=$(tput setab 4)
TMagentab=$(tput setab 5)
TCyanb=$(tput setab 6)
TWhiteb=$(tput setab 7)
This way they are always available for use and can even be merged to get more complex "styles" :

Code: Select all

# Error display style for scripts : Bold Red
TErr=$TBold$TRedf
# Warning display style for scripts : Bold Yellow
TWarn=$TBold$TYellowf
And use them in my scripts through functions :

Code: Select all

# Displays a string argument $1 as a warning, then restores standard attributes
WarnMsg () {
	echo -e "$TWarn$1$TStd"
}

# Displays a string argument $1 as an error, then restores standard attributes
ErrMsg () {
	echo -e "$TErr$1$TStd"
}
Of course, everyone has his way to cook the goose. If my recipe can be for some help...
Interests : Firefox, Cinnamon & Bash Scripts
LM Version : LMDE5 (LMDE4 just in case)
User avatar
Termy
Level 12
Level 12
Posts: 4248
Joined: Mon Sep 04, 2017 8:49 pm
Location: UK
Contact:

Re: Menu driven scripts

Post by Termy »

That's the thing, though: it is inherently your problem, as the programmer writing the code. Regardless, at least now the OP knows about it. :)

If you're saying associative arrays aren't useful, because you're also saying JSON and CSV files aren't useful, then you're mistaken, on both fronts. JSON and CSV allow people to share and handle data in a consistent and parseable fashion, without needing to reinvent the wheel with some new format. CSV (Comma-Separated Values) is also useful because it's very simple, making it very easy to parse. That being said, there are also other formats, such as XML, TOML, and YAML.

As for associative arrays, they are incredible when doing more complex operations. I grant you, your casual BASH scripter will probably rarely use them, but that doesn't equate to their lack of usefulness. There's a reason associative arrays are in practically every high-level programming language. I have a good example of using associative arrays in BASH, with CSi3.

Anyway, I'll bow out from this thread now, because I don't wanna further derail the topic. :lol:
I'm also Terminalforlife on GitHub.
user6c57b8
Level 2
Level 2
Posts: 52
Joined: Mon Aug 05, 2019 1:07 pm

Re: Menu driven scripts

Post by user6c57b8 »

Termy wrote: Fri May 27, 2022 2:14 pm That's the thing, though: it is inherently your problem, as the programmer writing the code.
It was a 90%joke, but more honestly/seriously I will add die("$!") to close() if I rewrote the bash script (assuming I used perl). I mean the die is redundant, sorta. Corny, maybe. Essential, eeeh. But 500 people might die if I don't add it in there.
Termy wrote: If you're saying associative arrays aren't useful, because you're also saying JSON and CSV files aren't useful, ...
I'm just angry that I might never be able to use hashes/associative-arrays/JSON-files/CSV-files in all of their glory (meaning like using the plethora of awesome Mint programming software to like import JSON into a perl data structure or convert a JSON file into XML if that's even possible) because I don't have any data that can exploit their benefits.

Ray94520 wrote: I'm trying to upgrade my menu process.
I currently have menu driven scripts
There are cooler/just-as-cool ways to display a nice menu/option-selection to its user:
man zenity #with this little guy you can open a window with buttons (or radio boxes) to select a food.
sudo apt-get install python3-tk #this in my opinion is the easiest way to get a window with buttons to click to do pretty much anything

Just some random ideas. Personally I'd go with zenity because it came with my system and I probably wouldn't use a tty/non-gui-system to access the menu.
Locked

Return to “Scripts & Bash”