shell scripting topic
-
I've just found this and decided to share here:
The goal of this book is to document known and unknown methods of doing various tasks using only built-in
bash
features. Using the snippets from this bible can help remove unneeded dependencies from scripts and in most cases make them faster. -
@meleu Wow this is really helpfull ;) Cool snippets for bash coders. Thank you so much.
For ex:
Reverse array I didfor ((z=${#array[*]}-1; z>-1; z--)); do echo "${array[z]}" done
Reverse array with the bash-bible
## Reverse an array # ```sh reverse_array() { # Usage: reverse_array "array" shopt -s extdebug f()(printf '%s\n' "${BASH_ARGV[@]}"); f "$@" shopt -u extdebug } # ```
Up to now my version seems a bit less complex. Maybe it's due my limited coding skills. I'm still learning ....
-
@meleu I think that's just a note to me ... BashPitfalls
function1(){ local status=$(false) echo $? }
Will return 0 which is obviously wrong
So the return code 0 just indicates the correct setting of a local setted value, which was correctly done ;)So to get out of this make following
function1(){ local status status=$(false) echo $? }
This will put out correct value for "error" 1
-
@cyperghost yeah, that's a thing to be careful. I learned it while reading the RetroPie's Shell Style Guide: https://retropie.org.uk/docs/Shell-Style-Guide/#use-local-variables
-
I would like to share a little trick I learned today and also ask for some help...
First the short story
I was needing to check if the current hour is after 18h, then I tried this:
hour=$(date +%H) if [[ $hour -gt 18 ]]; then echo "do something..." fi
And then I got this error (please, forgive the non-english):
-bash: [[: 08: valor muito grande para esta base de numeração (token de erro é "08")
As you can see, the problem is that
date +%H
returns08
, and when I try to compare it, bash doesn't see08
as a decimal number.The solution is obviously getting rid of that leading zero. I decided that using
sed
would be overkill for such a simple task, then I've found a pure bash solution using a feature of$(( ))
.hour=$(date +%H) hour=$(( 10#$hour )) # could also be an oneliner: $(( 10#$(date +%H) )) if [[ $hour -gt 18 ]]; then echo "do something..." fi
And now my script is working perfectly!
Now the help I mentioned earlier on the beginning of this post...
On that stackoverflow answer I see this:
The
$(( ))
sets up an arithmetic context and the10#
converts the number from base 10 to base 10 causing any leading zeros to be dropped.Alright, but I like to see stuff on the official documentation in a hope to learn more tricks. The
$(( ))
is a bash builtin feature, but in the official documentation there's no mention to the10#
operand.Any thoughts on where to get info about it?
-
@meleu That I can answer !
Actually it's in the very doc you mention :
https://www.gnu.org/software/bash/manual/bash.html#Shell-ArithmeticConstants with a leading 0 are interpreted as octal numbers. A leading ‘0x’ or ‘0X’ denotes hexadecimal. Otherwise, numbers take the form [base#]n, where the optional base is a decimal number between 2 and 64 representing the arithmetic base, and n is a number in that base. If base# is omitted, then base 10 is used. When specifying n, the digits greater than 9 are represented by the lowercase letters, the uppercase letters, ‘@’, and ‘_’, in that order. If base is less than or equal to 36, lowercase and uppercase letters may be used interchangeably to represent numbers between 10 and 35.
-
@sano whoops! Didn't catch those little words 😅
Thanks Sano-san. And yeah, I learned more tricks!
-
@meleu Just FYI, you could just have used
date +%-H
;)
Glad to see you here again BTW ! -
@sano ouch! Looks like I need RTFM some more...
From the
date
man page:By default, date pads numeric fields with zeroes. The following optional flags may follow '%': - (hyphen) do not pad the field
Thanks again, Sanso-sensei!
-
@meleu I really deserve no special credit for this, I just remembered something like this existed, probably had to use it in the past, too :)
-
A common mistake is often made by using
grep
.
It is often told that grep finds a total of all search strings within a text file due the-c
switch. That is total nonsense .... -c just counts linesSo we miss
hello hello hello hello hello grep -c hello 2
We use a small hack ;)
Better is to use the-o
option is will show occourences of search string listed in newline and now we pipe towc -l
... and count lines again - now we catched them all ;)hello hello hello hello hello grep -o hello | wc -l 5
-
EDIT BEGIN
I think I found a good solution with pure bash
But maybe some knows a better one ;)val=${#Unix[@]} for ((i=0; i<$val; i+=1)); do
EDIT END
Is there something that can be made easier (more efficient) than this script?
I want to merge two arrys
A1=(1 2 3)
A2=(one two there)
the result should be A3
A3=(1 one 2 two 3 three)It works with this script.
But first... I want to avoid any counters (if possible)
Do you know a nice trick to count up values{0..6}
works only with fixed characters not as variable. So{0..6}
is fine{0..$arraysize}
not#!/bin/bash # A small script to show how to merge two arrays # with alternating values (exp. for creating arrays for dialogs) # Example Array Unix=("Debian" "Red hat" "Ubuntu" "Suse" "Fedora" "UTS" "OpenLinux") Shell=("bash" "csh" "jsh" "rsh" "ksh" "rc" "tcsh") # Check if both arrays got some size [[ ${#Unix[@]} -eq ${#Shell[@]} ]] || exit 1 echo "Both arrays got same size -- Proceed" val=$((${#Unix[@]}-1)) echo $val for i in $(seq 0 $val); do echo "Merging ${Unix[$i]} and ${Shell[$i]}" UnixShell+=("${Unix[$i]}" "${Shell[$i]}") done echo "${UnixShell[@]}"
-
@cyperghost both methods are perfectly valid (using a for to iterate through all items).
-
@meleu thanks for the feedback -- I appreciate it ;)
Come on ... take a look in the MAME RoW now - if you have time ;) -
FYI, I'll release a new version of RetroPie Shell Script Boilerplate soon-ish.
This is a template for building shell scripts for RetroPie, with some helper functions, dialogs, etc.
-
Well, here it is! A new version of RetroPie Shell Script Boilerplate.
This is a template for building shell scripts for RetroPie.
I've added examples of the following dialog boxes:
--infobox
--yesno
--msgbox
--menu
All the dialogs can be found at
utils/dialogs.sh
I've also moved some functions to
utils/base.sh
.
Contributions to the project are always appreciated, so if you would like to support us with a donation you can do so here.
Hosting provided by Mythic-Beasts. See the Hosting Information page for more information.