[Bash] Use of brackets in this code snippet

  • Thread starter Wrichik Basu
  • Start date
  • Tags
    Code
In summary: Eenable extended globbingEnable extended globbing-F(none)List single-quoted strings without $, but do not execute...-GglobUse the GNU globbing library instead of the shell's own globbing facility.-hhelpDisplay this help and exit.-iignorecaseIgnore the case of the following arguments.-LdirectorySpecify the directory to search for library files. If this option is not given, the library files are searched in the current directory.-mmultilineAllow mult
  • #1
Wrichik Basu
Science Advisor
Insights Author
Gold Member
2,147
2,719
Disclaimer: I am an absolute beginner in bash scripting.

I spent the whole evening trying to make this code snippet work as intended. The program is supposed to sort an array using bubble sort algorithm.
Program:
#!/bin/bash

arr=(7 -1 9 2 11 -13 5)

for (( i=0; i<(( ${#arr[@]} - 1 )); i++ )) ; do
    for (( j=0; j<(( ${#arr[@]} - 1 - i )); j++ )); do
        if (( arr[j] > arr[j+1] )); then
            temp=${arr[j]}
            arr[j]=${arr[j+1]}
            arr[j+1]=${temp}
        fi
    done
done

echo -ne "\n"
printf '%s\n' "${arr[@]}"
Output:
-13
-1
2
5
7
9
11
I knew the algorithm well; the only problem I faced was brackets. Curly brackets, parenthesis, square brackets — all got mixed up. Later, I found this question on Stack Overflow that outlines the different brackets and their meanings. That solves most of the queries, but some remain:
  1. Square brackets, [[...]] are used for logical expressions. Then why does neither if [[ arr[j] > arr[j+1] ]] nor if [[ ${arr[j]} > ${arr[j+1]} ]] work? (On the other hand, both if (( ${arr[j]} > ${arr[j+1]} )) and if (( arr[j] > arr[j+1] )) works.)
  2. I found that I get the correct output even if I don't use $ in front of i and j. If bash can substitute the value of the variable here, why can't it do the same in other places? (For example, in lines 8, 9 and 10, I have to use ${...} on the RHS of the = operator.)
 
Technology news on Phys.org
  • #2
  • Informative
  • Like
Likes berkeman and jedishrfu
  • #3
Most bash scripters when faced with what you’re doing will quickly shift to python to get it done.

Bash is great for simple scripting and extremely dense for more complex stuff.
 
  • Like
Likes pbuk, FactChecker and PeterDonis
  • #4
jedishrfu said:
Most bash scripters when faced with what you’re doing will quickly shift to python to get it done.
I am doing it because I have to do it for my computer science elective this semester. Given a choice, I would have certainly chosen Java in most cases.
 
  • #5
I understand, I was just giving you my experience. I’ve tried to extend some scripts ans the peculiarities of bash always get in the way usually around single quotes vs double quotes.
 
  • Like
Likes Wrichik Basu
  • #6
Regarding OP's question 2 - I believe that you don't need the $ signs in front of variables when they are used in mathematical expressions. Presumably array indices count as mathematical expressions, hence ${arr[i]} not needing a dollar before the i.

I don't think it's a case of bash not being able to substitute a variable value, but that you don't want it to substitute a value unless you explicitly tell it to (or use the variable in a mathematical context where it's clear it should be used as a variable). Remember that this is a shell script - it's largely used to run operating system commands. So say you define a variable called ls. What do you want bash to do with the characters ls - interpret them as a variable and fetch the value, or execute the ls command? You could make known Unix commands reserved words, but you can't write an exhaustive list of programs you could be running so you would always risk a collision. Bash solves the problem allowing variable names to be (almost) anything and requiring you to write $ls to get the value of the variable.
 
  • Informative
Likes Wrichik Basu
  • #7
The single quote double quote issue is that single quotes are for literals ie no substitutions

echo "The book title is: $1" (prints the first script arg remember $0 is the script name itself)

vs

echo 'The book cost: $1' (prints the literal 'the book cost $1')

For some commands you want the delayed expansion of a file mask as in the command

find . -name '*.jpg' (to find all jpg files with the current directory tree)
 
  • Like
  • Informative
Likes Wrichik Basu and Ibix
  • #8
The best script development strategy is to use echo statements to see what happens and to add your changes slowly and carefully, testing in between to make sure things are working as you expect.

I think bash also has a no-execute flag where the script will display with substitutions and adjustments but not execute and commands.

as in bash -n for noexecute:

https://tldp.org/LDP/abs/html/options.html

Table 33-1. Bash options

Abbreviation​
Name​
Effect​
-B​
brace expansion​
Enable brace expansion (default setting = on)​
+B​
brace expansion​
Disable brace expansion​
-C​
noclobber​
Prevent overwriting of files by redirection (may be overridden by >|)​
-D​
(none)​
List double-quoted strings prefixed by $, but do not execute commands in script​
-a​
allexport​
Export all defined variables​
-b​
notify​
Notify when jobs running in background terminate (not of much use in a script)​
-c ...​
(none)​
Read commands from ...
checkjobs​
Informs user of any open jobs upon shell exit. Introduced in version 4 of Bash, and still "experimental." Usage: shopt -s checkjobs (Caution: may hang!)​
-e​
errexit​
Abort script at first error, when a command exits with non-zero status (except in until or while loops, if-tests, list constructs)​
-f​
noglob​
Filename expansion (globbing) disabled​
globstar​
Enables the ** globbing operator (version 4+ of Bash). Usage: shopt -s globstar​
-i​
interactive​
Script runs in interactive mode​
-n
noexec
Read commands in script, but do not execute them (syntax check)
-o Option-Name​
(none)​
Invoke the Option-Name option​
-o posix​
POSIX​
Change the behavior of Bash, or invoked script, to conform to POSIX standard.​
-o pipefail​
pipe failure​
Causes a pipeline to return the exit status of the last command in the pipe that returned a non-zero return value.​
-p​
privileged​
Script runs as "suid" (caution!)​
-r​
restricted​
Script runs in restricted mode (see Chapter 22).​
-s​
stdin​
Read commands from stdin​
-t​
(none)​
Exit after first command​
-u​
nounset​
Attempt to use undefined variable outputs error message, and forces an exit​
-v​
verbose​
Print each command to stdout before executing it​
-x​
xtrace​
Similar to -v, but expands commands​
-​
(none)​
End of options flag. All other arguments are positional parameters.​
--​
(none)​
Unset positional parameters. If arguments given (-- arg1 arg2), positional parameters set to arguments.​
 
  • Like
Likes Wrichik Basu
  • #9
Thanks, @Ibix; that also explains why ${arr[i+1]} or similar expressions execute without the need of double parenthesis inside the square brackets.
jedishrfu said:
The single quote double quote issue is that single quotes are for literals ie no substitutions
I haven't used parameterized functions yet, but was hoping to use them soon. Thanks for pointing out this subtlety; otherwise I would have had to spend hours not realizing where the error is occurring.

Also, I have made one error in the program: > or < cannot be used for numeric comparisons; they are for strings. Instead, I have to use -lt or -gt and so on.

An interesting note regarding question no. 1: the following works: if [[ ( ${arr[j]} -gt ${arr[j+1]} ) ]];, which probably means I have to evaluate the expression inside a subshell to make it work.
 
  • #10
I think the < and > re used for input output redirections:

echo "hello world" >somefile.txt

cat <somefile.txt

cat somefile.txt
 
  • Like
Likes Wrichik Basu

FAQ: [Bash] Use of brackets in this code snippet

What is the purpose of using brackets in this code snippet?

The brackets in this code snippet are used to enclose a command or expression, indicating that the enclosed code should be evaluated first before executing the rest of the command or expression.

Can you provide an example of how brackets are used in Bash?

Sure, for example, in the code snippet [ $a -gt $b ], the brackets are used to enclose the comparison operator "-gt" and the variables $a and $b to indicate that this condition should be evaluated before performing any action based on the result.

Are there different types of brackets used in Bash?

Yes, there are two types of brackets commonly used in Bash - square brackets [ ] and curly brackets { }.

Can brackets be nested in Bash?

Yes, brackets can be nested in Bash. This means that a set of brackets can be enclosed within another set of brackets to perform more complex evaluations or actions.

Is there a specific order in which brackets should be used in a code snippet?

Yes, in most cases, square brackets [ ] should be used before curly brackets { }. Square brackets are typically used for evaluations and conditions, while curly brackets are used for grouping and grouping commands.

Similar threads

Replies
29
Views
2K
Replies
6
Views
2K
Replies
22
Views
3K
Replies
4
Views
1K
Replies
2
Views
3K
Replies
17
Views
3K
Back
Top